unity3d Input.GetKeyDown()的Unity输入系统等效函数

dbf7pr2w  于 2023-01-09  发布在  其他
关注(0)|答案(1)|浏览(197)

我试着像其他人一样调用moveAction上的ReadValue方法并获得一个浮点数,但是玩家只是停留在蹲姿。我应该具体修改什么来完全用crouchAction替换crouchKey?抱歉,如果脚本太大,我完整地包含了它以避免任何可能的混乱。

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;
    }
}
7xzttuei

7xzttuei1#

如果您想继续轮询输入,可以在Update循环中使用沿着if(Keyboard.current.spaceKey.wasPressedThisFrame)的代码。
你也可以创建一个ActionMap(强烈推荐)并绑定到创建的动作而不是直接的击键。更多信息请参考this
我们执行类似以下的操作(!仅当在InputAction资产上激活Generate C# Class时有效!):

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
    }
}

为了以防万一,从输入中获取Vector 2将如下所示:

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

相关问题