这可以通过多种方式完成。在向您展示具体内容之前,这里有一个基本结构,适用于所有示例代码,我将使用它:
public class ColorChanger : MonoBehaviour {
//Avoid Find and GetComponent methods in performance-critical contexts like Update and FixedUpdate
//Store the value once in the beginning. This is called 'caching'
public SpriteRenderer _renderer;
//Don't hard-code stuff like this
public Color[] _colors;
public float _colorChangeInterval = 0.5f;
//Convenience property to access _renderer.color
public Color Color {
get => _renderer.color;
set => _renderer.color = value;
}
private void Start() {
//Attempts to find the SpriteRenderer in the object if it wasn't set in the inspector
if (!_renderer)
_renderer = GetComponent<SpriteRenderer>();
}
//This piece of code does a specific thing, so it's best to put it in a method
public void ChangeColor() {
if (_colors.Length < 1)
Debug.LogError($"You forgot to set {nameof(_colors)} in the Inspector. Shame! Shame!");
Color = _colors[Random.Range(0, _colors.Length - 1)];
}
}
在我看来,以下是一些主要的,按照它们的直观程度排列:
定时器模式:
两种口味。
1) 可以是经过时间的累加器(如下面的代码),或者相反,从区间递减到零:
private float _elapsed;
private void Update() {
_elapsed += Time.deltaTime;
if (_elapsed < _colorChangeInterval)
return;
ChangeColor();
_elapsed %= _colorChangeInterval;
}
或者 2) 可以是从上一个或直到下一个(如下)时间戳的时间戳检查触发器:
//Replaces _elapsed
private float _timestamp;
private void Start() {
//...
_timestamp = Time.time; //Initial timestamp
}
private void Update() {
if (Time.time < _timestamp + _colorChangeInterval)
return;
ChangeColor();
_timestamp = Time.time;
}
协程 & WaitForSeconds:
当您需要统一延迟或排序代码时,这是推荐的过程。
注意,Unity 还提供了其他类型的等待方法,如WaitWhile、WaitUntil 等...
//Since unlike code in Update, coroutines need to be started and stopped, we start it when the script is enabled
private void OnEnable() {
StartCoroutine(ChangeColorContinuously());
}
//This is automatically stopped by unity when the script is disabled
private IEnumerator ChangeColorContinuously() {
while (true) {
yield return new WaitForSeconds(_colorChangeInterval);
ChangeColor();
}
}
不要做异步等待!
嗯,它可以完成,但它有很多陷阱,非常不推荐给初学者。
无论如何,它并不是要取代协程。
不要执行 InvokeRepeating!
这是一种依赖于魔术字符串和反射的方法。对于示例代码的快速和简单的设置很有用,但如果可能的话(并且有可能,这要归功于上面的方法)应该像生产代码中的瘟疫一样避免。