Jump to content
Unity Insider Forum
Jomnitech

on trigger stay pendant (gelöst)

Recommended Posts

Gibt es ein Gegenstück zu "on trigger stay"? .
Ich habe ein kleines Script welches verhindert das man die Waffe benutzen kann wenn diese in eine Wand clipt. Dazu verwende ich die Abrage on trigger stay und on trigger exit. Nur wird aber teilweise der on trigger exit nicht sauber getriggert und die Waffe bleibt blockiert. Gibt es so etwas wie on trigger not stay?

Share this post


Link to post
Share on other sites

Gibt nicht.

Du kannst aber ein bool in FixedUpdate auf true setzen und OnTriggerStay auf false. Die Variable musst du in Update nur noch abfragen. (oder auch in FixedUpdate für den vorherigen Frame)

Share this post


Link to post
Share on other sites

Versuchs mal hiermit.

using UnityEngine;

public class TriggerChecker : MonoBehaviour {

    private bool isInTrigger = false;

    private void OnTriggerEnter(Collider other)
    {
        isInTrigger = true;
    }

    private void OnTriggerExit(Collider other)
    {
        isInTrigger = false;
    }

    private void Update()
    {
        if (!isInTrigger)
        {
            // do something
        }
    }
}

Ich hab den Code zwar nicht getestet aber er sollte eigentlich funktionieren.

Im if-Block innerhalb der Update Methode kannst du jetzt deinen Code ausführen.

Share this post


Link to post
Share on other sites

unsigned hat schon eine gute Lösung parat. Man sollte aber evtl. noch eine Unterscheidung für den Trigger rein tun. Es wird ja bestimmt nicht nur gegen die Wand getriggert.
Deswegen den Wänden noch den Tag "Wand" geben und in den Trigger so abfragen:
 

