这不是完整的脚本。我只显示我有问题的部分。
面临的问题:
我想制作整洁干净的脚本,因此我只在我的更新中调用函数。
我想在更新的第一行引入(StartGameFreezeMovement(功能。
我做不到。像其余函数一样,因为这个函数中有一个计时器。
想要的结果:
我的目的是找到一种方法,让更新中的第一个功能完全完成,然后加载或激活其余功能。
我怎样才能做到这一点?
public class PlayerController : MonoBehaviour {
private CharacterController controller;
public float speed;
private Vector3 moveVector;
private float verticalVelocity;
public float gravity;
private float animationDuration = 3.0f;
public Text text;
private float timer;
//-------------------------------------------------------------------------
void Start ()
{
text.text = "";
controller = GetComponent<CharacterController>();
}
//-------------------------------------------------------------------------
// Update is called once per frame
void Update ()
{
if(Time.time < animationDuration)
{
PlayerMovingForward();
return; //getout of if...
}
StartText();
PlayerMovingForward();
PlayerLeftnRight();
PlayerFalloffGravity();
}
//----------------------------------
void StartGameFreezeMovement()
{
if (Time.time < animationDuration)
{
PlayerMovingForward();
return; //getout of if...
}
}
我的目的是找到一种方法,将第一个函数更新到 完全完成,然后加载或激活其余部分。
您需要一个协程函数。Update
函数是一个void
函数。您必须创建一个协程函数并启动它一次,然后确保它不会退出,以便它将模仿每帧调用的Update
函数。这可以通过添加 while 循环并生成每一帧来完成。
最后,将StartGameFreezeMovement
函数从void
转换为协程函数,然后将if (Time.time < animationDuration)
更改为while (Time.time < animationDuration)
并在其内部使用yield return null;
让步,以便其他脚本有机会在等待StartGameFreezeMovement
函数完成时执行。
以下是您问题中代码的固定版本:
private void Start()
{
//Start once
StartCoroutine(YieldableUpdate());
}
IEnumerator YieldableUpdate()
{
//Call and wait for the StartGameFreezeMovement function to finish
yield return StartGameFreezeMovement();
//Run forever
while (true)
{
StartText();
PlayerMovingForward();
PlayerLeftnRight();
PlayerFalloffGravity();
//Wait a frame so that Unity doesn't freeze
yield return null;
}
}
IEnumerator StartGameFreezeMovement()
{
while (Time.time < animationDuration)
{
PlayerMovingForward();
//Wait a frame so that Unity doesn't freeze
yield return null;
}
}
如果您需要多次检查StartGameFreezeMovement()
移动yield return StartGameFreezeMovement();
while (true)
循环内,否则此检查将只发生一次。
您可以将 StartGameFreezeMovement 更改为布尔值。
bool StartGameFreezeMovement()
{
if (Time.time < animationDuration)
{
PlayerMovingForward();
return true; //getout of if...
}
return false;
}
然后更改更新功能。然后为了保持它干净,如果您没有通过布尔检查,请使用 return 提前退出更新函数。
void Update ()
{
if (!StartGameFreezeMovement())
{
return;
}
StartText();
PlayerMovingForward();
PlayerLeftnRight();
PlayerFalloffGravity();
}