使用Invoke延迟Update()

时间:2015-11-02 13:00:19

标签: unity3d

是否可以延迟附加到游戏对象的脚本的效果?

我在场景中有2个字符,都接收实时动作捕捉数据,因此它们都是相同的动画。我将一个旋转180度并将其放在另一个前面,以产生他们互相复制/镜像的印象。当然,每个都附有几个脚本。

现在,我希望能够延迟一个角色(例如1秒),使其看起来更逼真,好像一个角色正在观察另一个角色,然后复制其精确的动作。

我试图通过缓冲到达第二个字符的动画数据(网络数据)来实现这一点。下面是代码片段,它会动画第一个字符立即

class Job(models.Model):
    name = models.CharField(max_length=200)
    description = models.TextField(default='Add comprehensive job description')
    # parametes
    lat_lim=[MinValueValidator(-90), MaxValueValidator(90)]
    long_lim=[MinValueValidator(-180), MaxValueValidator(180)]
    lattitude = models.IntegerField('Lattitude North default value', null=True, validators=lat_lim)
    longitude = models.IntegerField('Lattitude South default value', null=True, validators=long_lim)
    time_query_begin = models.DateField('Job query start time', null=True, blank=True)
    ...

以下是应该为第二个角色制作动画的代码片段,但实际上根本没有动作:

void Update()
{
    Vector3[] latestPositions;
    Quaternion[] latestOrientations;

    if (mvnActors.getLatestPose(actorID-1, out latestPositions, out latestOrientations))
    {
            updateMvnActor(currentPose, latestPositions, latestOrientations);
            updateModel(currentPose, targetModel);
    }
}

Isn&#39; t private Queue<Vector3[]> posQueue; private Queue<Quaternion[]> rotQueue; void Start() { posQueue = new Queue<Vector3[]>(); rotQueue = new Queue<Quaternion[]>(); } void Update() { Vector3[] latestPositions; Quaternion[] latestOrientations; if (mvnActors.getLatestPose(actorID-1, out latestPositions, out latestOrientations)) { posQueue.Enqueue(latestPositions); rotQueue.Enqueue(latestOrientations); if ((posQueue.Count > 10) && (rotQueue.Count > 10)) { Vector3[] delayedPos = posQueue.Peek(); Quaternion[] delayedRot = rotQueue.Peek(); updateMvnActor(currentPose, delayedPos, delayedRot); updateModel(currentPose, targetModel); } } } 应该提供队列中的第一个元素,这里是第11个元素?或者是因为队列不适合繁重的动画更新?

编辑:已解决

peek添加到类变量(替换数字10)并使用int delayedFrames = 30;代替Dequeue

2 个答案:

答案 0 :(得分:1)

我认为你不能推迟Update方法。

您可以使用的是WaitForSeconds,或者您可以使用基于if的{​​{1}}语句测试是否过了1秒。

然后执行代码以移动第二个字符。

修改

我认为一个简单的计时器可以完成这项任务,但是你需要在获得最新的位置/方向时考虑1秒的时间。

Time

否则,您可以使用InvokeRepeating作为参数,每隔X秒重复一次方法。

要仅采取延迟之前所做的操作,您可以在完成操作时记录时间,并删除&#39;延迟期间采取的行动,并采取行动。

或者记录延迟期间第一个字符所做的操作次数,并删除相同数量的操作(最后一个)到第二个字符的更新。 (似乎更容易/更简单)

像这样,我假设第二个角色不会在延迟期间做最后的动作,但会在之后做。

答案 1 :(得分:1)

编辑:回答@ JTech的问题在这个答案中没有完整,请查看他/她的问题中最终解决方案的评论

我个人不喜欢WaitForSeconds,它减慢了我的游戏速度。 尝试类似:

public List<Vector3[]> PreviousPositions;
public List<Quaternion[]> PreviousRotations;
private Vector3[] latestPositions;
private Quaternion[] latestOrientations;


void Start(){
    PreviousPositions = new List<Vector3[]>();
    PreviousRotations = new List<Quaternion[]>();
}


void Update(){
    if (mvnActors.getLatestPose(actorID-1, out latestPositions, out latetOrientations))
    {
        updateModel(currentPose, targetModel);

        //Add the position and rotationstuff to the 'buffer' lists here
        Invoke("DoStuff", 1); 

    }
}


void DoStuff(){
    updateMvnActor(currentPose, PreviousPositions[0] , PreviousRotations[0]);
    PreviousPositions.RemoveAt(0);
    PreviousRotations.RemoveAt(0);

}

OnApplicationQuit(){
    CancelInvoke();
}