调用重复()限制?(C#)

调用重复()限制?(C#),c#,unity3d,C#,Unity3d,我目前正在尝试以给定的速率实例化游戏对象。通常,invokereepeating可以完成这项工作,但这次我不希望在实例化对象时速率是常量 我知道应该在代码的Start()部分内调用InvokeRepeating。所以我的问题是:有没有办法绕过这个问题,或者我必须采取不同的方法 提前谢谢大家 下面是代码的一部分,它说明了我所说的问题: using UnityEngine; using System.Collections; public class InstantiateLARSpider :

我目前正在尝试以给定的速率实例化游戏对象。通常,invokereepeating可以完成这项工作,但这次我不希望在实例化对象时速率是常量

我知道应该在代码的Start()部分内调用InvokeRepeating。所以我的问题是:有没有办法绕过这个问题,或者我必须采取不同的方法

提前谢谢大家

下面是代码的一部分,它说明了我所说的问题:

using UnityEngine;
using System.Collections;

public class InstantiateLARSpider : MonoBehaviour {

public float instantiateRate;
public GameObject xSpider;
private Vector3 position;
public float minimumSpeed;

void Start () {

    // instantiateRate is a variable that I want to modify over time.  
    InvokeRepeating("NewSpider", 1.0f, instantiateRate);
}

void NewSpider ()
{
    position = new Vector3(transform.position.x, Random.Range(-4.5f,4.5f), 0);
    Debug.Log("Instantiated");
    var Spider = Instantiate(xSpider, position, Quaternion.identity) as GameObject;
    if(transform.position.x>=11.0f){
        Spider.rigidbody2D.velocity = new Vector2(-1.0f * Random.Range(minimumSpeed, 6.0f), 0.0f);
    }
    else if(transform.position.x<=-11.0f){
        Spider.rigidbody2D.velocity = new Vector2(1.0f * Random.Range(minimumSpeed, 6.0f), 0.0f);
    }
    //I was thinking about increasing the instantiateRate by 0.1 every time a Spider is instantiated.
    instantiateRate -= 0.1f;
    minimumSpeed += 0.1f;
}
使用UnityEngine;
使用系统集合;
公共类实例化elarspider:单行为{
公开上市;
公共游戏对象xSpider;
私有向量3位置;
公共浮动最低速度;
无效开始(){
//InstanceRate是我希望随时间修改的变量。
调用重复(“NewSpider”,1.0f,实例化);
}
void NewSpider()
{
位置=新矢量3(变换位置x,随机范围(-4.5f,4.5f),0);
Log(“实例化”);
var Spider=实例化(xSpider、position、Quaternion.identity)作为游戏对象;
if(transform.position.x>=11.0f){
Spider.rigidbody2D.velocity=新矢量2(-1.0f*随机范围(最小速度6.0f),0.0f);
}

else if(transform.position.x在本例中,在使用InstanceRate调用InvokeRepeating后更改InstanceRate实际上不会更改InvokeRepeating接收的参数的副本。要镜像InvokeRepeating的功能,您可能会得到类似于以下内容的结果:

    public delegate void MethodToCall(); //A delegate - you can pass in any method with the signature void xxx() in this case!
    public IEnumerator InvokeRepeatingRange(MethodToCall method, float timeUntilStart, float minTime, float maxTime)
    {
        yield return new WaitForSeconds(timeUntilStart);
        while (true)
        {
            method(); //This calls the method you passed in
            yield return new WaitForSeconds(Random.Range(minTime, maxTime))
        }
    } 
我在这台机器上没有Unity,因此我无法验证它是否编译(主要是Random.Range部分,其余部分我非常熟悉)。在您的情况下,您可以将其称为:

    void Start()
    {
        StartCoroutine(InvokeRepeatingRange(NewSpider, 2, 5, 10));
    }

    void NewSpider() //Since NewSpider matches the signature void xxx(), we can pass it to InvokeRepeatingRange()
    {
        //...
    }
调整InvokeRepeatingRange内部的参数和逻辑以获得所需的效果,也许:

    public delegate void MethodToCall();
    public IEnumerator InvokeRepeatingDecreasingTime(MethodToCall method, float timeUntilStart, float minTime, float maxTime)
    {
        float currentTime = maxTime;
        yield return new WaitForSeconds(timeUntilStart);
        while (currentTime >= minTime)
        {
            method();
            currentTime -= .1f;
            yield return new WaitForSeconds(currentTime);
        }
    }
希望这能给你一种新的方式来思考这种做事方式,并回答你最初的问题

编辑:更新以获得更好的变量名和更多的解释。
添加了comment!

中提到的StartRoutine()调用,而不是使用InvokeRepeating,为什么不在Update方法中执行此操作?可以使用字段跟踪上次创建新对象的时间

private float lastTimeCreated;
private float timeBetweenCreation;
...

void Start()
{
    // Initial time between object creation
    this.timeBetweenCreation = 1f;
}

void Update()
{
    float now = Time.time;

    // Check if it's time to create a new object
    if (now - this.lastTimeCreated > this.timeBetweenCreation)
    {
        this.NewSpider();

        // Object created, so set new lastTimeCreated
        this.lastTimeCreated = now;

        // Some logic to change your timeBetweenCreation.  Do it here or in NewSpider().
        // this.timeBetweenCreation = ...
    }
}

void NewSpider ()
{
    // Mostly what you had
    position = new Vector3(transform.position.x, Random.Range(-4.5f,4.5f), 0);
    Debug.Log("Instantiated");
    var Spider = Instantiate(xSpider, position, Quaternion.identity) as GameObject;
    if(transform.position.x>=11.0f){
        Spider.rigidbody2D.velocity = new Vector2(-1.0f * Random.Range(minimumSpeed, 6.0f), 0.0f);
    }
    else if(transform.position.x<=-11.0f){
        Spider.rigidbody2D.velocity = new Vector2(1.0f * Random.Range(minimumSpeed, 6.0f), 0.0f);
    }

    // Some logic to change your timeBetweenCreation.  Do it here or in Update().
    // this.timeBetweenCreation = ...
}
private float lastTimeCreated;
创建之间的私有浮动时间;
...
void Start()
{
//创建对象之间的初始时间间隔
该时间间隔为1f;
}
无效更新()
{
现在浮动=时间;
//检查是否到了创建新对象的时间
如果(现在-this.lastTimeCreated>this.timeBetweenCreation)
{
this.NewSpider();
//对象已创建,因此设置new lastTimeCreated
this.lastTimeCreated=now;
//更改timeBetweenCreation的一些逻辑。请在此处或在NewSpider()中执行此操作。
//this.timeBetweenCreation=。。。
}
}
void NewSpider()
{
//大部分是你所拥有的
位置=新矢量3(变换位置x,随机范围(-4.5f,4.5f),0);
Log(“实例化”);
var Spider=实例化(xSpider、position、Quaternion.identity)作为游戏对象;
if(transform.position.x>=11.0f){
Spider.rigidbody2D.velocity=新矢量2(-1.0f*随机范围(最小速度6.0f),0.0f);
}

else if(transform.position.x由于您希望以不断变化的速率实例化,我将使用
Invoke
而不是
invokererepeating

void Start () {
    Invoke("NewSpider", 1.0f);
}

void NewSpider () {
    ...
    Invoke("NewSpider", instantiateRate);
}

NewSpider
将首先在
Start
中被调用。然后,在
NewSpider
方法的末尾,
NewSpider
将被再次调用,无论
instantiate
设置为什么。

您是否可以在
新闻的末尾使用
Invoke
pider
method?这样你每次都可以选择延迟。谢谢你的回答!它们工作得很好。我决定接受aqez的回答,因为你只能接受一个。然而Chris answer功能完善且聪明。另外,如果知道其中一个是否比另一个消耗更多资源,那将非常好。在aplic中我所做的调整其实并不重要,但我有兴趣知道将来的情况。@AQEZ值得注意的是,将调用链接在一起可能最终导致堆栈溢出或内存问题,这取决于调用是否立即返回或在运行试图调用的方法后返回。如果是后者,您将填充具有潜在无限递归的调用堆栈取决于NewSpider的实现。答案可靠,尽管C#中的协同路由需要一个。我知道我忘记了什么,谢谢你指出!