简体   繁体   English

InvokeRepeating 不使用 Random.Range 而是最初设置值

[英]InvokeRepeating not using Random.Range but initially set value instead

I've been puzzled by this one for a few hours now:我已经被这个困惑了几个小时了:

I have a variable 'spawnInterval' that is used to randomise the interval at which objects spawn on screen when a function is called by way of a method called InvokeRepeating.我有一个变量“spawnInterval”,用于在通过称为 InvokeRepeating 的方法调用 function 时随机化对象在屏幕上生成的间隔。

In the function 'SpawnRandomBall' the value is randomised and the rest of the code is run to instantiate the ball and randomise its X location on screen.在 function 'SpawnRandomBall' 中,值是随机的,代码的 rest 运行以实例化球并随机化其在屏幕上的 X 位置。

However, when the spawnInterval value is randomised and InvokeRepeating is called again it doesn't take into account 'spawnInterval's newly assigned value and will only repeat if a value has been set to begin with.但是,当 spawnInterval 值是随机的并且再次调用 InvokeRepeating 时,它不会考虑 'spawnInterval 新分配的值,并且只会在已将值设置为开头时重复。

If it's 0 then it won't repeat at all.如果为 0,则根本不会重复。

If it's any other positive value, it will repeat instantiate at that value/time.如果它是任何其他正值,它将在该值/时间重复实例化。

If I try and set the spawnInterval inside InvokeRepeating to end with Random.Range it will generate a new value but only once as it's in the void Start() function.如果我尝试将 InvokeRepeating 中的 spawnInterval 设置为以 Random.Range 结尾,它将生成一个新值,但只会生成一次,因为它位于 void Start() function 中。

I've used debug.log() to check to make sure the spawnInterval variable is indeed randomising and it is, but InvokeRepeating is seemingly ignoring that change to the value.我已经使用 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);
}

} }

This is part of a Junior Programmer course pathway on Unity Learning and a lot of learners on there are running into the same problem but have yet to figure this out themselves and the hints they've provided don't solve the issue.这是关于 Unity Learning 的初级程序员课程路径的一部分,那里的许多学习者都遇到了同样的问题,但他们自己还没有弄清楚,他们提供的提示并不能解决问题。

So any help anyone here can provide will ultimately help a lot of other people.因此,这里任何人可以提供的任何帮助最终都会帮助很多其他人。

Thank you.谢谢你。

Well, yes, InvokeRepeating takes the parameters only once .嗯,是的, InvokeRepeating只接受参数一次 Changing your local field value afterwards doesn't change the values you have already passed into the method call at the beginning.之后更改本地字段值不会更改您在开始时已经传递给方法调用的值。 float is a value type and is not passed by reference! float是一个类型,不是通过引用传递的!

Instead just use Invoke recursively like相反,只需像递归一样使用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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM