问题描述
任务:要列出从场景中最近的航路点到最远的航点 但每次将相同的航路点添加到newRoute时都是脚本。
敌人与场景中的航路点:
我正在尝试避免这种情况[!newRoute.Contains(waypoints [c]],但不起作用
List<Transform> GenerateNewRouteT()
{
List<Transform> newRoute = new List<Transform>();
Transform currentNearestWaypoint = waypoints[waypoints.Count - 1];
for (byte v = 0; v < waypoints.Count; v++)
{
for (byte c = 0; c < waypoints.Count; c++)
{
if (Vector3.distance(transform.position,waypoints[c].position) < Vector3.distance(transform.position,currentNearestWaypoint.position) && !newRoute.Contains(waypoints[c]))
{
currentNearestWaypoint = waypoints[c];
}
}
newRoute.Add(currentNearestWaypoint);
Debug.Log($"Added waypoint with coordinates: {currentNearestWaypoint.position.ToString()}");
}
return newRoute;
}
我无法使用[Serializefield]导致通过预制创建暴民
解决方法
我认为您需要将逻辑修改为:
- 找到离玩家最近的航路点。
- 找到与上一个航点(重复)最近的航点。
List<Transform> waypoints = new List<Transform>();
List<Transform> route = new List<Transform>();
Transform currentWaypoint = null;
// Start from the player.
currentWaypoint = FindClosestWaypoint(transform);
// Fill the route with waypoints.
for (int i = 0; i < waypoints.Count; i++)
{
currentWaypoint = FindClosestWaypoint(currentWaypoint);
if(currentWaypoint != null) route.Add(currentWaypoint);
}
Transform FindClosestWaypoint(Transform from)
{
// Default to the first element.
Transform closestWaypoint = waypoints[0];
var smallestDistance = Vector3.Distance(from.position,closestWaypoint.position);
foreach (var waypoint in waypoints)
{
// Skip when element is already in the route.
if (route.Contains(waypoint)) continue;
// Update closest waypoint/distance.
var distance = Vector3.Distance(from.position,waypoint.position);
if (distance < smallestDistance)
{
closestWaypoint = waypoint;
smallestDistance = distance;
}
}
return closestWaypoint;
}
,
也许错误在于另一种方法?
public class MobMovement : MonoBehaviour
{
[SerializeField] public float enemySpeed;
[HideInInspector] public byte _currentWaypointIndex = 0;
[SerializeField] public GameObject fisrtSpawnpoint;
private List<Transform> waypoints = new List<Transform>();
private bool generateNewRoute = false;
void Start()
{
InitializeWaypoints();
CheckRoute();
if (generateNewRoute)
{
waypoints = GenerateNewRoute();
Debug.LogWarning("Generated new route");
for (byte c = 0; c < waypoints.Count; c++)
{
Debug.Log(waypoints[c].position.ToString());
}
// for (byte c = 0; c < waypoints.Count; c++)
// {
// Debug.Log($"{c}: X:{waypoints[c].position.x.ToString()} Z:{waypoints[c].position.z.ToString()}");
// }a
}
}
void InitializeWaypoints()
{
foreach (GameObject respawn in GameObject.FindGameObjectsWithTag("Waypoint"))
{
waypoints.Add(respawn.transform);
//Debug.LogWarning("Found and added this point to waypoints list");
}
if (waypoints != null && waypoints.Count != 0)
{
//Debug.Log("Added waypoints in list for new mob");
//Debug.LogWarning($"{waypoints.Count.ToString()}");
}
else
{
Debug.LogError("Check code waypoints list is empty right now...");
}
}
void CheckRoute()
{
GameObject spawnpoint = GameObject.Find("Spawnpoint1");
if (Vector3.Distance(transform.position,spawnpoint.transform.position) < 3)
{
//Debug.Log("Following route from first spawnpoint");
RouteFrom1Spawnpoint firstRoute = new RouteFrom1Spawnpoint();
firstRoute.FollowRoute(ref waypoints,ref generateNewRoute);
}
else
{
//Debug.Log("Following route from 2 spawnpoint");
RouteFrom2Spawnpoint secondRoute = new RouteFrom2Spawnpoint();
secondRoute.FollowRoute(ref waypoints,ref generateNewRoute);
}
}
List<Transform> GenerateNewRoute()
{
List<Transform> route = new List<Transform>();
Transform currentWaypoint = null;
// Start from the player.
currentWaypoint = FindClosestWaypoint(transform);
// Fill the route with waypoints.
for (byte i = 0; i < waypoints.Count; i++)
{
currentWaypoint = FindClosestWaypoint(currentWaypoint);
if (currentWaypoint != null) route.Add(currentWaypoint);
}
Transform FindClosestWaypoint(Transform from)
{
// Default to the first element.
Transform closestWaypoint = waypoints[0];
var smallestDistance = Vector3.Distance(from.position,closestWaypoint.position);
foreach (var waypoint in waypoints)
{
// Skip when element is already in the route.
if (route.Contains(waypoint)) continue;
// Update closest waypoint/distance.
var distance = Vector3.Distance(from.position,waypoint.position);
if (distance < smallestDistance)
{
closestWaypoint = waypoint;
smallestDistance = distance;
}
}
return closestWaypoint;
}
return route;
}
List<Transform> GenerateNewRouteT()
{
List<Transform> newRoute = new List<Transform>();
Transform currentNearestWaypoint = waypoints[waypoints.Count - 1];
for (byte v = 0; v < waypoints.Count; v++)
{
for (byte c = 0; c < waypoints.Count; c++)
{
if (Vector3.Distance(transform.position,waypoints[c].position) < Vector3.Distance(transform.position,currentNearestWaypoint.position) && !newRoute.Contains(waypoints[c]))
{
currentNearestWaypoint = waypoints[c];
}
}
newRoute.Add(currentNearestWaypoint);
Debug.Log($"Added waypoint with coordinates: {currentNearestWaypoint.position.ToString()}");
}
return newRoute;
}
void Update()
{
Movement();
}
private void Movement()
{
//check spwawnpoint
if (_currentWaypointIndex < waypoints.Count)
{
transform.position = Vector3.MoveTowards(transform.position,waypoints[_currentWaypointIndex].position,Time.deltaTime * enemySpeed);
transform.LookAt(waypoints[_currentWaypointIndex].position);
if (Vector3.Distance(transform.position,waypoints[_currentWaypointIndex].position) < 0.5f)
{
_currentWaypointIndex++;
}
}
}
abstract class RouteFollower
{
public abstract void FollowRoute(ref List<Transform> listOfWaypoints,ref bool generateNewRoute);
}
class RouteFrom1Spawnpoint : RouteFollower
{
public override void FollowRoute(ref List<Transform> listOfWaypoints,ref bool generateNewRoute)
{
List<Transform> newRoute = new List<Transform>();
newRoute.Add(listOfWaypoints[8]);
listOfWaypoints = newRoute;
generateNewRoute = false;
}
}
class RouteFrom2Spawnpoint : RouteFollower
{
public override void FollowRoute(ref List<Transform> listOfWaypoints,ref bool generateNewRoute)
{
generateNewRoute = true;
}
}
}