Jump to content
Unity Insider Forum

Collider wie kann man das machen?


nibiru6411

Recommended Posts

Hallo Leute!

 

Ich bin jetzt soweit, dass ich alles für mein Spiel zusammen habe und dabei bin es zusammen zu setzen. Allerdingst habe ich noch drei Probleme mit den Collider und ich wäre froh wenn mir hier jemand helfen könnte. Ich werde diese drei Probleme mit euch der Reihe nach durchgehen. Da meine Starthierarchy nur aus einem Collider besteht, also hier das erste Problem.

Erklärung: Es soll eine Labyrinth entstehen, was sich ständig verändert. Dieses besteht aus sogenannten Hauptkörbern in dem etwa 90 verschiedene Gegner sich generieren, selbst die Suche nach dem Spieler vornehmen und so weiter. Diese Haupt Körber existieren nun in verschiedenen Formen und sollen durch Collider automatisch entstehen, was auch alles wunderbar funktioniert. Hier der Code dazu (welcher natürlich noch mehr Haupt Körber hat (nur zur Demonstration)).

 

 

var hauptkoerper1:GameObject;
var hauptkoerper2:GameObject;
var hauptkoerper3:GameObject;
var leerecollider : GameObject;
var Range : int;
var Zufall = 0;
transform.position = Vector3 (188.65, 11.841, 9.21);


function OnTriggerEnter(hit:Collider){
if(hit.CompareTag("Player")){
   Zufall = Random.Range(1,3);
if(Zufall==1){Instantiate(hauptkoerper1, transform.position, transform.rotation);}
if(Zufall==2){Instantiate(hauptkoerper2, transform.position, transform.rotation);}
if(Zufall==3){Instantiate(hauptkoerper3, transform.position, transform.rotation);}
 Instantiate(Leerecollider, transform.position, transform.rotation); [/color]
 Destroy(gameObject);
 }
 }

 

Wie man hier sieht soll zum Objekt nun ein weitere Collider per Instantiate entstehen, dieser soll nun die Ausgabe haben, beim Verlassen des entstandenen Collider, diesen Haupt Körber zu löschen. Das soll mit diesem Code Passieren. Ich weiss natürlich dass er den Haupt Körber nicht löschen kann, weil er ja auch nicht angesprochen wird.

 

var collposition1:GameObject;
function OnTriggerExit(hit:Collider){
if(hit.CompareTag("Player")){
 Instantiate(collposition1, transform.position, transform.rotation);
 Destroy(gameObject);
 }
 }

 

Es funktioniert zwar, aber er löscht eben nur den Collider und nicht das Gameobjekt, lässt den ersten Collider wieder entstehen, so dass ich dann an derselben Stelle zwei Haupt Körber habe, wenn ich wieder reingehe. Wie kann ich es nun anstellen, diesem Collider zu sagen, dass er eben den Haupt Körber löschen soll, der vorher entstanden ist. Das Problem dabei ist ja nicht ihm zu sagen dass er es machen soll wenn dieser Körber fest wäre, aber dieser entsteht ja im ersten durch Zufall, wo ich nicht weiss welcher nun entstanden ist. Ich hatte schon überlegt, aus dem einem Collider einen zu machen, diesen stehen zu lassen und die Codes zusammenzuführen, aber auch hier habe ich das Problem das ich eben nicht weiss welcher Haupt Körber beim Eintreten in den Collider entstanden ist.

 

 

Zur besseren übersicht, wäre es mir am liebsten wenn man irgendwie sagen könnte lösche das Gameobjekt auf Position„ transform.position = Vector3 (188.65, 11.841, 9.21)“

 

über Hilfe wäre ich sehr dankbar.

 

 

Habe die Nacht gesessen und das Problem behoben und konnte einige Fehler finden die jetzt beseitigt sind. Wem es Interessiert hier der nun der fertige Code. Die transform.position war zum Beispiel an der falschen Stelle. Leider muss ich diese aber angeben, weil das Prefab nach und nach fertig gestellt wurde, am Ende der Nullpunkt nicht das Centrum ist.

