Unity输入系统等价于input . getkeydown()



我试图做到这一点,我通过调用ReadValue方法对moveAction和获得一个浮动,但玩家只是卡在蹲伏的位置。我具体应该改变什么来完全取代crouchKey与crouchAction?如果脚本太大,我很抱歉,我把它包含在它的全部,以避免任何可能的混乱。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.InputSystem;
public class PlayerMovement : MonoBehaviour
{
[Header("Movement")]
private float moveSpeed;
public float walkSpeed;
public float sprintSpeed;
public float groundDrag;
[Header("Jumping")]
public float jumpForce;
public float jumpCooldown;
public float airMultiplier;
bool readyToJump;
[Header("Crouching")]
public float crouchSpeed;
public float crouchYScale;
private float startYScale;
[Header("Keybinds")]
public KeyCode crouchKey = KeyCode.LeftControl;
[Header("Ground Check")]
public float playerHeight;
public LayerMask whatIsGround;
bool grounded;
[Header("Slope Handling")]
public float maxSlopeAngle;
private RaycastHit slopeHit;
private bool exitingSlope;
public Transform orientation;
float horizontalInput;
float verticalInput;
Vector3 moveDirection;
Rigidbody rb;
PlayerInput playerInput;
InputAction moveAction;
InputAction jumpAction;
InputAction sprintAction;
InputAction crouchAction;
public MovementState state;
public enum MovementState
{
walking,
sprinting,
crouching,
air
}
private void Start()
{
rb = GetComponent<Rigidbody>();
playerInput = GetComponent<PlayerInput>();
moveAction = playerInput.actions["move"];
jumpAction = playerInput.actions["jump"];
sprintAction = playerInput.actions["sprint"];
crouchAction = playerInput.actions["crouch"];
rb.freezeRotation = true;
readyToJump = true;
startYScale = transform.localScale.y;
}
private void Update()
{
grounded = Physics.Raycast(transform.position, Vector3.down, playerHeight * 0.5f + 0.2f, whatIsGround);
MyInput();
SpeedControl();
StateHandler();
if (grounded)
rb.drag = groundDrag;
else
rb.drag = 0;
}
private void FixedUpdate()
{
MovePlayer();
}
private void MyInput()
{
var jumpInput = jumpAction.ReadValue<float>();
var crouchInput = crouchAction.ReadValue<float>();
if(jumpInput > 0 && readyToJump && grounded)
{
readyToJump = false;
Jump();
Invoke(nameof(ResetJump), jumpCooldown);
}
if (Input.GetKeyDown(crouchKey))
{
transform.localScale = new Vector3(transform.localScale.x, crouchYScale, transform.localScale.z);
rb.AddForce(Vector3.down * 5f, ForceMode.Impulse);
}
if (Input.GetKeyUp(crouchKey))
{
transform.localScale = new Vector3(transform.localScale.x, startYScale, transform.localScale.z);
}
}
private void StateHandler()
{
var sprintInput = sprintAction.ReadValue<float>();
var crouchInput = crouchAction.ReadValue<float>();
if (Input.GetKey(crouchKey))
{
state = MovementState.crouching;
moveSpeed = crouchSpeed;
}
else if(grounded && sprintInput > 0)
{
state = MovementState.sprinting;
moveSpeed = sprintSpeed;
}
else if (grounded)
{
state = MovementState.walking;
moveSpeed = walkSpeed;
}
else
{
state = MovementState.air;
}
}
private void MovePlayer()
{
var moveInput = moveAction.ReadValue<Vector2>();
moveDirection = orientation.forward * moveInput.y + orientation.right * moveInput.x;
if (OnSlope() && !exitingSlope)
{
rb.AddForce(GetSlopeMoveDirection() * moveSpeed * 20f, ForceMode.Force);
if (rb.velocity.y > 0)
rb.AddForce(Vector3.down * 80f, ForceMode.Force);
}
else if(grounded)
rb.AddForce(moveDirection.normalized * moveSpeed * 10f, ForceMode.Force);
else if(!grounded)
rb.AddForce(moveDirection.normalized * moveSpeed * 10f * airMultiplier, ForceMode.Force);
rb.useGravity = !OnSlope();
}
private void SpeedControl()
{
if (OnSlope() && !exitingSlope)
{
if (rb.velocity.magnitude > moveSpeed)
rb.velocity = rb.velocity.normalized * moveSpeed;
}
else
{
Vector3 flatVel = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
if (flatVel.magnitude > moveSpeed)
{
Vector3 limitedVel = flatVel.normalized * moveSpeed;
rb.velocity = new Vector3(limitedVel.x, rb.velocity.y, limitedVel.z);
}
}
}
private void Jump()
{
exitingSlope = true;
rb.velocity = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
rb.AddForce(transform.up * jumpForce, ForceMode.Impulse);
}
private void ResetJump()
{
readyToJump = true;
exitingSlope = false;
}
private bool OnSlope()
{
if(Physics.Raycast(transform.position, Vector3.down, out slopeHit, playerHeight * 0.5f + 0.3f))
{
float angle = Vector3.Angle(Vector3.up, slopeHit.normal);
return angle < maxSlopeAngle && angle != 0;
}
return false;
}
private Vector3 GetSlopeMoveDirection()
{
return Vector3.ProjectOnPlane(moveDirection, slopeHit.normal).normalized;
}
}

如果你想继续轮询输入,你可以在你的Update循环中使用类似if(Keyboard.current.spaceKey.wasPressedThisFrame)的东西。

你也可以创建一个ActionMap(强烈推荐)并绑定到创建的动作而不是直接击键。

我们做这样的事情(!)只有当Generate C# Class在InputAction资产上被激活时才有效!):

public class PlayerController : MonoBehaviour
{
//Replace YourInput with your InputMap name.
private YourInput _inputMap;
private void Awake()
{
_inputMap = new YourInput();
RegisterInputEvents();
_inputMap.Player.Enable();
}
private void OnDestroy()
{
UnregisterInputEvents();
}

private void RegisterInputEvents()
{
_inputMap.Player.SomeAction.performed += OnLeftHookInput;
//...//
}
/// <summary>
/// Deregisters functions of all input events
/// </summary>
private void UnregisterInputEvents()
{
if (_inputMap == null) return;
_inputMap.Player.SomeAction.performed -= OnLeftHookInput;
//...//
}
private void OnLeftHookInput(InputAction.CallbackContext actionContext)
{
//we need this for some reason...
if (!actionContext.performed) return;
//Do Stuff
}
}

只是在你需要它的情况下,从输入中获得一个Vector2将是这样的:

private void OnMousePositionInput(InputAction.CallbackContext actionContext)
{
if (!actionContext.performed) return;
_mousePosition = actionContext.ReadValue<Vector2>();
}

最新更新