Unity C#:如何实现仅在水果标签变为Sliced时生成新水果?
切割触发式水果生成逻辑修改方案
核心思路
放弃原有的固定间隔生成逻辑,改用事件驱动模式:只有当水果被切割(标签变为"Sliced")时,才触发下一个水果的生成。关键是通过自定义事件监听切割动作,替代固定等待延迟。
修改后的完整代码
1. Spawner 类代码调整
using UnityEngine; using System.Collections; public class Spawner : MonoBehaviour { public GameObject[] fruitPrefabs; public Transform spawnArea; public int numberOfFruits; public float minAngle, maxAngle; public float minForce, maxForce; public float maxLifetime; private int fruitsSpawned; // 定义切割事件委托 public delegate void FruitSlicedHandler(); // 切割事件:水果被切割时触发 public event FruitSlicedHandler OnFruitSliced; private void Start() { StartCoroutine(Spawn()); } private IEnumerator Spawn() { // 可选初始等待,可根据需求删除 yield return new WaitForSeconds(2f); // 生成第一个水果,无需等待切割 if (fruitsSpawned < numberOfFruits) { SpawnSingleFruit(); fruitsSpawned++; } while (fruitsSpawned < numberOfFruits) { // 等待切割事件触发 yield return new WaitUntil(() => OnFruitSliced != null); // 重置事件,避免同一切割信号重复触发生成 OnFruitSliced = null; // 生成下一个水果 SpawnSingleFruit(); fruitsSpawned++; } } // 提取单个水果生成逻辑,提升复用性 private void SpawnSingleFruit() { GameObject prefab = fruitPrefabs[Random.Range(0, fruitPrefabs.Length)]; Vector3 position = new Vector3( Random.Range(spawnArea.bounds.min.x, spawnArea.bounds.max.x), Random.Range(spawnArea.bounds.min.y, spawnArea.bounds.max.y), Random.Range(spawnArea.bounds.min.z, spawnArea.bounds.max.z) ); // 斜向生成角度设置 Quaternion rotation = Quaternion.Euler(0f, 0f, Random.Range(minAngle, maxAngle)); GameObject fruit = Instantiate(prefab, position, rotation); float force = Random.Range(minForce, maxForce); fruit.GetComponent<Rigidbody>().AddForce(fruit.transform.up * force, ForceMode.Impulse); } }
2. 水果切割脚本(示例)
在处理水果切割的脚本中(比如FruitSlice.cs),添加触发事件的逻辑:
using UnityEngine; public class FruitSlice : MonoBehaviour { private Spawner spawner; private void Awake() { // 获取场景中的Spawner实例,也可通过Inspector手动赋值 spawner = FindObjectOfType<Spawner>(); } // 你的切割触发逻辑(比如鼠标点击、碰撞检测触发) public void TriggerSlice() { // 修改标签为Sliced gameObject.tag = "Sliced"; // 触发Spawner的切割事件,通知生成下一个水果 spawner?.OnFruitSliced?.Invoke(); // 延迟销毁切割后的水果 Destroy(gameObject, spawner.maxLifetime); } // 示例:鼠标点击切割 private void OnMouseDown() { TriggerSlice(); } }
关键改动说明
- 事件驱动替代固定延迟:用
OnFruitSliced事件监听切割动作,只有当玩家切割水果时才会生成下一个,完全符合需求 - 代码拆分优化:将单个水果生成逻辑拆分为独立方法,提升代码可读性和维护性
- 初始生成逻辑:第一个水果直接生成,避免玩家进入游戏后无水果可切的空白期
- 事件重置机制:每次生成后重置事件,防止同一切割信号多次触发生成,避免逻辑混乱
内容的提问来源于stack exchange,提问作者Marcel Majhenic
相关产品推荐
相关产品推荐

