Jump to content
Unity Insider Forum

Raycast geht durch Wände


ONeillsBude

Recommended Posts

Hey,

bin gerade dabei einen Gegner zu programmieren habe das Problem das mich dieser noch durch Wände sehen kann.

Kurz danach bei Google gesucht und auch ne Lösung gefunden: Raycast. Gleich mal in mein Script eingefügt und.... es macht keinen unterschied ob mit oder ohne Raycast, also geht der Raycast der verhindern soll der Gegner durch Wände sehen soll doch durch Wände.

Außerdem scheint die maxDistance ab 2 irgendwie unendlich zu sein. Bei 1 triggert es noch wirklich 1 Meter vor dem Gegner, aber bei 2 steht mein Player etwa 5 oder 6 Meter vom Gegner entfernt und es triggert trotzdem schon.

Wo ist mein Fehler?

 

RaycastHit hit;
public Transform player;

if (Physics.Raycast (transform.position, (player.position - transform.position), out hit, 2)) 
		{
			Debug.Log("Wir werden angegriffen");
			MissionFehlgeschlagen();
		}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Physics.Raycast gibt true zurück, wenn irgendetwas getroffen wurde. Und in deinem Fall trifft er halt die Wand. Mit dem RaycastHit, den du dir ja schon holst, musst du schauen, was getroffen wurde. Und dann den Kram nur auslösen, wenn es der Spieler ist.

RaycastHit hit;
public Transform player;

if(Physics.Raycast (transform.position, (player.position - transform.position), out hit, 2)) 
{
  if(hit.collider.transform == player)
  {
    Debug.Log("Wir werden angegriffen");
    MissionFehlgeschlagen();
  }
}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Habs mit ner Formel lösen können, die ich schon durch das AI Tutorial hatte, mit nem bisschen probieren hatte es dann funktioniert.

RaycastHit hit;
public Transform player;

	void Update () 
	{
		Vector3 direction = player.position - this.transform.position;
		direction.y = 0;

		if (Physics.Raycast (transform.position, (direction), out hit, 20)) 
		{
			if (hit.collider.transform == player)
			{
					Debug.Log ("Alarm");
					Verfolgung();
			}
		}
	}

So konnte ich das dann auch in mein AI Script einfügen, keine Ahnung warum es vorher nicht funktionierte.

Jetzt möchte ich aber noch eine Funktion ausführen wenn der Gegner den Spieler nicht mehr sehen kann. einfach nach nem collider suchen der nicht player ist geht ja nicht, weil es sonst ja auch bei den Wänden triggert und auch ein else funktioniert nicht, weil es dann auch von Anfang an und die ganze Zeit triggert.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Alles, was du jetzt geändert hast ist, dass dein Raycast horizontal ist. Sicher, dass es das ist, was du willst?

Jedenfalls...

vor 18 Stunden schrieb ONeillsBude:

Jetzt möchte ich aber noch eine Funktion ausführen wenn der Gegner den Spieler nicht mehr sehen kann.

Nicht mehr hieße, du führst es aus, wenn der Raycast den Spieler eben noch getroffen hat und jetzt eben... nicht mehr. Das heißt, dass du dir bis zum nächsten Raycast merken musst, ob du eben gerade getroffen hast:

private bool lastRaycastDidHit;

private void Update()
{
  if(Raycast( ... ))
  {
    if(!lastRaycastDidHit)
    {
      // gerade fRisch getroffen, verfolgung aufnehmen!
    }
    lastRaycastDidHit = true;
  }
  else // wenn nicht getroffen
  {
    if(lastRaycastDidHit)
    {
      // eben hab ich ihn noch gesehen...
    }
    lastRaycastDidHit = false;
  }
}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Am 29.12.2017 um 23:40 schrieb Sascha:

Alles, was du jetzt geändert hast ist, dass dein Raycast horizontal ist. Sicher, dass es das ist, was du willst?