var hauptkoerper1:GameObject;
var hauptkoerper2:GameObject;
var hauptkoerper3:GameObject;
var Range : int;
var Zufall = 0;

function OnTriggerEnter(hit:Collider){
  if(hit.CompareTag("Player")){
   Zufall = Random.Range(1,3);
   transform.position = Vector3 (188.65, 11.841, 9.21);
  if(Zufall==1){Instantiate(hauptkoerper1, transform.position, transform.rotation);}
  if(Zufall==2){Instantiate(hauptkoerper2, transform.position, transform.rotation);}
  if(Zufall==3){Instantiate(hauptkoerper3, transform.position, transform.rotation);}
 Destroy(gameObject);
 }
 }

Den Exit Code habe ich nun nicht mehr in einem extra Collider gepackt, sondern über das Prefab gesetzt und dieses neu geschaffen.

var collposition1:GameObject;

function OnTriggerExit(hit:Collider){
if(hit.CompareTag("Player")){
 Instantiate(collposition1, transform.position, transform.rotation);	
 Destroy(gameObject);
 }
 }

Danke an die versuchte Hilfe im Chat, die Lösungsansätze waren aber zu umständlich.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Deshalb jetzt zu Punkt2 des Problems Collider, wie man es machen kann.

 

 

 

Wenn Die Waffen Schiessen, werden beim Auftreffen der Kugeln Einschusslöcher erzeugt. Das Problem nun, wenn ein Collider in den Weg kommt, dann werden diese Löscher nun in der Luft erzeugt. An Fahrstühlen konnte ich das noch ganz lösen, indem ich nur eine Plane gesetzt habe und diese als Trigger verwendet habe mit dem entsprechenden „Tag“ so dass die Löscher zwar in der Luft sind, man das aber kaum bemerkt. Leider geht das aber nicht bei allen Collidern. Hier der Code

 

 

if (hit.collider.transform.CompareTag ("Untagged")) {
var rotation =  Quaternion.FromToRotation(Vector3.up, hit.normal);
if (BulletHole){
 var BulletHole : GameObject = Instantiate(BulletHole, hit.point , rotation);
 BulletHole.transform.parent = hit.collider.transform;
}
if (Smoke){
 var Smoke: GameObject = Instantiate (Smoke, hit.point , rotation);
}
  }

Ich weiss ich könnte dem Collider einen anderen Tag geben, aber gerade wenn man direkt vor einem Trigger steht und Schiesst, dann sollte schon das Loch zu sehen sein und es auch Rauchen. Deshalb gibt es eine Möglichkeit, Collider die einen Trigger haben auszuschliessen? Oder wie könnte man das noch realisieren , das der Schuss durch alles geht was nicht den entsprechenden Tag hat?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Kannst du dein Problem vielleicht ein bisschen kürzer fassen?

Ich weiß immernoch nicht, was du genau willst.

 

Kollisionen ausschalten kannst du layerweise.

Einfach die richtigen Layer auswählen und diese Layer oben unter Edit => Project Settings => Physics in der Layer-Kollsions-Matrix aus schalten.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo!

 

Erst mal danke für die Antwort. Ich habe jetzt dort mal etwas rumexperimentiert, bis jetzt habe ich die Layer noch nicht gebraucht. Wenn ich dort was verstelle, dann verhalten sich meine Gegner sehr merkwürdig. Gibt es irgendwo ein Tut wo einem erklärt wird wie diese Layer einsetzbar sind?

 

 

 

Jetzt habe ich das Problem, das eben meine Gegner auch alle per Raycast gesteuert sind. Zum Beispiel das hier eingefügte Bild. Hier ist ein Geländer wo es nach Unten geht. Wenn ich diesem einen Meshcollider zuweise, kann ich wunderbar durch das Geländer schiessen. Aber in diesem Moment kann der Gegner das Hinternis nicht mehr erkennen und versucht natürlich dort an der Stelle weiter zu laufen, weil der Punkt des Raycastes höher liegt. Setze ich einen Boxcollider hin, dann verhält sich der Gegner richtig, erkennt diesen und berechnet das entspechend um nicht dagegen laufen zu können. Aber dann kann ich nicht durch das Geländer Schiessen, die Funken bzw. der Rauch der dann entsteht, weil er ja aufgetroffen ist entsteht in der Luft. (Die Raycastpunkte sind bei den Gegnern verschieden).

 

