Rokks Geschrieben 26. Mai 2015 Melden Share Geschrieben 26. Mai 2015 Moinsen, ich habe ein Testfeld mit 3 x 3 einfachen Cubes. Jedes Cube hat ein separates Triggerfeld an den Seiten "A" bis "D". Ausgenommen der Ober- und Unterseite. Berührungen werden in den Variablen SideA bis SideD mit true/false gesetzt. Um zu überprüfen, an welchen Seiten eine Berührung vorliegt, löst "OnTriggerStay" aus. Angedacht ist, dass ich aus dem Testfeld einfache Cubes entferne und die dadurch nun unberührten Seiten auf "false" gesetzt werden. Lohnt es, an dieser Stelle zusätzlich "OnTriggerExit" anzuführen, oder reicht "OnTriggerStay" vollkommen aus? Es sollen bisweilen keinerlei Cubes neu gesetzt werden können, nur entfernen. public string wallSide; //Welche Triggerseite meldet Kontakt void OnTriggerStay(Collider col) { //Wenn Collider-Layer == 10 (Trigger) if (col.gameObject.layer == 10) { if (wallSide == "A") { //Seite-A -> Seite-C if (!transform.GetComponentInParent<WallState>().WallSiteA && col.gameObject.tag == "WallChild3") { transform.GetComponentInParent<WallState>().WallSiteA = true; } else if (transform.GetComponentInParent<WallState>().WallSiteA && col.gameObject.tag != "WallChild3") { transform.GetComponentInParent<WallState>().WallSiteA = false; } } if (wallSide == "B") { //Seite-B -> Seite-D if (!transform.GetComponentInParent<WallState>().WallSiteB && col.gameObject.tag == "WallChild4") { transform.GetComponentInParent<WallState>().WallSiteB = true; } else if (transform.GetComponentInParent<WallState>().WallSiteB && col.gameObject.tag != "WallChild4") { transform.GetComponentInParent<WallState>().WallSiteB = false; } } if (wallSide == "C") { //Seite-C -> Seite-A if (!transform.GetComponentInParent<WallState>().WallSiteC && col.gameObject.tag == "WallChild1") { transform.GetComponentInParent<WallState>().WallSiteC = true; } else if (transform.GetComponentInParent<WallState>().WallSiteC && col.gameObject.tag != "WallChild1") { transform.GetComponentInParent<WallState>().WallSiteC = false; } } if (wallSide == "D") { //Seite-D -> Seite-B if (!transform.GetComponentInParent<WallState>().WallSiteD && col.gameObject.tag == "WallChild2") { transform.GetComponentInParent<WallState>().WallSiteD = true; } else if (transform.GetComponentInParent<WallState>().WallSiteD && col.gameObject.tag != "WallChild2") { transform.GetComponentInParent<WallState>().WallSiteD = false; } } } } } Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Hrungdak Geschrieben 27. Mai 2015 Melden Share Geschrieben 27. Mai 2015 Ich hab mal versucht, das aufzudröseln, komme aber mit deiner Logik nicht klar. Ich denke, dass jeder deiner 3x3 Cubes insgesamt vier Collider als Trigger hat, auf jeder Seite einen? Und du willst anhand der OnTriggerStay rausfinden, wo ein Nachbarcube vorhanden ist und wo nicht? Oder sind das keine Collider, sondern andere GameObjekte? Wenn es GameObjekte sind, dann hat wohl jedes davon dieses Script und die Variable WallSide wird schon im Inspector gesetzt? Sonst ergibt das für mich keinen Sinn. Wenn ich das richtig interpretiere, wirst du OnTriggerExit brauchen. Wenn du einen Cube entfernst, wird einfach OnTriggerStay nicht mehr aufgerufen und du kannst nicht darauf reagieren. In deinem Code sehe ich aber noch ein paar Probleme: OnTriggerStay wird Du rufst in jedem Frame für jeden Trigger, der in einem anderen Trigger steckt, mindestens drei mal GetComponentInParent auf. Das ist ziemlicher Overkill und drückt die Performance gewaltig. Was mich auch durcheinander bringt, du bezeichnest die Variable als WallSiteA, den Collider allerdings mit WallChild3. Warum nicht WallChildC? Wenn ich alles richtig interpretiert habe, sollte das so auch gehen: private WallState m_WallState; void Start() { m_WallState = (WallState)GetComponentInParent<WallState>(); } void OnTriggerStay(Collider col) { if (wallSide == "A") { if (col.gameObject.tag == "WallChild3") m_WallState.WallSiteA = true; } if (wallSide == "B") { if (col.gameObject.tag == "WallChild4") m_WallState.WallSiteB = true; } } void OnTriggerExit() { if (wallSide == "A") { m_WallState.WallSiteA = false; if (wallSide == "B") { m_WallState.WallSiteB = false; } Ist natürlich nicht getestet und ich kann mich bei meinen Annahmen irren. Für eine bessere Lösung bräuchte ich mehr Code. Aber so würde ich vorgehen. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Rokks Geschrieben 27. Mai 2015 Autor Melden Share Geschrieben 27. Mai 2015 Okay, das mit dem vorherigen setzen der Variable im Start() leuchtet ein. Sagt OnTriggerStay aber nicht auch aus, dass ein Object im Trigger solange erkannt bleibt,wie er sich in diesem befindet? Wäre OnTriggerExit somit nicht überflüssig? Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 27. Mai 2015 Melden Share Geschrieben 27. Mai 2015 Ich hab das Thema jetzt nur überflogen, aber: Ohne OnTriggerExit setzt ja am Ende keiner mehr den Wert auf false. Was dagegen etwas überflüssi aussieht, ist OnTriggerStay - OnTriggerEnter würde vermutlich dasselbe Ergebnis bringen, und dafür nicht in jedem FixedUpdate passieren. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Rokks Geschrieben 27. Mai 2015 Autor Melden Share Geschrieben 27. Mai 2015 Bei näherer Überlegen ist da was wahres dran Dank Hrungdak's Anregung, Get-Variablen bereits im Start() zu setzen, spare ich mir nicht nur viel getickere sondern auch einiges an Performance. Hatte mich bereits gewundert, wieso ab und an meine Gizmos und Drawlines verrückt gespielt haben Ich danke. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 27. Mai 2015 Melden Share Geschrieben 27. Mai 2015 Tipp: Aus guten Gründen solltest du das in Awake machen, statt in Start. Im Moment ist es noch egal, aber später wird's nützlich, das so zu machen. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Rokks Geschrieben 28. Mai 2015 Autor Melden Share Geschrieben 28. Mai 2015 Awake() wird noch vor Start() ausgeführt,soweit habe ich das verstanden. Ist der Unterschied der Variablenzuweisung so drastisch spürbar/messbar? Bei vielen Objekten mit vielen Zugehörigkeiten und Anforderungen könnt ich mir das zumindest schon vorstellen, dass hier mal eine ms dort mal eine ms am ende zu Sekunden führen können. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Mark Geschrieben 28. Mai 2015 Melden Share Geschrieben 28. Mai 2015 Awake wird ausgeführt nachdem das Objekt Instanziiert wurde. Start wird ausgeführt wenn das Objekt Enabled wird/ist und wenn ich mich nicht irre sogar erst dann wenn der Part von Unity der grade den Code ausführt der das Objekt instanziierte fertig ist. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Hrungdak Geschrieben 28. Mai 2015 Melden Share Geschrieben 28. Mai 2015 Ob Awake() oder Start() hat erst mal nichts mit Performance zu tun. Nur mit dem Ausführungszeitpunkt. Das einzige, was die Performance beeinflusst, ist, wenn Objekte zwar instanziiert, aber nicht aktiviert werden. Start() wird erst bei der Aktivierung ausgeführt. Guter Link, was wann wo ausgeführt wird und die Zusammenhänge: http://docs.unity3d.com/Manual/ExecutionOrder.html Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 28. Mai 2015 Melden Share Geschrieben 28. Mai 2015 Der Grund, warum du Awake für Variablenzuweisungen benutzen willst, ist schlicht, dass du in Start schon Dinge passieren lassen willst. Wenn diese Dinge nun von anderen Objekten abhängen und diese Objekte dafür bestimmte Werte schon gesetzt haben müssen, dann sollten diese in Awake schon gesetzt worden sein, damit sie in Start auf jeden Fall schon da sind. Z.B.: public class Fountain : MonoBehaviour { private ParticleSystem waterSplash; void Awake() { waterSplash = GetComponent<ParticleSystem>(); } public void TurnOn() { waterSplash.Play(); } } public class FountainManager : MonoBehaviour { [serializeField] private Fountain[] fountains; public Start() { //Schalte zufällig einen der Brunnen an fountains[Random.Range(0, fountains.Length)].TurnOn(); } } Wäre der Code in Fountain.Awake jetzt stattdessen in Start, könnte es sein, dass Start von FountainManager zuerst ausgeführt würde. Ergebnis wäre dann eine NullReferenceException anstatt eines angeschalteten Brunnens. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Rokks Geschrieben 28. Mai 2015 Autor Melden Share Geschrieben 28. Mai 2015 Super, lieben Dank. Nu hab ich auch den Zusammenhang verstanden 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.