在Unity中,虽然不直接使用迭代器模式的原始定义(即设计模式中的迭代器模式),但我们可以借助C#语言中的迭代器功能来实现类似的效果。迭代器模式允许顺序访问聚合对象的元素,而无需暴露其内部表示。Unity引擎中广泛应用了C#的IEnumerator和yield关键字来创建协程,这些协程可以视为一种特殊的迭代器。
以下是五个关于Unity中利用IEnumerator实现迭代器模式概念的代码实例:
using UnityEngine;
using System.Collections;
public class Example1 : MonoBehaviour
{
private int[] numbers = { 1, 2, 3, 4, 5 };
IEnumerator Start()
{
foreach (int number in numbers)
{
Debug.Log(number);
yield return new WaitForSeconds(1f); // 每秒输出一个数字
}
}
}
这个例子展示了如何通过foreach循环遍历数组,并在Unity中以协程的形式逐个延迟输出数组元素。
using System.Collections.Generic;
public class CustomEnumerable : IEnumerable<int>
{
private List<int> data = new List<int>{ 6, 7, 8, 9, 10 };
public IEnumerator<int> GetEnumerator()
{
foreach (var item in data)
{
yield return item;
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public class Example2 : MonoBehaviour
{
void Start()
{
CustomEnumerable customList = new CustomEnumerable();
foreach (int number in customList)
{
Debug.Log(number);
}
}
}
这里定义了一个实现了IEnumerable接口的自定义集合类,它通过GetEnumerator方法返回一个IEnumerator,从而可以被foreach语句遍历。
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
public class AssetLoader : MonoBehaviour
{
public string[] assetKeys;
IEnumerator LoadAssets()
{
foreach (string key in assetKeys)
{
AsyncOperationHandle<GameObject> handle = Addressables.LoadAssetAsync<GameObject>(key);
yield return handle;
if (handle.Status == AsyncOperationStatus.Succeeded)
{
GameObject loadedObject = handle.Result;
Instantiate(loadedObject);
}
else
{
Debug.LogError($"Failed to load asset: {key}");
}
}
}
void Start()
{
StartCoroutine(LoadAssets());
}
}
在这个示例中,我们利用Addressables异步加载资源,每次加载一个资源后yield返回,直到所有资源加载完毕,这体现了迭代器在处理异步流程时的灵活性。
using UnityEngine;
using System.Collections;
public class LevelManager : MonoBehaviour
{
public Level[] levels;
IEnumerator LoadLevels()
{
for (int i = 0; i < levels.Length; i++)
{
Level level = levels[i];
LoadLevel(level);
yield return new WaitForSeconds(level.LoadDelay);
// 加载完成后的逻辑,比如切换场景等
}
}
void LoadLevel(Level level)
{
// 加载关卡逻辑...
}
void Start()
{
StartCoroutine(LoadLevels());
}
}
[System.Serializable]
public class Level
{
public string SceneName;
public float LoadDelay;
}
此例中,我们有一个关卡列表,通过协程逐个加载每个关卡并等待指定时间,这是对迭代器用于序列化操作的一个应用。
using UnityEngine;
using System.Collections;
public class EnemySpawner : MonoBehaviour
{
[SerializeField] private GameObject enemyPrefab;
[SerializeField] private float spawnInterval;
private IEnumerator SpawnCoroutine()
{
while (true)
{
Vector3 spawnPosition = GetRandomSpawnPosition();
Instantiate(enemyPrefab, spawnPosition, Quaternion.identity);
yield return new WaitForSeconds(spawnInterval);
}
}
void Start()
{
StartCoroutine(SpawnCoroutine());
}
private Vector3 GetRandomSpawnPosition()
{
// 实现获取随机生成位置的逻辑...
}
}
这个例子中,我们创建了一个无限循环生成敌人的协程,每一次yield都代表一次新的敌人生成间隔,表现出了迭代器在持续性行为控制上的运用。
请注意,在Unity中,“迭代器”一词更多地与IEnumerator和yield关联,它们共同构成了“协程”的基础,而并非严格遵循GOF设计模式中的迭代器模式定义。
python推荐学习汇总连接:
50个开发必备的Python经典脚本(1-10)
50个开发必备的Python经典脚本(11-20)
50个开发必备的Python经典脚本(21-30)
50个开发必备的Python经典脚本(31-40)
50个开发必备的Python经典脚本(41-50)
————————————————
最后我们放松一下眼睛