bild1.png

 

Deshalb die Frage: Jetzt wird ja meinem Schuss gesagt, wenn du das getroffen hast mit Tag x dann mache das, wenn das dann das usw..

 

Gibt es eine Möglichkeit zu sagen, also nur dem Schuss. Wenn Du getroffen hast den Tag (z. B) „collider“, dann ignoriere diesen und fliege weiter?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Warum benutzt du Raycasts für Charactersteuerung?

Dafür gibt's den CharacterController!

Ich denke er meint eher Sichtfeldprüfung usw..

 

@Topic:

Du kannst der Raycast Methode eine sog. LayerMask übergeben. Such ein wenig im Internet danach, dann wirst du auf die Lösung kommen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Nein ich arbeite mit Raycast. Das funktioniert auch wunderbar. Die Gegner suchen selbstständig den „gameObject.tag“ Player und wenn Sie keinen finden, dann Patrollieren Sie selbstständig in der Weltgeschichte, um Ihn zu finden.

 

Ich kann das auch nicht mehr ändern, habe mehr als 150 Gegner fertig, jeder Gegner hat seine eigene Methode zu suchen zu schiessen, andere Leben usw.. Eigentlich ist mein Spiel von den Scripten her so gut wie fertig. Ich setze es zurzeit nur noch zusammen. Dann fehlt hier da noch ein Modell was erstellt wird. Mit diesen Fragen hier geht es eigentlich in erster Linie die Feinheiten rauszuarbeiten und dazu gehört eben das Einschuss loch, was eben auf einem Trigger Collider nicht entstehen soll bzw. wenn ich einen anderen Tag gebe, dass dann funken Sprühen, was in diesem Fall in der Luft passiert.

 

 

Deshalb auch Problem Nummer eins, was ich ja selbst lösen konnte. In einem Hauptkörper entstehen durch Zufall 90 Gegner. Wenn drei solcher Hauptkörper mit einmal da sind, dann geht das sehr auf die Performance. Deshalb darf immer nur der das sein, wo aktuell gespielt wird.

 

Aber hier mal was zum Zeigen. Hier habe ich die beweglichen Gegner aber nur aufgestellt, das heisst die schiessen zurzeit nicht, weil ich das Sichtfeld auf 1 Meter für diese begrenzt habe. Der grösste Teil läuft auch auf den Nullpunkt weil keine Collider eingebaut sind. Trotzdem sieht man schön wie die durch die Gegend Patrollieren. Man kann sie abschiessen, wo wiederum Items entstehen, die man einsammeln kann. Die festen und technischen Gegner habe ich hier nicht eingebaut. Es stehen 5 Waffen zur Verfügung, sowie 5 verschiedene Arten von Handgranaten. Es war nur ein Testfeld für mich.

 

http://test2.galaxy-.../WebPlayer.html

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ah, zu dem Collider Problem:

http://unity3d.com/support/documentation/ScriptReference/Collider.OnCollisionEnter.html

 

