Garzec Geschrieben 29. September 2018 Melden Share Geschrieben 29. September 2018 Hallo, es geht um eine FPS Steuerung, der Spieler soll mit Gegenständen interagieren können. Beispiele wären Schlüssel aufheben, Türen öffnen, Kisten öffnen, Dinge schieben. Angenommen es liegt ein Schlüssel auf dem Tisch und der Spieler kommt dem Schlüssel ausreichend nahe, dann soll folgendes passieren: Der Schlüssel bekommt einen outline Shader Es erscheint der Text "Schlüssel aufheben" Zunächst habe ich ein Interface erstellt public interface IInteractable { string InteractabilityInfo { get; } void ShowInteractability(); void Interact(); } Dadurch kann ich das Interface dem Schlüssel Script hinzufügen public class Key : MonoBehaviour, IInteractable { public string InteractabilityInfo { get { return "Schlüssel aufheben"; } } public void ShowInteractability() { // Shader anzeigen beispielsweise } public void Interact() { // Den Schlüssel aufheben } } Zum Schluss brauche ich noch ein Script, das prüft, ob der Spieler in Reichweite eines interagierbaren Objektes steht und damit interagieren kann. Aufgrund der FPS Sicht habe ich das Script der Camera beigefügt, diese prüft das Ganze dann mit einem Raycast. public class InteractabilityCheck : MonoBehaviour { private const int RANGE = 3; private void Update() { RaycastHit hit; if (Physics.Raycast(transform.position, transform.forward, out hit, RANGE)) { IInteractable interactable = hit.collider.GetComponent<IInteractable>(); if (interactable != null) { interactable.ShowInteractability(); if (Input.GetKeyDown(KeyCode.E)) { interactable.Interact(); } } } } } Dieses Script versucht zu prüfen, ob das GameObject das Interface implementiert; trifft dieser Fall ein, so werden die Methoden des Interfaces aufgerufen. Der Code funktioniert wunderbar, trotzdem stört mich, dass 1x pro Frame der Raycast mit GetComponent läuft. Jetzt könnte man sagen das ist verkraftbar, aber vielleicht gibt es einen besseren Ansatz? Vielleicht eine ganz andere Herangehensweise / Lösung? Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
malzbie Geschrieben 29. September 2018 Melden Share Geschrieben 29. September 2018 Du kannst ganz einfach sagen, dass ein Raycast eben nicht jedes Frame sondern z.b. nur alle 15 Frames gesendet wird. Erzeuge ne Int Variable, die bei jedem Raycast auf 0 gestellt wird. In jedem Update wird gleich zu Beginn die Variable um 1 erhöht und erst wenn sie die 10 erreicht hat wird der Code, der jetzt in der Update steht, ausgeführt und da stellst du natürlich die Int wieder auf 0. Das wäre dann also alle 1/4 Sekunde, wenn man von 60fps ausgeht. Du kannst natürlich auch die nötige Zahl von der Framerate abhängig machen um auf allen Systemen immer den gleichen Intervall hin zu bekommen. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Garzec Geschrieben 29. September 2018 Autor Melden Share Geschrieben 29. September 2018 Die Idee finde ich nicht schlecht. Jetzt bin ich nochmal gespannt, ob eine ganz andere Lösung kommt Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
KaBau Geschrieben 29. September 2018 Melden Share Geschrieben 29. September 2018 Kannst du nicht einfach dem Objekt einen Collider geben und "is Trigger" aktivieren? Dein Player bekommt auch einen kleinen Collider und im Script des Objektes wird mit "OnTriggerEnter" eine Aktion gestartet. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Mr 3d Geschrieben 29. September 2018 Melden Share Geschrieben 29. September 2018 Ich würde fast sagen, dass ein Trigger pro Item unperformanter sein dürfte als ein Raycast pro Frame.. In einem meiner Projekte habe ich hunderte Raycasts pro Frame und selbst auf älterer Hardware habe ich keine Probleme, also sollte dein einzelner Ray nichts ausmachen.. Wenn du trotzdem Bedenken hast, würde ich wie malzbie schon meinte, einfach nur jedes x-te Frame einen Raycast schießen. Dann könntest du noch mit einer LayerMask arbeiten, damit du nur nach Items und Wänden checkst. Und du kannst jedes mal, wenn ein neues Objekt getroffen wird, dein 'IInteractable' cachen. Damit sparst du dir viele GetComponent calls, die wahrscheinlich schlimmer als der Raycast selbst sind. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 30. September 2018 Melden Share Geschrieben 30. September 2018 Warum geht's denn schon wieder um Performance? Der Vorschlag von @KaBau könnte je nach Situation auch einfach angenehmer zu verwenden sein. Performance ist nach wie vor bei Weitem nicht die einzige Skala für Lösungsqualität. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Garzec Geschrieben 30. September 2018 Autor Melden Share Geschrieben 30. September 2018 Die Idee mit Triggern habe ich verworfen, da sich folgende Situation ergeben könnte (nur mal als Härtefall): Auf dem Tisch liegen 2 Schlüssel nebeneinander, der Spieler steht genau davor. Welcher Schlüssel gewinnt nun das Trigger Rennen? Oder der Trigger des Schlüssels ist so gering, dass der Spieler auf den Tisch springen müsste, um ihn aufzuheben. 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.