Garzec Geschrieben 6. September 2017 Melden Share Geschrieben 6. September 2017 Hallo, ich habe mal ein Pathfollowing gebastelt. Man kann durch Gameobjects kleine Wegpunkte erstellen und ein Objekt läuft diese dann ab. Beende ich das Spiel, fängt der Editor an, Nullpointer zu schmeißen. Ebenso meldet er zu Beginn immer zwei OutOfRangeExceptions. Hier mal das Script für den Container, der die Wegpunkte enthält und die Linien in der Szene zeichnet. public class PathContainer : MonoBehaviour { [SerializeField] private List<Transform> pathObjectList = new List<Transform>(); // alle Wegpunkte private Color rayColor = Color.red; // rote Linien private Transform[] pathObjects; private float wireSphereRadius = 1; // Radius der Kugeln, die den Wegpunkt darstellen private void Start() { pathObjects = GetComponentsInChildren<Transform>(); // alle Wegpunkte holen } public List<Transform> GetPathObjects() // Liste an andere Klassen weitergeben { return pathObjectList; } private void OnDrawGizmos() // Linien einzeichnen { Gizmos.color = rayColor; pathObjectList.Clear(); foreach (Transform pathObj in pathObjects) { if (pathObj != transform) pathObjectList.Add(pathObj); } for (int i = 0; i < pathObjectList.Count; i++) { Vector3 currentPosition = pathObjectList[i].position; if (i > 0) { Vector3 previousWaypointPosition = pathObjectList[i - 1].position; Gizmos.DrawLine(previousWaypointPosition, currentPosition); Gizmos.DrawWireSphere(currentPosition, wireSphereRadius); } } } } Das Objekt, dass diesem Pfad folgt, nutzt dieses Script public class PathFollowObject : MonoBehaviour { [SerializeField] private float followSpeed; // Bewegungsgeschwindigkeit [SerializeField] private float reachDistance; // Wie nah muss das Objekt am Wegpunkt sein, um ihn erreicht zu haben? [SerializeField] private float rotationSpeed; // Rotationsgeschwindigkeit [SerializeField] private GameObject pathObject; // Der Container für die Wegpunkte [SerializeField] private bool isLooping; // Nach einem Durchlauf aufhören? private PathContainer pathToFollow; // Referenz zum Script private int currentWaypoint = 0; // beginne beim ersten Wegpunkt private Vector3 lastPosition; // die Position des letzten Wegpunktes private Vector3 currentPosition; // die Position des aktuellen Wegpunktes private void Start() { pathToFollow = pathObject.GetComponent<PathContainer>(); lastPosition = transform.position; } private void Update() { Vector3 currentPosition = transform.position; Vector3 targetPosition = pathToFollow.GetPathObjects()[currentWaypoint].position; // der neue Wegpunkt Quaternion objectRotation = Quaternion.LookRotation(targetPosition - currentPosition); transform.rotation = Quaternion.Slerp(transform.rotation, objectRotation, rotationSpeed * Time.deltaTime); // bei der Bewegung rotieren float distance = Vector3.Distance(targetPosition, currentPosition); // die Distanz zum nächsten Wegpunkt transform.position = Vector3.MoveTowards(currentPosition, targetPosition, followSpeed * Time.deltaTime); // Zum Punkt bewegen if (distance <= reachDistance) // nächster Wegpunkt currentWaypoint++; if (currentWaypoint >= pathToFollow.GetPathObjects().Count) { if (!isLooping) // Script entfernen, sobald der letzte Wegpunkt erreicht wurde Destroy(this); currentWaypoint = 0; // Reset } } } Also die Bewegung und Technik funktioniert eindwandfrei, nur sobald ich das Spiel beende meckert der Editor mit den oben genannten Fehlern. Hat jemand eine Idee? Ich vermute, es liegt daran, dass der Container der Wegpunkte im Inspector eine leere Liste ist und nur zur Laufzeit sich über seine Kinder die Liste füllt. Hat jemand eine Idee, wie ich das fixen kann, sodass es auch außerhalb der Laufzeit funktioniert / keine Fehler schmeißt ? Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Zer0Cool Geschrieben 6. September 2017 Melden Share Geschrieben 6. September 2017 Ja, das Array PathObjects wird erst zu Laufzeit gesetzt und ist daher nicht initialisiert, was zu einer NPE führt, da OnDrawGizmos auch im Editor ausgeführt wird. Du könntest auch noch [ExecuteInEditMode] deiner Klasse hinzufügen, damit würde das Array auch im Editor schon gesetzt.https://docs.unity3d.com/ScriptReference/ExecuteInEditMode.html private void OnDrawGizmos() // Linien einzeichnen { if (pathObjects == null) return; // Hinzugefügt Gizmos.color = rayColor; pathObjectList.Clear(); foreach (Transform pathObj in pathObjects) { if (pathObj != transform) pathObjectList.Add(pathObj); } for (int i = 0; i < pathObjectList.Count; i++) { Vector3 currentPosition = pathObjectList[i].position; if (i > 0) { Vector3 previousWaypointPosition = pathObjectList[i - 1].position; Gizmos.DrawLine(previousWaypointPosition, currentPosition); Gizmos.DrawWireSphere(currentPosition, wireSphereRadius); } } } Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Mr 3d Geschrieben 6. September 2017 Melden Share Geschrieben 6. September 2017 --- Edit: zu spät ^^ statt ' if( pathObjects == null ) return; ' könntest du auch 'if( ! Application.isRunning ) return;' benutzen.. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Garzec Geschrieben 7. September 2017 Autor Melden Share Geschrieben 7. September 2017 oh darauf hät ich ja auch selbst kommen können ... dann wäre nur noch die Frage, welcher Code ist sinnvoller if( pathObjects == null ) return; oder if( ! Application.isRunning ) return; ? Zu Application.isRunning weiß ich leider nichts. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Recommended Posts
Archiviert
Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.