我正在尝试使用新的输入系统创建一个 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() 函数中的一些选项,但我对值的调整并没有影响结果。
确保您的移动矢量与相机的方向对齐。修改
Update()
中的移动计算以考虑相机的当前旋转,而不仅仅是玩家的初始方向。这会将玩家的移动方向与摄像机的视角方向同步。