Eigentlich ja nicht, diese Formel ist eigentlich dafür das der Gegner den Spieler ohne Raycast sehen kann, aber für das Testlevel funktioniert es erstmal.

Ist eher ne Notlösung, bis ich herausgefunden habe, warum es "normal" nicht funktioniert.

 

Aber danke erstmal für die Hilfe, damit kann ich schon mal arbeiten.

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 2 weeks later...

Hey,

habe mir mal eben die Zeit genommen den "Fehler" zu finden, warum die ursprüngliche Richtung des Raycast nicht funktionierte (und immer noch nicht funktioniert).

if(Physics.Raycast (transform.position, (player.position - transform.position), out hit, 20)) 
{
	if (hit.collider.transform == player) 
			{
				Spielerverfolgung();
			}
}

Das Problem ist das der Ray bei dem Player in den Boden geht. Ich kann mir aber nicht erklären warum der Ray so tief geht, da der Player ja auch genau auf dem Boden steht (eigentlich sogar noch etwas über dem Boden schwebt).

(Die weiße Linie wird mit "Debug.DrawRay (transform.position, (player.position - transform.position));" dargestellt.

Raycast.jpg

Mit der anderen Formel ist das nicht passiert, weil das Ende des Strahls beim Player nach oben auf 0 verschoben wurde.

Kann man den Ray irgendwie komplett nach oben verschieben? Selbst auf 0 habe ich das Problem das mein Gegner mich nicht mehr verfolgt sobald ich auf den Gehweg gehe, der etwas erhöht ist. Ich würde es besser finden wenn der Ray bei Gegner und Spieler etwas in der Mitte der Höhe der Modelle wäre, damit der Gegner den Spieler noch über leichte Erhöhungen sehen kann..

Link zu diesem Kommentar
Auf anderen Seiten teilen

"player.position" zu nehmen ist auch nie eine gute Lösung. Das "Handle bzw. Root" (und damit die Position des Transforms) eines Meshes muss nicht im Zentrum des Meshes liegen.

Bei einem animierten Spieler nimmt man oft den "Head"-Bone des Animations-Rigs (damit "zielt" man dann exakt auf den Kopf des Spielers), man kann natürlich auch einen anderen Bone nehmen. Dies hat den Vorteil, daß man immer exakt das richtige Körperteil trifft, auch wenn sich das Spielermesh über den Skinnedmesh-Renderer verschiebt. Man kann auch ein leeres GameObjekt (Position 0 0 0 ) unter den Headbone platzieren und dieses referenzieren.
 
Bei einem nicht animierten Spieler ist die einfachste Lösung ein leeres GameObjekt unter dem Spieler zu platzieren und dieses GameObjekt dann an die Position zu verschieben, die man haben möchte (z.b. in die Mitte des Meshes oder in Richtung Kopf). Den Ray lässt man dann auf dieses GameObjekt feuern. Natürlich sollte man auch beim Gegner ein solches GameObjekt platzieren. So hat man genaue Kontrolle über den Start- und den Endpunkt des Rays.

Zudem solltest du überlegen dem Spieler und dem Gegner Layer zuzuweisen und den Ray auf diese Layer zu beschränken. Nimmt man nun eine Wand ebenfalls in diese Layer auf, trifft der Ray die Wand, entfernt man die Wand aus diesen Layern, geht der Ray durch die Wand hindurch, also man kann es so einstellen wie man es haben möchte.

Ein Beispiel: Weist du dem Spieler den Layer "player" zu (und dem Gegner den Layer "enemy") und sendest einen Raycast mit der Layermask "player" trifft dein Ray nur noch den Spieler (keine Gegner / keine Wände etc)

Wenn dein Ray alle möglichen Objekte in der Szene treffen soll, dann brauchst du natürlich keine Layer zu setzen.

Siehe (layerMask):
https://docs.unity3d.com/ScriptReference/Physics.Raycast.html

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

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

×
×
  • Neu erstellen...