【问题标题】:InvokeRepeating not using Random.Range but initially set value insteadInvokeRepeating 不使用 Random.Range 而是最初设置值
【发布时间】:2021-04-04 17:46:04
【问题描述】:

我已经被这个困惑了几个小时了:

我有一个变量“spawnInterval”,用于在通过称为 InvokeRepeating 的方法调用函数时随机化对象在屏幕上生成的间隔。

在函数“SpawnRandomBall”中,值是随机的,然后运行其余代码来实例化球并随机化其在屏幕上的 X 位置。

但是,当 spawnInterval 值是随机的并且再次调用 InvokeRepeating 时,它不会考虑 'spawnInterval 新分配的值,并且只会在值已设置为开头时重复。

如果为 0,则根本不会重复。

如果它是任何其他正值,它将在该值/时间重复实例化。

如果我尝试将 InvokeRepeating 中的 spawnInterval 设置为以 Random.Range 结尾,它将生成一个新值,但只会生成一次,因为它位于 void Start() 函数中。

我已经使用 debug.log() 来检查以确保 spawnInterval 变量确实是随机化的,但 InvokeRepeating 似乎忽略了对值的更改。

private float spawnLimitXLeft = -22;
private float spawnLimitXRight = 7;
private float spawnPosY = 30;
private float startDelay = 3.0f;

// This value needs an initial value set otherwise it won't repeat in the InvokeRepeating method.
// random.range cannot be used here
float spawnInterval = 0.5f; 


// Start is called before the first frame update
void Start()
{
    // Though spawnInterval's value is changed when the SpawnRandomBall method is called, it doesn't effect InvokeRepeating as it should.
    InvokeRepeating("SpawnRandomBall", startDelay, spawnInterval); 
}


// Spawn random ball at random x position at top of play area
void SpawnRandomBall ()
{
    // Randomise ball interval
    // Gave up and used HINT which gave me this solution. Ultimately didn't work either
    spawnInterval = Random.Range(0.1f, 6.0f);

    // Generate random ball index and random spawn position
    int ballIndex = Random.Range(0, ballPrefabs.Length);
    Vector3 spawnPos = new Vector3(Random.Range(spawnLimitXLeft, spawnLimitXRight), spawnPosY, 0);

    // instantiate ball at random spawn location
    Instantiate(ballPrefabs[ballIndex], spawnPos, ballPrefabs[0].transform.rotation);
}


void Update()
{
    // Displays spawnInterval float variable randomising but not effecting the InvokeRepeating method
    Debug.Log(spawnInterval);
}

}

这是关于 Unity Learning 的初级程序员课程路径的一部分,那里的许多学习者都遇到了同样的问题,但他们自己还没有弄清楚,他们提供的提示并不能解决问题。

因此,这里任何人所能提供的任何帮助最终都会帮助很多其他人。

谢谢。

【问题讨论】:

    标签: c# visual-studio unity3d


    【解决方案1】:

    嗯,是的,InvokeRepeating 只接受参数一次。之后更改本地字段值不会更改您在开始时已经传递给方法调用的值。 floatvalue 类型,不通过引用传递!

    而只是递归地使用Invoke

    void Start()
    {
        Invoke(nameof(SpawnRandomBall), startDelay); 
    }
    
    void SpawnRandomBall ()
    {
        spawnInterval = Random.Range(0.1f, 6.0f);
    
        int ballIndex = Random.Range(0, ballPrefabs.Length);
        var spawnPos = new Vector3(Random.Range(spawnLimitXLeft, spawnLimitXRight), spawnPosY, 0);
    
        Instantiate(ballPrefabs[ballIndex], spawnPos, ballPrefabs[0].transform.rotation);
    
        // Trigger the invokation of the next recursive call
        Invoke(nameof(SpawnRandomBall), spawnInterval);
    }
    

    【讨论】:

    • 现在这实际上很有意义,InvokeRepeating 只是获取初始值并保留它而不接受任何新值。 Invoke 在开始时会延迟调用一次,然后根据 Interval 计时器无限期地再次调用 SpawnRandomBall()。神奇,喜欢。在那里学到了很多东西,谢谢!
    猜你喜欢
    • 1970-01-01
    • 2016-04-25
    • 1970-01-01
    • 1970-01-01
    • 2016-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多