Time.deltaTime无法正常工作

时间:2016-05-05 12:33:19

标签: c# unity3d

我写了以下代码:

using UnityEngine;
using System.Collections;

public class ObstacleSpawn : MonoBehaviour {

    public PlayerScript pScript;
    public ObstacleScript oScript;

    public GameObject player;
    public GameObject obstacle;

    public float randomSpawnMin;
    public float randomSpawnMax;

    // Use this for initialization
    void Start () {
        InvokeRepeating ("Spawn", 2F, Random.Range (randomSpawnMin, randomSpawnMax));
    }

    // Update is called once per frame
    void Update () { 

    }

    void Spawn() {
        if (pScript.isRight == true && pScript.inAir == false) {
            obstacle.transform.localScale = new Vector3 (-1, 1, 1);
            Instantiate (obstacle, player.transform.position + new Vector3 (0.05F, (4F + pScript.playerDimensionY + oScript.obstacleDimensionY) * Time.deltaTime, 0), Quaternion.identity);
        } else if (pScript.isRight == false && pScript.inAir == false) {
            obstacle.transform.localScale = new Vector3 (1, 1, 1);
            Instantiate (obstacle, player.transform.position + new Vector3 (-0.05F, (4F + pScript.playerDimensionY + oScript.obstacleDimensionY) * Time.deltaTime, 0), Quaternion.identity);
        }
    }
}

在我的void Spawn()中,我生成了一个名为障碍物的物品,它应该在几秒钟内从我的玩家身上实现所需的数量。 (等等。它应该在击中玩家之前2秒,或者1秒等等。你在我的虚空中可以看到的是我在玩家的位置实例化障碍物+我测量的数量,然后乘以时间。 deltaTime。但是我的距离不会改变,我改变我的值是否乘以Time.deltaTime。我的对象之间的距离总是0.02秒。

如何解决此问题以自定义时间间隔?

编辑 - 为了澄清这是2D,我也将展示这个例子来创造一些理解。 我尝试删除Time.deltaTime的乘法,因为程序运动确实在deltaTime中运行:

void Spawn() {
        if (pScript.isRight == true && pScript.inAir == false) {
            obstacle.transform.localScale = new Vector3 (-1, 1, 1);
            Instantiate (obstacle, player.transform.position + new Vector3 (0.05F, (4F + pScript.playerDimensionY + oScript.obstacleDimensionY), 0), Quaternion.identity);
        } else if (pScript.isRight == false && pScript.inAir == false) {
            obstacle.transform.localScale = new Vector3 (1, 1, 1);
            Instantiate (obstacle, player.transform.position + new Vector3 (-0.05F, (4F + pScript.playerDimensionY + oScript.obstacleDimensionY), 0), Quaternion.identity);
        }
    }

显示的代码给我一个0.58秒的间隔,这至少是一个间隔。有了这个逻辑,我相信这段代码应该提供1.16间隔(间隔的两倍):

void Spawn() {
        if (pScript.isRight == true && pScript.inAir == false) {
            obstacle.transform.localScale = new Vector3 (-1, 1, 1);
            Instantiate (obstacle, player.transform.position + new Vector3 (0.05F, (8F + pScript.playerDimensionY + oScript.obstacleDimensionY), 0), Quaternion.identity);
        } else if (pScript.isRight == false && pScript.inAir == false) {
            obstacle.transform.localScale = new Vector3 (1, 1, 1);
            Instantiate (obstacle, player.transform.position + new Vector3 (-0.05F, (8F + pScript.playerDimensionY + oScript.obstacleDimensionY), 0), Quaternion.identity);
        }
    }

然而,这给出了0.92间隔的结果,而不是1.16 - 这是我真正感到困惑的地方。

编辑背景:

enter image description here

红色障碍总是向下移动以击中玩家,但是我需要它在可调节的时间产生(距离1秒,距离0.5秒等)。

2 个答案:

答案 0 :(得分:6)

Time.deltaTime的使用仅在Update方法中有意义。确保从Update()或LateUpdate()调用Spawn()方法。 更具体地说,deltaTime属性存储自上次更新调用以来的确切时间量。 无论如何,我不确定你为什么要让这个距离取决于帧速率。如果你知道你的运动员的速度,你应该让他的运动时间依赖,但不是距离计算。 为了使用inverval生成对象,我建议使用coroutine。这样的事情:

private IEnumerator CoSpawn()
    {
        while (true)//you can put here any stop condition, otherwise this coroutine will run while gameObject exists and its not stopped by StopCoroutine()
        {
            //actual Spawn() call that will instantiate a new obstacle

            yield return new WaitForSeconds(Random.Range(0, randomSpawnMax) + 2f); //pause for [2-(2+randomSpawnMax)] interval
        }
    }

您可以使用Start()方法中的StartCoroutine()而不是InvokeRepeating()来启动此协程。

<强>更新 好吧,如果你想计算障碍物的正确距离,那么我认为速度是恒定的。如果是这样,您可以通过这种方式将障碍物移动到玩家:

private void _Update()
    {
        var characterPosition = //cant say what it should be in your case
        MoveTo(characterPosition);
    }

    private void MoveTo(Vector3 target)
    {
        //use 'transform' if you`re moving the obstacle from the script that is attached to it
        //if your moving it from some scene controller or anywhere else, call [Obstacle].transform
        transform.position = Vector3.MoveTowards(transform.position, target, Speed * Time.deltaTime);
    }

在此代码中,速度值应该在两种方法中都可用 - 移动障碍物的方法和实例化方法的方法。例如,您可以使Speed保持不变或将其放在某个全局配置脚本中。 在Spawn()方法中,您可以计算正确的距离:

{
   var timeToFall = 2f;//amount of time that the obstacle will fall
   var position = new Vector3(0, timeToFall * Speed, 0);
}

答案 1 :(得分:0)

Time.deltaTime存储帧之间的时差。使用Time.deltaTime只有在Update方法上使用它才有意义,每个帧都会调用它。

在您的情况下,您可以计算每次Spawn()来电之间经过的时间。将当前Time.time存储在属性中,并计算上次Spawn执行之间的差异:

float lastUpdate = 0;    

void Spawn() {
    float myDelta = Time.time - lastTime;
    lastUpdate = Time.time

然后将Time.deltaTime替换为myDelta变量:

float lastUpdate = 0;    

void Spawn() {
    float myDelta = Time.time - lastTime;
    lastUpdate = Time.time

    if (pScript.isRight == true && pScript.inAir == false) {
        obstacle.transform.localScale = new Vector3 (-1, 1, 1);
        Instantiate (obstacle, player.transform.position + new Vector3 (0.05F, (4F + pScript.playerDimensionY + oScript.obstacleDimensionY) * myDelta, 0), Quaternion.identity);
    } else if (pScript.isRight == false && pScript.inAir == false) {
        obstacle.transform.localScale = new Vector3 (1, 1, 1);
        Instantiate (obstacle, player.transform.position + new Vector3 (-0.05F, (4F + pScript.playerDimensionY + oScript.obstacleDimensionY) * myDelta, 0), Quaternion.identity);
    }
}