Jump to content
Unity Insider Forum
  • Announcements

    • Lars

      Allgemeine Forenregeln   03/13/2017

      Forenregeln Nimm dir bitte einen Moment um die nachfolgenden Regeln durchzulesen. Wenn du diese Regeln akzeptierst und die Registration fortsetzen willst, klick einfach auf den "Mit der Registrierung fortfahren"-Button. Um diese Registration abzubrechen, klick bitte einfach auf den "Zurück" Button deines Browsers. Wir garantieren nicht für die Richtigkeit, Vollständigkeit und Brauchbarkeit der Nachrichten und sind auch nicht dafür verantwortlich. Die Beiträge drücken die Meinung des Autors des Beitrags aus, nicht zwangsläufig das, wofür die Forensoftware steht. Jeder Nutzer, der denkt, dass ein veröffentlichter Beitrag unzulässig bzw. störend ist, ist aufgefordert uns unverzüglich per E-Mail zu kontaktieren. Wir haben das Recht störende Beiträge zu löschen und bemühen uns, das in einem realistischem Zeitraum zu erledigen (sofern wir beschlossen haben, dass die Löschung notwendig ist). Du akzeptierst, durchgehend während der Nutzung dieses Services, dass du dieses Forum nicht dazu missbrauchen wirst, Inhalte zu veröffentlichen, welche bewusst falsch und/oder verleumderisch, ungenau, beleidigend, vulgär, hasserfüllt, belästigend, obszön, sexuell belästigend, bedrohlich, die Privatsphäre einer Person verletzend oder in irgend einer Art und Weise das Gesetz verletzen. Des Weiteren akzeptierst du, dass du keine urheberrechtlich geschützte Inhalte ohne Erlaubnis des Besitzers in diesem Forum veröffentlichst. Mit dem Klick auf den "Mit der Registrierung fortfahren"-Button, akzeptierst du zudem unsere Datenschutzerklärung und stimmst der Speicherung deiner IP-Adresse und personenbezogenen Daten zu, die dafür benötigt werden, um dich im Falle einer rechtswidrigen Tat zurückverfolgen zu können bzw. permanent oder temporär aus dem Forum ausschließen zu können. Es besteht keine Pflicht zur Abgabe der Einwilligung, dies erfolgt alles auf freiwilliger Basis.   Zusatzinformationen Der Forenbetreiber hat das Recht, Nutzer ohne Angabe von Gründen permanent aus dem Forum auszuschließen. Des Weiteren hat er das Recht, Beiträge, Dateianhänge, Umfrage, Blogeinträge, Galleriebilder oder Signaturen ohne Angabe von Gründen zu entfernen. Mit der Registrierung verzichtest du auf alle Rechte an den von dir erstellten Inhalten, bzw. treten diese an das Unity-Insider.de und Unity-Community.de ab. Dies bedeutet im Klartext, dass das Unity-Insider.de und Unity-Community.de frei über deine Texte verfügen kann, sofern diese nicht wiederum die Rechte anderer verletzen. Es besteht weiterhin kein Anspruch von registrierten Nutzern bzw. ehemaligen registrierten Nutzern darauf, dass erstellte Inhalte und/oder die Mitgliedschaft (User) wieder gelöscht werden (Erhaltung der Konsistenz dieses Forums).   Einwilligungserklärung Wenn du mit der Speicherung deiner personenbezogenen Daten sowie den vorstehenden Regeln und Bestimmungen einverstanden bist, kannst du mit einem Klick auf den Mit der Registrierung fortfahren-Button unten fortfahren. Ansonsten drücke bitte Zurück. Stand: 07.03.2011
Sign in to follow this  
ONeillsBude

Raycast geht durch Wände

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();
		}

 

Share this post


Link to post
Share on other sites

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();
  }
}

 

Share this post


Link to post
Share on other sites

OK, jetzt geht gar nichts mehr, selbst mit extrem hoher maxDistance triggert es nur noch wenn ich direkt im Gegner drinnen stehe.

Der "Strahl" geht doch direkt vom Gegner zu Spieler, oder? Der "Strahl" scheint aber nur zu treffen wenn der Player direkt im Gegner steht.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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;
  }
}

 

Share this post


Link to post
Share on other sites

Wieso hat er gerade einen fisch getroffen?? Was denn für'n Fisch?
* Jahresabschluß-Rosinenkacker-Scherz* :D

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

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..

Share this post


Link to post
Share on other sites

"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

Share this post


Link to post
Share on other sites

Danke für diese sehr ausführlich Antwort, hat mir sehr weiter geholfen!

Jetzt funktioniert es genauso wie es soll

Damit dürfte das Thema "Raycast" nun endlich komplett abgeschlossen sein.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

×