Diese Funktion kann für jeden Collider überschrieben werden. einfach nur aus der übergebenen "Collision" (http://unity3d.com/support/documentation/ScriptReference/Collider.OnCollisionEnter.html) das GameObjekt rausziehen und tags vergleichen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also ich habe, mir nun mal alles vorgeschlagene durchgearbeitet. Musste aber feststellen das keins davon ist, wo ein Ergebnis rauskommt, was mich zufrieden stellt. Dass heisst ohne anderes negativ zu beeinflussen. Zumal in den Dokumentationen ja auch noch darauf hingewiesen wird die „Physics.IgnoreCollision“, nicht zu viel(oft) einzusetzen, da dies eine sehr grosse Ausweitung der Berechnungen darstellt. Da „viel“ ein dehnbarer Begriff ist und man nicht weiss was nun viel ist, habe ich mich entschlossen diesen Weg nicht zu gehen. Eigentlich habe ich beim Testen der Verschiedenen Sachen einen ganz einfachen Weg gefunden, der mich keinerlei Rechenressourcen extra kostet. Ich habe ganz einfach als Trigger eine Plane genommen und diese um 180 Grad verdreht. So Schiesst der jetzt dort durch, die Einschusslöcher entstehen dort wo sie sollen. Ich denke einfacher geht es wirklich nicht.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Jetzt zu Punkt drei, meines Trigger-Problems. Was ist an diesem Code falsch?

function OnTriggerEnter(){
  if(Input.GetKey("e")){
  animation.CrossFade("tueroeffnen",.2);
  }
  }



function OnTriggerExit (){
  animation.CrossFade("tuerschliessen",.2);
}

 

 

Die Tür will sich einfach nicht damit öffnen. Aber beim Rauslaufen schliesst diese. Es wird auch kein Fehler angezeigt. Setze ich eine statische Variable, dann funktioniert es zwar aber es gehen alle Türen auf, was ich nicht will. So müsste ich für jede Tür eine extra Variable festlegen was ich auch nicht unbedingt möchte. Ich möchte nur die Tür öffnen in deren Trigger ich mich gerade befinde.

Link zu diesem Kommentar
Auf anderen Seiten teilen

AAAh, jetzt ist mir das klar, das habe ich natürlich nicht gemacht, ich dachte ich kann dann im Trigger die Animation per Taste aufrufen. Das war natürlich ein kompletter Denkfehler, da brauche ich mich nicht zu wundern. Also wird mir nichts anderes übrig bleiben, als statische Variablen festzulegen für jede Tür und dann entsprechend den Trigger auf True bzw. false zu setzen.

 

 

Denn bei meinen Fahrstühlen funktioniert es ja. Aber dort hat eben jeder Fahrstuhl ein eigenes Script.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Brauchst keine Statische Variable oO

Vergiss natürlich nicht die entsprechende Layer für den Trigger einzustellen, ansonsten wird OnTriggerStay immer ausgeführt, da immer ein Objekt im Trigger ist (Tür Collider!)


var isDoorClosed = true;

function OnTriggerStay()
{
if(Input.GetKeyDown(KeyCode.E))
{
if(isDoorClosed)
{
isDoorClosed = false;
animation.CrossFade("tueroeffnen");
}
else
{
isDoorClosed = true;
animation.CrossFade("tuerschliessen");
}
}
}
[/Code]

Link zu diesem Kommentar
Auf anderen Seiten teilen

Habe den Code etwas angepasst, den ich möchte ja, wenn ich aus dem Trigger rausgehe, das sich das Tor wieder schliesst, da es ja ein in sich ständig veränderndes Labyrinth wird, so dass man nicht wissen soll wo man war und ist. Aber jetzt funktioniert es wie es sein soll.


var isDoorClosed = true;


function OnTriggerStay(){
if(Input.GetKeyDown(KeyCode.E)){
if(isDoorClosed){
animation.CrossFade("tueroeffnen",2);
isDoorClosed = false;
}
}
}
function OnTriggerExit (collidertuer:Collider){
if(isDoorClosed != true){
animation.CrossFade("tuerschliessen",2);
isDoorClosed = true;
}
}
[/Code]

Link zu diesem Kommentar
Auf anderen Seiten teilen

Danke, habe sofort angepasst.

 

 

 

Hier nochmal eine wichtige Sache die ich zufügen musste. Wenn in einer Scene, mehrere „OnTriggerStay“ sind, die verschiedene Aufgaben haben, muss unbedingt folgende Zeile eingefügt werden.

if(hit.CompareTag("Player") …….

 

Als das noch nicht drin war, hat Unity so einiges durcheinander gehauen. So wurde angezeigt das die Tür nicht geöffnet werden kann wo er eigentlich einen Transporter aktivieren soll und einen ganz anderen Text ausgeben sollte. Seit dem ich die Codezeile eingefügt habe, gibt es keine Probleme mehr.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

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

×
×
  • Neu erstellen...