繁体   English   中英

随着时间的推移移动游戏对象

[英]Move GameObject over time

我正在从 Swift SpriteKit 背景中学习 Unity,其中移动精灵的 x Position 就像运行如下操作一样简单:

let moveLeft = SKAction.moveToX(self.frame.width/5, duration: 1.0)
let delayAction = SKAction.waitForDuration(1.0)
let handSequence = SKAction.sequence([delayAction, moveLeft])
sprite.runAction(handSequence)

我想知道将精灵移动到特定 position 特定持续时间(例如一秒)的等效或类似方法,延迟不必在更新 function 中调用。

gjttt1 的答案很接近,但缺少重要功能,并且使用WaitForSeconds()移动GameObject是不可接受的。 您应该结合使用LerpCoroutineTime.deltaTime 您必须了解这些内容才能在 Unity 中通过 Script 制作动画。

public GameObject objectectA;
public GameObject objectectB;

void Start()
{
    StartCoroutine(moveToX(objectectA.transform, objectectB.transform.position, 1.0f));
}


bool isMoving = false;

IEnumerator moveToX(Transform fromPosition, Vector3 toPosition, float duration)
{
    //Make sure there is only one instance of this function running
    if (isMoving)
    {
        yield break; ///exit if this is still running
    }
    isMoving = true;

    float counter = 0;

    //Get the current position of the object to be moved
    Vector3 startPos = fromPosition.position;

    while (counter < duration)
    {
        counter += Time.deltaTime;
        fromPosition.position = Vector3.Lerp(startPos, toPosition, counter / duration);
        yield return null;
    }

    isMoving = false;
}

类似问题: SKAction.scaleXTo

git1 的答案很好,但如果您不想使用 couritines,还有另一种解决方案。

您可以使用InvokeRepeating重复触发一个函数。

float duration; //duration of movement
float durationTime; //this will be the value used to check if Time.time passed the current duration set

void Start()
{
    StartMovement();
}

void StartMovement()
{
    InvokeRepeating("MovementFunction", Time.deltaTime, Time.deltaTime); //Time.deltaTime is the time passed between two frames
    durationTime = Time.time + duration; //This is how long the invoke will repeat
}

void MovementFunction()
{
    if(durationTime > Time.time)
    {
        //Movement
    } 
    else 
    {
        CancelInvoke("MovementFunction"); //Stop the invoking of this function
        return;
    }
}

您可以使用协同程序来做到这一点。 为此,请创建一个返回类型IEnumerator的函数并包含一个循环来执行您想要的操作:

private IEnumerator foo()
{
    while(yourCondition) //for example check if two seconds has passed
    {
        //move the player on a per frame basis.
        yeild return null;
    }
}

然后你可以使用StartCoroutine(foo())调用它

这会在每一帧调用该函数,它会从上次停止的地方开始。 所以在这个例子中,它在一帧的yield return null处停止,然后在下一帧再次开始:因此它每帧重复while循环中的代码。

如果你想暂停一段时间,那么你可以使用yield return WaitForSeconds(3)等待 3 秒。 你也可以yield return其他协程! 这意味着当前例程将暂停并运行第二个协程,然后在第二个协程完成后再次启动。

我建议检查文档,因为它们在解释这一点方面做得比我在这里要好得多

暂无
暂无

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

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