如何将InvokeRepeating生成的墙体预制体加入List并实现碰撞停止与统一移动
实现无限生成移动墙体并处理碰撞停止逻辑
我来帮你把需求落地,咱们针对三个核心要求一步步修改代码:
核心需求拆解与实现步骤
1. 存储生成的预制体到List里
首先需要添加一个List<GameObject>来保存所有生成的墙体,这样后续才能统一控制它们的移动或者停止。同时加一个布尔变量isRunning作为开关,控制生成和移动的启停。
2. 碰撞玩家后停止生成与移动
当墙体和玩家碰撞时,我们需要:
- 取消
InvokeRepeating的调用,停止生成新墙体 - 把
isRunning设为false,让所有已生成的墙体停止移动 - 这里要注意给玩家对象设置正确的标签(比如"Player"),方便碰撞检测时识别
3. 统一应用移动逻辑
把移动逻辑抽出来,在Update里遍历List中的所有墙体,只有当isRunning为true时才执行移动,这样能统一控制所有墙体的运动状态。
修改后的完整代码
using UnityEngine; using System.Collections.Generic; public class Wall : MonoBehaviour { public Vector3[] positions = new Vector3[4]; public GameObject barrier; public float speed = 1f; // 存储所有生成的墙体 private List<GameObject> spawnedBarriers = new List<GameObject>(); // 控制生成和移动的开关 private bool isRunning = true; void Start() { // 启动重复生成 InvokeRepeating("SpawnBarrier", 1f, speed); } void Update() { // 只有开关开启时才移动所有墙体 if (isRunning) { MoveAllBarriers(); } } void SpawnBarrier() { // 如果开关已经关闭,直接返回,不再生成 if (!isRunning) return; for (int i = 0; i <= 3; i++) { GameObject newBarrier = Instantiate(barrier, positions[i], Quaternion.identity); // 将新生成的墙体加入List spawnedBarriers.Add(newBarrier); } } void MoveAllBarriers() { // 遍历所有墙体,执行移动逻辑(这里假设是向下移动,你可以根据需求修改方向) foreach (var barrier in spawnedBarriers) { if (barrier != null) { barrier.transform.Translate(Vector3.down * speed * Time.deltaTime); // 你可以替换成自己需要的移动方向或逻辑 } } } void OnTriggerEnter(Collider other) { // 检测碰撞对象是否是玩家(记得给玩家设置"Player"标签) if (other.gameObject.CompareTag("Player")) { // 停止生成新墙体 CancelInvoke("SpawnBarrier"); // 关闭移动开关 isRunning = false; Debug.Log("墙体与玩家碰撞,已停止生成和移动"); } } }
关键注意点
- 确保你的墙体预制体带有Collider组件,并且勾选了
Is Trigger(因为用的是OnTriggerEnter),同时玩家对象也需要带有Collider和Rigidbody组件(才能触发碰撞检测) - 移动逻辑里的
Vector3.down可以根据你的需求改成任意方向(比如Vector3.forward),速度参数也可以调整 - 如果墙体可能被销毁,记得在
MoveAllBarriers里做空值判断,避免空引用错误
内容的提问来源于stack exchange,提问作者Don_Huan
相关产品推荐
相关产品推荐

