【发布时间】:2020-11-07 23:26:15
【问题描述】:
我正在使用 Unity 制作 2D 平台游戏。我使用this 教程编写了这段代码,但做了一点改动。我想同时支持键盘和游戏手柄,所以我使用了新的输入系统。我已经定义了三个名为 GroundedRememeber、JumpPressedRemember 和 JumpPressedRememberTime 的变量,它们基本上像计时器一样工作,并检查玩家是否离开地面,然后玩家可以在靠近地面时跳跃而无需触摸它,我想用它代替著名的“groundCheck”。但问题是这些计时器不起作用,当我快速按下跳跃按钮时,即使在空中,玩家也可以永远跳跃。此外,如您所见,我添加了一个名为“groundLayers”的图层蒙版,让玩家只能在这种类型的物体上跳跃,但是当我在 Inspector 的“groundLayers”插槽中选择“Ground”时,玩家无法再跳跃.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerController : MonoBehaviour, PlayerInputActions.IPlayerActions
{
private PlayerInputActions controls;
[SerializeField] LayerMask groundLayers;
private Rigidbody2D rb;
private Animator anim;
private bool facingRight = true;
private Vector2 moveInput;
[SerializeField] private float jumpForce;
float JumpPressedRemember = 0;
[SerializeField] float JumpPressedRememberTime = 0.2f;
float GroundedRemember = 0;
[SerializeField] float GroundedRememberTime = 0.25f;
[SerializeField] float HorizontalAcceleration = 1;
[SerializeField] [Range(0, 1)] float HorizontalDampingBasic = 0.5f;
[SerializeField] [Range(0, 1)] float HorizontalDampingWhenStopping = 0.5f;
[SerializeField] [Range(0, 1)] float HorizontalDampingWhenTurning = 0.5f;
[SerializeField] [Range(0, 1)] float JumpHeight = 0.5f;
private void Awake()
{
controls = new PlayerInputActions();
controls.Player.SetCallbacks(this);
}
void Start()
{
rb = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();
}
void PlayerInputActions.IPlayerActions.OnMove(InputAction.CallbackContext context)
{
moveInput = context.ReadValue<Vector2>();
}
void Jump() {
rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Force);
GroundedRemember = 0;
JumpPressedRemember = 0;
}
bool TryJump() {
if (GroundedRemember > 0) {
Jump();
return true;
} else {
JumpPressedRemember = JumpPressedRememberTime;
return false;
}
}
void PlayerInputActions.IPlayerActions.OnJump(InputAction.CallbackContext context)
{
jumpForce = context.ReadValue<float>();
switch (context.phase) {
case InputActionPhase.Performed:
TryJump();
break;
}
}
void FixedUpdate()
{
if(facingRight == false && moveInput.x > 0){
Flip();
}else if (facingRight == true && moveInput.x < 0){
Flip();
}
}
void Flip(){
facingRight = !facingRight;
Vector3 Scaler = transform.localScale;
Scaler.x *= -1;
transform.localScale = Scaler;
}
void OnEnable()
{
controls.Enable();
}
void OnDisable()
{
controls.Disable();
}
void Update()
{
Vector2 GroundedBoxCheckPosition = (Vector2)transform.position + new Vector2(0, -0.01f);
Vector2 GroundedBoxCheckScale = (Vector2)transform.localScale + new Vector2(-0.02f, 0);
bool Grounded = Physics2D.OverlapBox(GroundedBoxCheckPosition, transform.localScale, 0, groundLayers);
GroundedRemember -= Time.deltaTime;
if (Grounded)
{
GroundedRemember = GroundedRememberTime;
}
JumpPressedRemember -= Time.deltaTime;
if ((JumpPressedRemember > 0)) {
TryJump();
}
rb.velocity = new Vector2(rb.velocity.x, jumpForce);
float HorizontalVelocity = rb.velocity.x;
HorizontalVelocity += moveInput.x;
if (Mathf.Abs(moveInput.x) < 0.01f)
HorizontalVelocity *= Mathf.Pow(1f - HorizontalDampingWhenStopping, Time.deltaTime * 10f);
else if (Mathf.Sign(moveInput.x) != Mathf.Sign(HorizontalVelocity))
HorizontalVelocity *= Mathf.Pow(1f - HorizontalDampingWhenTurning, Time.deltaTime * 10f);
else
HorizontalVelocity *= Mathf.Pow(1f - HorizontalDampingBasic, Time.deltaTime * 10f);
rb.velocity = new Vector2(HorizontalVelocity, rb.velocity.y);
}
}
【问题讨论】: