即使使用 Time.deltaTime,玩家的移动也是依赖于帧的

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

我正在尝试将我朋友的 Scratch 游戏移植到 Unity 来娱乐,但减速代码导致玩家根据帧速率加速和减慢。最大 X 速度应为 6.75,即 30 fps(scratch 的通常帧速率),但当 FPS 更改时,其速度会变化到约 7.5。 代码(未完成):

 using System.Collections.Generic;
 using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    public Vector2 Velocity, WallJumpForce;
    public float Acceleration, Decceleration;
    public float Gravity, JumpForce;
    public int TargetFPS;

    void Update()
    {
        Velocity.y -= Gravity;
        if(Input.GetKey("right") || Input.GetKey("d"))
        Velocity.x += Acceleration * SDT();
        if(Input.GetKey("left") || Input.GetKey("a"))
        Velocity.x -= Acceleration * SDT();
        Velocity.x -= Velocity.x*(1-Decceleration) * SDT();
        Move(Velocity.x, 0);
        Debug.Log(1 / Time.deltaTime + ", " + SDT());
        Application.targetFrameRate = TargetFPS;
    }

    void Move(float x, float y) //Converts Scratch Units to Unity Units
    {
        transform.position += new Vector3(x, y, 0) * 1.2f * Time.deltaTime;
    }
    
    float SDT() //Basically allows Scratch variables designed for 30fps work in unity
    {
        return 30 * Time.deltaTime;
    }
}

我发现改变

Velocity.x *= Decceleration * SDT();
Velocity.x -= Velocity.x*(1-Decceleration) * SDT();
有帮助,但不能解决问题。 作为参考,这是我正在移植的游戏。 https://scratch.mit.edu/projects/590825095

c# unity-game-engine frame-rate
2个回答
3
投票

帮自己一个忙,每次写物理方程时验证一下你的单位。在这种情况下,验证您的单位将解决问题。

速度的单位为距离/时间,重力的单位为距离/(时间^2)。
因此,让我们检查一下这一行的单位:

 Velocity.y -= Gravity;

你是说距离/时间-=距离/(时间^2)。
那些单位不起作用!

显然,您必须将

Gravity
乘以一定的时间才能获得速度的变化。为此,我们有 Δt,即自上一帧以来经过的时间量:

Velocity.y -= Gravity * Time.deltaTime;

现在的单位是距离/时间 -= 距离/(时间^2)*时间。这更有意义。 对所有物理方程执行此操作,您的问题就会得到解决。


0
投票

晚了几年,但以防万一有人偶然发现这一点。您应该使用FixedUpdate() 进行移动。我相信在某些情况下,固定更新每帧运行多次,并且出于这个确切原因而设计为以固定间隔运行。

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