void OnTriggerEnter(Collider other){
	if(other.CompareTag("Wand"){
		inWand=true;
	}
}
void OnTriggerExit(Collider other){
	if(other.CompareTag("Wand"){
		inWand=false;
	}
}

Kurze Erklärung zum Grundproblem:
Getriggert wird immer, da wird nichts verschluckt. Aber der Moment ist halt wirklich kurz. Und wenn der FixedTimestep schneller ist, als deine Framerate ( und das sollte in der Regel immer so sein) dann kann es zwischen 2 Frames zu mehreren Physik Updates kommen und deswegen auch mehrmals die OnTrigger Abfrage kommen.  Und wenn man diesen Moment nicht in eine Variable zwischenspeichert oder sie innerhalb jedes Triggerevents vorher auf false setzt, passiert folgendes:

Letztes Update: Die Waffe ist nicht im Trigger.
Physics Update: Die Waffe ist in den Trigger eingetaucht und wird auch mit OnTriggerEnter registriert.
Jetzt kommt ein weiteres Physical Update, weil die Framerate geringer ist als die Wiederholungsrate für die Physik.
Physics Update: Im letzten Zyklus war die Waffe in der Wand. OnTriggerStay merkt, dass die Waffe immer noch drin ist und somit ist hierfür die Bedingung erfüllt. OnTriggerEnter ist jetzt aber nicht mehr aktiv, denn jetzt gerade ist nichts eingetaucht.
Erst jetzt kommt das nächste Update. OnTriggerEnter ist schon lange vorbei. Nur OnTriggerStay steht noch an.

Etwas später geht deine Waffe aus dem Trigger wieder raus.
Physics Update: OnTriggerExit erkennt, dass die Waffe jetzt draußen ist.
Ein weiteres physical Update kommt und jetzt ist nichts mehr im Trigger und es geht auch nichts raus, denn das ist ja in der letzten Abfrage passiert.
Jetzt kommt das Update und nichts kann ausgewertet werden.
Hier noch mal eine Grafik dazu, bei der du erkennen Kannst, dass die physikalischen Dinge mit FixedUpdate synchron laufen und eigentlich ein Loop sind, aus dem immer nur dann rausgesprungen wird, wenn das nächste Frame ansteht.

zyklus.thumb.JPG.253cc81449db9cfc273a346a06870e83.JPG
Wenn du also ein Variable nutzt, die nur über Enter und Exit ihren Wert verändert bekommt und nirgendwo anders verändert wird, dann wird alles funktionieren.

Share this post


Link to post
Share on other sites

@malzbie

Vielen Dank für deine ausführliche Antwort.

Das mit OnTriggerEnter und OnTriggerExit funktioniert leider nicht. @unsigned
Wenn ich zwei Wände haben, nennen wir sie Wand1 und Wand2, und diese sich überlagern (was ja durchaus mal vorkommt das zwei Objekte ineinander ragen), dann habe ich das Problem, das ich den Wand1 TriggerExit bekomme, aber keinen neuen Wand2 TriggerEnter, da ich ja bereits in Wand2 bin, was zur Folge hat, das ich in Wand2 die Waffe wieder abfeuern kann.

Deswegen habe ich den TriggerEnter mit einem TriggerStay ersetzt. Sieht wie folgt aus:

    void OnTriggerStay(Collider other)
    {
        canShoot = false;
    }
    private void OnTriggerExit(Collider other)
    {
        canShoot = true;
    }

Mehr mache ich nicht. Und trotzdem kommt es ab und zu vor das die Variable canShoot auf false bleibt, obwohl ich aus dem Trigger raus bin.

 

vor 2 Stunden schrieb malzbie:

Man sollte aber evtl. noch eine Unterscheidung für den Trigger rein tun. Es wird ja bestimmt nicht nur gegen die Wand getriggert.

 

Ist richtig, ich möchte nicht gegen jedes erdenkliche Objekt eine Abrage machen.

Ich verwende derzeit nur Layers und keine Tags, die Wand und der WaffenCollider hat natürlich den entsprechenden Layer, und ist in der Physic Option dementsprechend eingestellt.
Ich finde Tag Abfrage eigenartig, klingt für mich als ob man zuerst abfragt ob eine Kollision stattfindet und dann ob der Tag demjenigen etspricht. Scheint für mich ünnötiger rechenaufwand zu sein zuerst kollisionen generell abzufragen. Ist dem so?

 

Edit:

Ich denke ich habe den Fehler gefunden. Es liegt an zerstörbaren Objekten, wenn diese weg sind habe ich keinen TriggerExit mehr. Ist mir zwar noch etwas rätsehaft wie ich das Objekt zerschiessen kann wenn ich nicht schiessen dürfte, aber ich denke hier beisst sich etwas die Update mit der Physic Abfrage.
 

Share this post


Link to post
Share on other sites
Zitat

Ich finde Tag Abfrage eigenartig, klingt für mich als ob man zuerst abfragt ob eine Kollision stattfindet und dann ob der Tag demjenigen etspricht. Scheint für mich ünnötiger rechenaufwand zu sein zuerst kollisionen generell abzufragen. Ist dem so?

Na ja. Da ist natürlich eine Abfrage mehr drin, aber das macht so gut wie kein Rechenaufwand.
Vielmehr ist die Unterscheidung nicht schlecht, wenn es mehrere triggerbare Objekte gibt und du je nach Objekt etwas anderes machen willst.
 

Übrigens funktioniert ein Triggerevent immer in beide Richtungen. Also in deinem Fall beim Player und bei der Wand.
Wenn du also in eine Wand eindringen solltest, diese aber zerstört wird, wird möglicherweise kein Exit mehr kommen weil der Collider der Wand einfach nicht mehr in der Szene ist.
Du kannst die Wand aber etwas tun lassen, bevor sie sich vernichtet und mit deinem Player bzw. der Waffe vorher OnTriggerEnter ausgeführt hatte. Die Wand hatte das Event ja auch mitgekriegt und könnte für diesen Fall beim zerstören  über OnDestroy() eine Info an die Waffe senden. Klar, die Wand braucht dann ein Script.
 

Share this post


Link to post
Share on other sites

@malzbie

Hat mich bisher mehr verwirrt, da wenn ich viele Tags und auch noch viele Layers habe, das ganze etwas unübersichtlich wird, ob man jetzt eine Abfrage über die Layers setzt oder über die Tags. Aber kommt denke ich immer darauf an, was man gerade tun möchte.

vor 11 Minuten schrieb malzbie:

OnDestroy() eine Info an die Waffe senden
 

Habe ich jetzt so gemacht. Ich denke das sollt das Problem lösen.

Vielen herzlichen Dank.

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×