大家好,我正在开发一个餐厅策略游戏,顾客会进来购买东西。我创建了一个由Transform类型对象组成的数组,这些对象作为路径点,我希望顾客只朝场景中激活的路径点移动。我考虑使用for循环或while循环,每当遇到一个未激活的路径点时,就跳到下一个路径点并检查它是否激活。我不确定这是否是正确的方法,因为我似乎无法让它工作。无论如何,我真的很需要帮助。谢谢!
var waypoints : Transform[];var waypoint : Transform;var currentWaypoint : int;var agent : NavMeshAgent;var script1 : SlideOutMenu;function Awake(){agent = gameObject.GetComponent.<NavMeshAgent>();agent.speed = Random.Range(2.5, 5);script1 = gameObject.Find("GUIElements").GetComponent(SlideOutMenu);}function Update () {waypoint = waypoints[currentWaypoint];agent.SetDestination(waypoint.position);}function OnTriggerExit(other : Collider){if (other.name == "0 Start"){ currentWaypoint = Random.Range(1, 2); }}function OnTriggerEnter (other : Collider) {EatMeal();if (other.name == "0 Start"){currentWaypoint++;} if (other.name == "1"){ script1.globalMoney += 50; WaitForSoda(); } if (other.name == "2"){ script1.globalMoney += 100; WaitForFood(); } if (other.name == "4 End"){ Destroy(gameObject); }}function WaitForSoda(){yield WaitForSeconds(2);currentWaypoint++;}function WaitForFood(){yield WaitForSeconds(5);currentWaypoint = Random.Range(5, 12);}function EatMeal(){if (currentWaypoint >= 4 && currentWaypoint <= 12){yield WaitForSeconds(Random.Range(5, 12));currentWaypoint = 4;}}
回答:
在游戏编程中,如果你发现自己每次执行某个操作时,都会遍历所有对象并检查它们是否激活,这通常是一个坏主意。我曾经在一个100000×100000的网格上犯过这个错误。解决这类问题的最佳方法通常是反转问题。不要询问每个路径点是否激活,而是让每个路径点询问自己是属于激活还是未激活集合。我建议至少有两个列表:activeWaypoints
和inactiveWaypoints
。如果需要(有时确实需要),可以使用masterWaypoints
作为一个通用集合。
现在很简单:每个路径点都知道自己是激活还是未激活,当它激活时,它会从未激活列表中移除自己并添加到激活列表中,反之亦然。当它被创建时,你必须选择它默认是激活还是未激活(或者提供一个选项来创建具有任一默认值的路径点),但这充其量只是一个小的设计问题。当它被销毁时,只需从当前所在的列表中移除它,如果存在的话,还要从masterWaypoints
中移除。
这样做的好处是,你只需要在状态发生变化时更新事物,而不是每帧都检查它们(更糟的是:每帧为每个NPC代理检查它们)。
从这里开始,你只需为每个顾客检查activeWaypoints
。如果需要为每个顾客进行进一步的过滤,这会变得稍微复杂一些。在这种情况下,可以接受遍历所有activeWaypoints
并忽略所有不符合条件的路径点。不过,根据需要进行的过滤量,我可能会考虑编写某种WaypointManager
,它具有基于激活/未激活/红色/蓝色/由果酱制成/引起疯狂等的过滤逻辑,通过getWaypointsMeetingCriteria(过滤器列表)
访问。这可以根据你为每个标签决定的内容,使用地图、列表和通过迭代进行过滤的混合方法。
这里有一个小问题,即路径点可能是按顺序排列的,这意味着当路径点从未激活变为激活时,需要保持它们的顺序,但有很多方法可以快速插入和/或构建一个排序列表。