TheOnlyOne Geschrieben 15. Oktober 2018 Melden Share Geschrieben 15. Oktober 2018 Guten Abend, ich habe eine Klasse, welche das Ihandler Interface's verwendet. Nun möchte ich, dass in einer anderen Klasse, sobald OnDrag() Ereignis aktiv ist, ebenfalls paar Funktionen durchlaufen. Ich kann natürlich ein Bool verwenden, wenn OnDrag aktiv ist und in anderen Klasse über bool Funktionen starten, aber gibt bestimmt eine elegantere Lösung? Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Jolinah Geschrieben 16. Oktober 2018 Melden Share Geschrieben 16. Oktober 2018 Hallo, Das lässt sich über C#-Events oder UnityEvents lösen. Mit C# funktioniert es etwa so: public event System.Action<PointerEventData> Drag; public void OnDrag(PointerEventData eventData) { System.Action<PointerEventData> handler = Drag; if (handler != null) { handler(eventData); } } In der Klasse die darauf reagieren soll muss dann aber ein Event-Handler registriert und allenfalls wieder entfernt werden: void OnEnable() { otherObject.Drag += Other_Drag; } void OnDisable() { otherObject.Drag -= Other_Drag; } private void Other_Drag(PointerEventData eventData) { // Dieser Code wird dann ausgeführt, wenn bei der anderen Klasse das OnDrag ausgeführt wird. } Mit UnityEvents sähe es so aus: public class MyDragEvent : UnityEvent<PointerEventData> {} public MyDragEvent dragEvent; void Start() { if (dragEvent == null) dragEvent = new MyDragEvent(); } public void OnDrag(PointerEventData eventData) { dragEvent.Invoke(eventData); } Der Vorteil von UnityEvents ist, dass via Inspektor Objekte und Methoden zugewiesen werden können, die dann aufgerufen werden beim OnDrag. Aber natürlich können die Handler auch wie bei C# mit Code hinzugefügt werden: void OnEnable() { otherObject.dragEvent.AddListener(Other_Drag); } void OnDisable() { otherObject.dragEvent.RemoveListener(Other_Drag); } void Other_Drag(PointerEventData eventData) { // Dieser Code wird dann ausgeführt, wenn bei der anderen Klasse das OnDrag ausgeführt wird. } Oder meintest du Drag&Drop eines UI-Elements auf ein 3D-Objekt etc.? Dann müsste bei der Kamera einfach ein PhysicsRaycaster hinzugefügt werden, damit das Interface IDropHandler auch bei 3D-Objekten funktioniert. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
TheOnlyOne Geschrieben 18. Oktober 2018 Autor Melden Share Geschrieben 18. Oktober 2018 Vielen Dank! Das ist genau wonach ich gesucht habe. Ich verstehe nicht ganz die deklaration und definition von Events in diesem Fall. public event System.Action<PointerEventData> Drag; Warum event klein geschrieben und was bedeutet System.Action<PointerEventData>? System.Action<PointerEventData> handler = Drag; und diese Zeile verstehe ich auch nicht, kann man ohne diese Zeile direkt Drag(eventData) schreiben? Wäre sehr dankbar wenn du mir das erklären könntest. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Jolinah Geschrieben 19. Oktober 2018 Melden Share Geschrieben 19. Oktober 2018 Event ist kleingeschrieben, weil das ein Sprachfeature von C# ist und somit ein Schlüsselwort. Also für C# hat das eine spezielle Bedeutung. Es weiss dann dass man ein Event definieren möchte. Ein Event ruft, wenn es ausgelöst wird eine bestimmte Funktion auf. Beim definieren eines Events muss man auch definieren wie die Funktion genau aussehen soll, die dann aufgerufen wird. System.Action<PointerEventData> bedeutet: Eine Funktion ohne Rückgabewert (Action), mit genau einem Parameter vom Typ PointerEventData. Um das Event auszulösen, benutzt man normalerweise den Code den ich in OnDrag() eingefügt habe. Im Prinzip könnte man auch direkt schreiben: if (Drag != null) { Drag(eventData); // <- löst das Drag-Event aus und übergibt das benötigte PointerEventData-Objekt } Die Zeile vor dem If ist nur eine lokale Variable namens handler und das Drag wird dieser handler-Variable zugewiesen. Danach wird das Event über die Variable ausgelöst. Das macht man in der Regel aus Gründen der Threadsicherheit, aber das ist erstmal nicht so wichtig. In deinem Fall musst du das Event nicht selber auslösen, da das OnDrag bereits durch Unity über das Interface aufgerufen wird. Ein Event kann dann mehrere Objekte haben die auf das Ereignis reagieren möchten. Beim Auslösen des Events werden automatisch alle Objekte benachrichtigt, die sich zuvor bei dem Event registriert haben. Das Objekt das darauf reagieren will, teilt dem Event sozusagen mit, welche Funktion vom Event aufgerufen werden soll, sobald es ausgelöst wird: // Das Event soll bei Auslösung MeineFunktion aufrufen // Ausgelöst wird das Event von der Quelle, dann wenn sie es für nötig hält bzw. in deinem Fall in OnDrag quelle.Event += MeineFunktion; private void MeineFunktion(PointerEventData eventData) { // Und MeineFunktion muss genau so aussehen, wie das Event es verlangt // bzw. wie das Event definiert wurde. In diesem Fall System.Action<PointerEventData> // was void Name(PointerEventData parameterName) entspricht. } Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
TheOnlyOne Geschrieben 20. Oktober 2018 Autor Melden Share Geschrieben 20. Oktober 2018 Vielen Dank für die ausführliche Erläuterung Jolinah, jetzt verstehe ich das langsam. 😊 Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
TheOnlyOne Geschrieben 24. Oktober 2018 Autor Melden Share Geschrieben 24. Oktober 2018 Ich möchte jetzt neben OnDrag(), noch für jewals für OnPointerDown() und OnPointerUp() in der selben Klasse erstellen. Muss ich für jeden Event den Vorgang wiederholen, oder gibt es eine bessere Lösung? Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Jolinah Geschrieben 25. Oktober 2018 Melden Share Geschrieben 25. Oktober 2018 Was es noch gibt sind die Methoden SendMessage und BroadcastMessage. Damit kannst du Methoden bei anderen MonoBehaviours ausführen lassen, allerdings läuft das über Reflection und kann je nachdem langsamer sein. public void OnDrag(PointerEventData eventData) { // Ruft die Methode bei allen MonoBehaviours auf dem selben GameObject auf (falls vorhanden) SendMessage("MyOnDrag", eventData, SendMessageOptions.DontRequireReceiver); // Ruft die Methode bei allen MonoBehaviours auf dem selben und untergeordneten GameObject auf (falls vorhanden) BroadcastMessage("MyOnDrag", eventData, SendMessageOptions.DontRequireReceiver); // Ruft die Methode bei allen MonoBehaviours auf dem selben und auf übergeordneten GameObjects auf (falls vorhanden) SendMessageUpwards("MyOnDrag", eventData, SendMessageOptions.DontRequireReceiver); } Aber es stellt sich die Frage, ob das ein Script ist, welches diese Events generell weiterleiten soll oder ob die Objekte an die du weiterleiten möchtest sowieso bekannt sind. Dann ginge es auch viel einfacher: public AnderesScript anderesScript; // Via Inspektor ein Objekt/Behaviour zuweisen public void OnDrag(PointerEventData eventData) { anderesScript.Methode(); } 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.