为什么当我移动和相机旋转时物体会卡顿?

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

我已经开始开发 fps 脚本,并按照教程来帮助编写该脚本。现在一切都很好,但唯一的问题是,每当玩家同时移动和旋转时,视图中的任何对象似乎都会卡顿。 玩家移动和摄像机旋转的脚本如下。 有人能指出我正确的方向吗? 谢谢。

{

public Transform cam;
public Rigidbody rb;

public float camRotationSpeed = 5f;
public float camMinimumY = -60f;
public float camMaximumY = 75f;
public float rotationSmoothSpeed = 10f;

public float walkSpeed = 9f;
public float runSpeed = 14f;
public float maxSpeed = 20f;
public float jumpPower = 30f;

public float extraGravity = 45;

float bodyRotationX;
float camRotationY;
Vector3 directionIntentX;
Vector3 directionIntentY;
float speed;

public bool grounded;

void Update()
{
    LookRotation();
    Movement();
    ExtraGravity();
    GroundCheck();
    if(grounded && Input.GetButtonDown("Jump"))
    {
        Jump();
    }
}

void LookRotation()
{
    Cursor.visible = false;
    Cursor.lockState = CursorLockMode.Locked;

    bodyRotationX += Input.GetAxis("Mouse X") * camRotationSpeed;
    camRotationY += Input.GetAxis("Mouse Y") * camRotationSpeed;

    camRotationY = Mathf.Clamp(camRotationY, camMinimumY, camMaximumY);

    Quaternion camTargetRotation = Quaternion.Euler(-camRotationY, 0, 0);
    Quaternion bodyTargetRotation = Quaternion.Euler(0, bodyRotationX, 0);

    transform.rotation = Quaternion.Lerp(transform.rotation, bodyTargetRotation, Time.deltaTime * rotationSmoothSpeed);
    cam.localRotation = Quaternion.Lerp(cam.localRotation, camTargetRotation, Time.deltaTime * rotationSmoothSpeed);
}

void Movement()
{
    directionIntentX = cam.right;
    directionIntentX.y = 0;
    directionIntentX.Normalize();

    directionIntentY = cam.forward;
    directionIntentY.y = 0;
    directionIntentY.Normalize();

    rb.velocity = directionIntentY * Input.GetAxis("Vertical") * speed + directionIntentX * Input.GetAxis("Horizontal") * speed + Vector3.up * rb.velocity.y;
    rb.velocity = Vector3.ClampMagnitude(rb.velocity, maxSpeed);

    if (Input.GetKey(KeyCode.LeftShift))
    {
        speed = runSpeed;
    }
    if (!Input.GetKey(KeyCode.LeftShift))
    {
        speed = walkSpeed;
    }

}

void ExtraGravity()
{
    rb.AddForce(Vector3.down * extraGravity);
}

void GroundCheck()
{
    RaycastHit groundHit;
    grounded = Physics.Raycast(transform.position, -transform.up, out groundHit, 1.25f);
}

void Jump()
{
    rb.AddForce(Vector3.up * jumpPower, ForceMode.Impulse);
}

}

c# unity-game-engine camera rotation rigid-bodies
2个回答
0
投票

发生这种情况可能是因为框架需要同时更新相机旋转和玩家位置。我建议在固定更新中旋转相机。因为这将在每一帧的末尾运行。

像这样:

    void FixedUpdate()
    {
         LookRotation();
    }

我建议的另一件事是在运行地面检查时移动玩家,因为如果你单独这样做,我可以看到当玩家移动速度更快时代码可以运行或其他东西时会出现错误。因此,建议是或者在移动方法中运行它,或者在调用移动方法时调用该方法。

这个:

    void Movement()
{
directionIntentX = cam.right;
directionIntentX.y = 0;
directionIntentX.Normalize();

directionIntentY = cam.forward;
directionIntentY.y = 0;
directionIntentY.Normalize();

rb.velocity = directionIntentY * Input.GetAxis("Vertical") * speed + directionIntentX * Input.GetAxis("Horizontal") * speed + Vector3.up * rb.velocity.y;
rb.velocity = Vector3.ClampMagnitude(rb.velocity, maxSpeed);

if (Input.GetKey(KeyCode.LeftShift))
{
    speed = runSpeed;
}
if (!Input.GetKey(KeyCode.LeftShift))
{
    speed = walkSpeed;
}
   GroundCheck();

}

或者随意复制代码并将其粘贴到您的移动方法中。


0
投票

以防万一其他人正在看这里,您之所以出现口吃是因为您的旋转代码与帧率无关。

Jadon 的答案大多有效,因为通过将其放入固定更新中,您可以确保您想要移动相机的量以固定的时间差一致地发生。 由于某种原因,我仍然注意到这种方法有点口吃。

无论如何,这是一个没有口吃的解决方案:

void Update()
{
    Vector2 axis = InputManager.pcInput.Player.Look.ReadValue<Vector2>();
    mouseX = axis.x * sensitivity;
    mouseY = axis.y * sensitivity;

    rotation.x -= mouseY * Time.deltaTime;
    rotation.x = Mathf.Clamp(rotation.x, maxDownAngle, maxUpAngle);
    rotation.y += mouseX * Time.deltaTime;

    SpectatorCam.transform.localRotation = Quaternion.Euler(rotation);

    //Movement
    Vector2 moveAxis = InputManager.pcInput.Player.Move.ReadValue<Vector2>();
    hInput = moveAxis.x;
    vInput = moveAxis.y;

    Vector3 movement = (SpectatorCam.transform.forward * vInput + SpectatorCam.transform.right * hInput).normalized * (InputManager.pcInput.Player.Run.phase == InputActionPhase.Performed ? fastMoveSpeed : slowMoveSpeed);
    movement *= Time.deltaTime;

    SpectatorCam.transform.position += movement;
}
© www.soinside.com 2019 - 2024. All rights reserved.