【问题标题】:Unity 3D Jumping issueUnity 3D跳跃问题
【发布时间】:2021-06-29 15:31:43
【问题描述】:

我一直在学习 3D 射击游戏教程(到目前为止还不错),但在帧速率和跳跃方面遇到了障碍。我的电脑上的帧率并不一致,因此跳跃高度不断变化,有时角色根本不跳跃。我知道处理 Update(而不是 FixedUpdate)中的跳转可能会导致有关帧速率的问题,但本教程坚持认为使用 Time.deltaTime 应该可以解决该问题。关于我应该做些什么来保持我的跳跃一致有什么想法吗?

 //Jumping
public float jumpHeight = 10f;
public Transform ground;
private bool readyToJump;
public LayerMask groundLayer;
public float groundDistance = 0.5f;

// Update is called once per frame
private void Update()
{
    Jump();
    PlayerMovement();
    CameraMovement();
    Shoot();

}
    


void PlayerMovement()
{
    float x = Input.GetAxis("Horizontal");
    float z = Input.GetAxis("Vertical");

    Vector3 movement = x * transform.right + z * transform.forward;

    myController.Move(movement * speed * Time.deltaTime);


    
    //9.8 meters/second^2
    velocity.y += Physics.gravity.y * Mathf.Pow(Time.deltaTime, 2) * gravityModifier;
    if (myController.isGrounded)
    {
        velocity.y = Physics.gravity.y * Time.deltaTime;
        
    }



    myController.Move(velocity);
}

private void CameraMovement()
{

    float mouseX = Input.GetAxisRaw("Mouse X") * mouseSensitivity * Time.deltaTime;
    float mouseY = Input.GetAxisRaw("Mouse Y") * mouseSensitivity * Time.deltaTime;
    cameraVerticalRotation -= mouseY;
    cameraVerticalRotation = Mathf.Clamp(cameraVerticalRotation, minVertCameraAngle, maxVertCameraAngle);
    transform.Rotate(Vector3.up * mouseX);

    myHead.localRotation = Quaternion.Euler(cameraVerticalRotation, 0f, 0f);

}


void Jump()
{
    readyToJump = Physics.OverlapSphere(ground.position, groundDistance, groundLayer).Length > 0;
    if (Input.GetButtonDown("Jump") && readyToJump)
    {
        velocity.y = Mathf.Sqrt(jumpHeight * -2f * Physics.gravity.y) * Time.deltaTime;
    }
    myController.Move(velocity);
}

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    自己处理加速是个坏主意,尤其是在Update 而不是FixedUpdate 中。您应该知道,在现实生活中,速度会随着加速度随时间平滑地变化。如果你画一条曲线,它就是一个直线斜率。但是,在计算机中,如果你只是逐帧计算速度,曲线会看起来像楼梯。

    您可以使用 Unity 中的物理引擎并在角色跳跃时为其添加即时速度。只需让 Unity 处理加速即可。

    首先,您需要为其添加一个Rigidbody 组件。然后,您可以将代码修改为:

    private Rigidbody rb;
    
    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }
    
    void Jump()
    {
        readyToJump = Physics.OverlapSphere(ground.position, groundDistance, groundLayer).Length > 0;
        if (Input.GetButtonDown("Jump") && readyToJump)
        {
            rb.velocity = Vector3.up * jumpHeight * 2f / -Physics.gravity.y * gravityModifier;
        }
    }
    

    Rigidbody 组件中有Use Gravity 之后,不要忘记删除PlayerMovement 中的处理坠落的代码。

    编辑

    如果你使用CharacterController,你只能自己处理加速。您可以将逻辑移至FixedUpdate 以解决各种高度问题,或者进行更准确的模拟。例如,使用它来处理跳跃:

    velocity.y = jumpHeight * 2f / -Physics.gravity.y * gravityModifier;
    

    并用它来处理跌倒:

    myController.Move(velocity * Time.deltaTime + Physics.gravity * Mathf.Pow(Time.deltaTime, 2) / 2f * gravityModifier);
    // Here you should check whether it will fall through the ground.
    // If no, use this line to update the velocity.
    velocity.y += Physics.gravity.y * gravityModifier * Time.deltaTime;
    // Otherwise, update the position to make it on ground and set velocity.y to 0.
    

    【讨论】:

    • 我使用的是 CharacterController 而不是 RigidBody。贴过来的时候被剪掉了,不过名字是myController;
    • 在使用CharacterController时,您仍然可以将Rigidbody组件添加到游戏对象中。
    • 我尝试了修改,但现在跳转根本不起作用。我检查并发现 rb.velocity 正在改变,但角色根本没有垂直移动。
    • 哦,很抱歉这个错误信息。看来您只能使用RigidbodyCharacterController。如果您想继续使用CharacterController,让我们处理FixedUpdate 的跳跃和跌落。在Update 中使用Time.deltaTime 无法解决各种高度问题。
    • 我将输入检查保持在更新中,并将下降和跳跃都移动到固定更新中,这似乎已经解决了这个问题。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-12
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多