Jump to content
Unity Insider Forum

Sichtbarkeit der Objects innerhalb der FOV der Kamera


vickal93

Recommended Posts

Ich würde gerne nach und nach alle sichtbaren GameObjects ausgeben lassen. Dabei folgt die Kamera einem Pfad (es ist ein Flur und die sichtbaren Wände sollen ausgegeben werden). Ich habe bislang das hier ausprobiert: 

    void Update() {
        GameObject walls = GameObject.FindGameObjectWithTag ("Wall");
        Renderer[] renders = walls.GetComponentsInChildren<Renderer> ();

        for (int i = 1; i < renders.Length; i++) {
            if (walls.GetComponentInChildren<Renderer> ().isVisible) {
                Debug.Log (renders[i] + " is detected!");
            } else {
                Debug.Log ("Nothing's detecetd!");
            }
        }
    }

Jedoch wird mir dann jede Wand immer und immer wieder ausgegeben. Das Script ist an die Kamera gebunden und alles Sichtbare (im Bild grün, an dem roten ist die Kamera soz. schon "vorbeigefahren") ist das, was sich innerhalb der FOV der Kamera befindet.

Habt ihr Vorschläge?

Unbenannt-2.jpg

Link zu diesem Kommentar
Auf anderen Seiten teilen

Eine andere Methode wäre jeder Wand ein Skript zu verpassen, welches die Sichtbarkeit ausgibt. Beispielhaft verpasse ich hier allen Childs unter dem GameObjekt mit dem Tag "Wall" ein solches Script:

void Start() {
   GameObject walls = GameObject.FindGameObjectWithTag ("Wall");

   foreach (Transform child in walls.transform) {
     child.gameObject.AddComponent<LogVisibility>();
   }
}

Die Klasse:

using UnityEngine;
using System.Collections;

public class LogVisibility : MonoBehaviour {
    void OnBecameVisible() {
        print(this.gameObject.name + " ist sichtbar.");
    }

    void OnBecameInvisible() {
        print(this.gameObject.name + " ist nicht mehr sichtbar.");
    }

}


Eines gibt es noch zu beachten:
Wenn die Wände noch im Editorfenster sichbar sind, dann zählen diese noch als sichtbar! Das Ganze funktioniert also besser in einem Build.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Du könntest alles in ein HashSet packen:

https://www.dotnetperls.com/hashset

Ein set entspricht einer Mathematischen Menge. Da sind Dinge also nur einmal drin. Die add Methode gibt dir ein true zurück, wenn das Element hinzugefügt werden konnte, es also neu ist.

So könntest du z.B. folgendes machen:

HashSet<GameObject> allSeenObjects= new HashSet<GameObject>();
 GameObject walls ;
  Renderer[] renders;
void Start()
{
  walls = GameObject.FindGameObjectWithTag ("Wall");
  renders = walls.GetComponentsInChildren<Renderer> ();//verschoben, das du das nur einmal machen musst.
}
void Update(){      

        for (int i = 1; i < renders.Length; i++) {// wieso zählst du von 1?
            if (renders[i].isVisible) { // Hier hast du das falsche Object gecheckt.
              if(allSeenObjects.add(renders[i].gameObject))// nur true, wenn das object neu ist.
                Debug.Log (renders[i] + " is detected!");
            } else {
                Debug.Log ("Nothing's detecetd!");
            }
        }
    }

Mich wundert es gerade, dass ich keine Methode finde die einem alle Objekte liefert, welche eine Kamera gerade "sieht". Das sollte es doch geben.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Von 1 zählen macht in dem Fall ausnahmsweise einmal Sinn, da man damit das Objekt "walls" selbst ausklammert. Bei meiner Methode wird dem Objekt "walls" auch ein Skript verpasst, man könnte dies noch unterbinden mit. Zudem hatte ich nur die unmittelbaren Childs erwischt.

Hier noch eine Ergänzung zu meinem Code oben:

// Diese Methode liefert nur die unmittelbaren Childs
foreach (Transform child in walls.transform) {
  if (walls.transform!=child) { 
    child.gameObject.AddComponent<LogVisibility>();
  }
}

// Liefert alle Childs unter "walls":
Transform[] allChildren = walls.GetComponentsInChildren<Transform>();
foreach (Transform child in allChildren) {
  if (walls.transform!=child) { 
    child.gameObject.AddComponent<LogVisibility>();
  }
}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

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

×
×
  • Neu erstellen...