Jump to content
Unity Insider Forum

mit Objekten interagieren


Garzec

Recommended Posts

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

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

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

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

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...