如何修改DrawPathToCollectable函数使其指向场景中指定Collectable对象
修改DrawPathToCollectable函数以支持场景中已存在的Collectable对象
要实现针对场景中已存在的Collectable对象绘制路径,你需要对原代码做以下几处关键修改:
- 移除重复字段:原代码重复定义了
private Collectable ActiveInstance;,删掉其中一个 - 让协程接收目标参数:把硬依赖全局变量的逻辑改成通过参数传入目标Collectable
- 新增公共启动方法:提供外部调用入口,传入场景中已有的Collectable对象
- 协程生命周期管理:避免同时运行多个路径绘制协程,启动新协程前先停止旧的
修改后的完整代码
using UnityEngine; using UnityEngine.AI; using System.Collections; public class PathDrawer : MonoBehaviour { [SerializeField] private Collectable Prefab; [SerializeField] private Transform Player; [SerializeField] private LineRenderer Path; [SerializeField] private float PathHeightOffset = 1.25f; [SerializeField] private float SpawnHeightOffset = 1.5f; [SerializeField] private float PathUpdateSpeed = 0.25f; private Collectable ActiveTarget; private NavMeshTriangulation Triangulation; private Coroutine DrawPathCoroutine; // 公共方法:传入场景中已有的Collectable对象,开始绘制路径 public void StartDrawingPathToExistingCollectable(Collectable targetCollectable) { // 先停止当前正在运行的路径绘制协程 if (DrawPathCoroutine != null) { StopCoroutine(DrawPathCoroutine); } ActiveTarget = targetCollectable; // 启动新的路径绘制协程 DrawPathCoroutine = StartCoroutine(DrawPathToCollectable(ActiveTarget)); } // 可选:主动停止路径绘制 public void StopDrawingPath() { if (DrawPathCoroutine != null) { StopCoroutine(DrawPathCoroutine); DrawPathCoroutine = null; } ActiveTarget = null; Path.positionCount = 0; // 清空线渲染器 } private IEnumerator DrawPathToCollectable(Collectable target) { WaitForSeconds wait = new WaitForSeconds(PathUpdateSpeed); NavMeshPath path = new NavMeshPath(); while (target != null && target.gameObject.activeInHierarchy) { // 检查目标是否还存在(防止被销毁) if (NavMesh.CalculatePath(Player.position, target.transform.position, NavMesh.AllAreas, path)) { Path.positionCount = path.corners.Length; for (int i = 0; i < path.corners.Length; i++) { Path.SetPosition(i, path.corners[i] + Vector3.up * PathHeightOffset); } } else { Debug.LogError($"无法在NavMesh上计算从{Player.position}到{target.transform.position}的路径!"); Path.positionCount = 0; // 计算失败时清空路径 } yield return wait; } // 目标消失或被销毁后清空路径 Path.positionCount = 0; DrawPathCoroutine = null; } }
关键修改说明
- 参数化协程:
DrawPathToCollectable现在接收Collectable参数作为目标,不再依赖全局变量,可灵活传入场景中任意已存在的Collectable对象 - 公共启动入口:
StartDrawingPathToExistingCollectable方法让外部代码可以直接传入目标对象启动路径绘制,比如检测到场景中的Collectable时调用该方法 - 协程管理:启动新协程前先停止旧的,避免多个协程同时更新LineRenderer;目标被销毁或失活时自动停止绘制并清空路径
- 健壮性提升:循环条件加入
target.gameObject.activeInHierarchy,防止目标对象被销毁后出现空引用错误
使用示例
在其他脚本中可这样调用:
// 获取场景中已有的Collectable对象 Collectable existingCollectable = GameObject.FindObjectOfType<Collectable>(); PathDrawer pathDrawer = GetComponent<PathDrawer>(); pathDrawer.StartDrawingPathToExistingCollectable(existingCollectable);
内容的提问来源于stack exchange,提问作者Maximilian
相关产品推荐
相关产品推荐

