如何解决玩家没有朝正确方向移动的问题?

问题描述 投票:0回答:1

我正在尝试使用新的输入系统创建一个 Unity 运动 C# 脚本。我遇到了一个问题,即玩家没有按照我所看的方向移动。该系统还使用 Cinemachine 作为第三人称和战斗摄像机。其他一切功能正常。

脚本:

using UnityEngine;

public class ThirdPersonCam : MonoBehaviour
{
    private DeviceControls controls;

    [Header("Objects")]
    public GameObject thirdPersonCam;
    public GameObject combatCam;

    [Header("Camera")]
    public CameraStyle currentStyle;
    public Transform orientation;
    public Transform player;
    public Transform playerObj;
    public Rigidbody rb;
    public float rotationSpeed;
    public Transform combatLookAt;

    [Header("Movement")]
    public float moveSpeed;
    float horizontalInput;
    float verticalInput;
    Vector3 moveDirection;

    [Header("Grounded")]
    public float playerHeight;
    public LayerMask whatIsGround;
    bool grounded;
    public float groundDrag;

    [Header("Jumping")]
    public float jumpForce;
    public float jumpCooldown;
    public float airMultiplier;
    bool readyToJump;

    public enum CameraStyle
    {
        Basic,
        Combat
    }

    private void Awake()
    {
        controls = new DeviceControls();
        controls.Gameplay.Jump.performed += ctx => { Jump(); };
    }

    private void Start()
    {
        Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = false;
        rb.freezeRotation = true;
        readyToJump = true;
        AimCancel();
    }

    private void Update()
    {
        Vector3 viewDir = player.position - new Vector3(transform.position.x, player.position.y, transform.position.z);
        orientation.forward = viewDir.normalized;

        grounded = Physics.Raycast(transform.position, Vector3.down, playerHeight * 0.5f + 0.2f, whatIsGround);
        if (grounded) rb.drag = groundDrag;
        else rb.drag = 0;

        MyInput();
        SpeedControl();

        if (currentStyle == CameraStyle.Basic)
        {
            moveDirection = orientation.forward * verticalInput + orientation.right * horizontalInput;
            if (moveDirection != Vector3.zero) playerObj.forward = Vector3.Slerp(playerObj.forward, moveDirection.normalized, Time.deltaTime * rotationSpeed);
        }
        else if (currentStyle == CameraStyle.Combat)
        {
            Vector3 dirToCombatLookAt = combatLookAt.position - new Vector3(transform.position.x, player.position.y, transform.position.z);
            orientation.forward = dirToCombatLookAt.normalized;
            playerObj.forward = dirToCombatLookAt.normalized;
        }
    }

    private void FixedUpdate()
    {
        MovePlayer();
    }

    private void MyInput()
    {
        horizontalInput = Input.GetAxis("Horizontal");
        verticalInput = Input.GetAxis("Vertical");
    }

    private void MovePlayer()
    {
        if (grounded) rb.AddForce(moveDirection.normalized * moveSpeed * 10f, ForceMode.Force);
        else if (!grounded) rb.AddForce(moveDirection.normalized * moveSpeed * 10f * airMultiplier, ForceMode.Force);
    }

    private void SpeedControl()
    {
        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()
    {
        if (readyToJump && grounded)
        {
            readyToJump = false;
            rb.velocity = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
            rb.AddForce(transform.up * jumpForce, ForceMode.Impulse);
            Invoke(nameof(ResetJump), jumpCooldown);
        }
        else return;
    }

    private void ResetJump()
    {
        readyToJump = true;
    }

    private void SwitchCameraStyle(CameraStyle newStyle)
    {
        thirdPersonCam.SetActive(false);
        combatCam.SetActive(false);

        if (newStyle == CameraStyle.Basic) thirdPersonCam.SetActive(true);
        if (newStyle == CameraStyle.Combat) combatCam.SetActive(true);

        currentStyle = newStyle;
    }

    private void AimStart()
    {
        SwitchCameraStyle(CameraStyle.Combat);
    }

    private void AimCancel()
    {
        SwitchCameraStyle(CameraStyle.Basic);
    }

    public void OnEnable()
    {
        controls.Enable();
    }

    public void OnDisable()
    {
        controls.Disable();
    }
}

我尝试修改 Update() 函数中的一些选项,但我对值的调整并没有影响结果。

c# unity-game-engine input cinemachine
1个回答
0
投票

确保您的移动矢量与相机的方向对齐。修改

Update()
中的移动计算以考虑相机的当前旋转,而不仅仅是玩家的初始方向。这会将玩家的移动方向与摄像机的视角方向同步。

© www.soinside.com 2019 - 2024. All rights reserved.