Jump to content
Unity Insider Forum

Prefrab per Script zu parent oder child machen


Simsala Animationen

Recommended Posts

Hallo ich habe jetzt schon länger im Internet gesucht um mein Problem zu lösen und auch eigene Experimente gemacht. Auch hier im Forum habe ich schon gesucht doch leider nix gefunden.Fasll ich so ein Thema nur übersehen habe tut es mit leid.

Es geht um folgendes.

Ich wollte ein ZufallsMonsterCreator erschaffen. Der aus verschieden Prefrabs zufällig einenen Kopf, Rumpf und Beine heraussucht. Da die Figur allerdings auch Unterschiedlich lang sein können soll,

sollten die Prefrabs etwas ausseinander initalisiert werden und dann sozusagen auf den Rumpf zu schweben und per collider "andocken". 

Das Script dafür wäre folgendes

public GameObject Rumpf;

void OnTriggerEnter (Collider other)

{

if(other.Comparetag("Monster"))

{

this.transform.parent= Kopf.transform}

}}

 

Das ganze klappt ganz gut wenn man Objekte hat, die schon im Spiel vorhanden sind. Doch soweit meine Englischkenntnisse reichen und was ich im Internet erfahren habe scheint sich ein Prefrab immer an den Positionskoordinaten des Originals zu bedienen, was dazu zu führen scheint das Unity den Vorgang abschaltet damit keine Dateien beschädigt werden.

Meine Frage wäre jetzt ob das was ich vor habe überhaupt möglich ist und wie man das machen könnte. Im besten Fall natürlich so das ich das Script nicht zu stark umändern müsste um selbst überhaupt noch durchzusehen. Leider blicke ich nämlich bei den Scripten nicht allzu oft durch.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 23 Stunden schrieb Simsala Animationen:

Doch soweit meine Englischkenntnisse reichen und was ich im Internet erfahren habe scheint sich ein Prefrab immer an den Positionskoordinaten des Originals zu bedienen, was dazu zu führen scheint das Unity den Vorgang abschaltet damit keine Dateien beschädigt werden.

Das klingt nicht richtig. Dateien werden so oder so nicht beschädigt.

vor 23 Stunden schrieb Simsala Animationen:

Meine Frage wäre jetzt ob das was ich vor habe überhaupt möglich ist und wie man das machen könnte.

Grundsätzlich ist die Antwort immer "ja".

Aber du musst aufpassen, nicht in ein XY-Problem zu laufen. Dein Problem ist nicht, dass OnTriggerEnter nicht zu funktionieren scheint - sondern dass OnTrigger Enter einfach nicht das ist, was du benutzen solltest, um dein zugrundeliegendes Problem zu lösen: Dass du Prefabs instanziieren willst und die Instanzen aneinander packen willst.

Erst einmal hat Instantiate einen Rückgabewert - die Referenz auf das neu gespawnte Objekt. Statt

Instantiate(myPrefab);

schreibst du also

var myInstance = Instantiate(myPrefab);

und kannst mit myInstance machen, was du willst. Der Typ von myInstance entspricht dabei dem von myPrefab. Ist myPrefab eine Variable vom Typ GameObject, dann ist myInstance auch eine.

Parenting geht zwar auch direkt über Parameter der Instantiate-Funktion, aber wenn man es ausschreibt, ist es vielleicht leichter ersichtlich, was passiert:

var myTorso = Instantiate(torsoPrefab);
var myLegs = Instantiate(legPrefab);

myLegs.transform.parent = myTorso.transform; // Beine dem Torso unterordnen

Jetzt würde ich den Torso-Prefab einfach so bauen, dass dessen Nullpunkt da liegt, wo auch der Nullpunkt der Beine liegen soll. Dann musst du nur noch die Beine zum Torso verschieben, sodass die Nullpunkte aufeinander liegen. Da myLegs schon myTorso untergeordnet sind, musst du dafür nur die lokale Position (also die relativ zum Parent, dem Torso) auf 0, 0, 0 setzen:

myLegs.transform.localPosition = Vector3.zero;

Um jetzt den Kopf am Torso anzubringen, wäre eventuell ein Kind-Objekt beim Torso sinnvoll. Dieses macht nichts besonderes außer da zu sein, wo der Kopf hin soll. Du packst dann in jedes Torso-Prefab so ein Objekt rein und holst es dir nach dem instanziieren:

var neckPosition = myTorso.transform.Find("Neck Object");

Ich würde generell von Transform.Find eher abraten, aber aktuell ist es schön einfach damit, das ganze erstmal zum Laufen zu kriegen. "Neck Object" (ohne Anführungszeichen) ist dabei der Name des Kind-Objekts des Torsos.

Jetzt noch den Kopf spawnen und es dem Hals unterordnen:

var myHead = Instantiate(headPrefab);
myHead.transform.parent = neckPosition;
myHead.transform.localPosition = Vector3.zero;

Fertig! Da gibt's noch ein paar Sachen, die man auf lange Sicht verbessern könnte, aber jetzt funktioniert das schon einmal ganz ohne Collider.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Danke erst mal für die Antwort. Ich habe das ganze noch einmal mit dem Collider probiert da ich mir ziemlich sicher war das etwas da stand, was mit den Daten zu tun hat. Jetzt steht aber

"Setting the parent of a transform which resides in a prfab is diabled to prevent data corruption.UnityEngine.Transform:set_parent(Transform) " da.

Ich hatte mich für den Collider entschieden weil ich den Monstercreator wie im Spiel "Spore" nachstellen wollte, nur das eben das ganze zufällig erstellt wird statt vom Spieler.

So das auch die Gliedmaßen an den verschiedensten Stellen auftauchen können.

Mit der Methode die du vorschlägst müsste sich das allerdings auch über verschieden Positionsangaben regeln lassen.

Ich verstehe allerdings nicht warum ein Rückgabewert von Instantiate verhindert das ich so nicht nutzen konnte.(Wenn ich das richtig verstanden habe was du meinst.)

Ich suche schon länger nach Erklärungen die mehr auf transform und Vectoren eingehen die mehr als nur Bewegung erklären, doch finde leider immer nur alles über Variablen, Schleifen und Methoden.

Bei der UnityDokumentation verstehe ich gleich nie was die da überhaupt von mir wollen.

Jetzt habe ich mal wieder was neues gelernt. Das man var selbst als GameObject verwenden kann.

Das bringt mich auf jeden Fall schon einmal weiter, vielen Dank :D

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ah, dein Fehler kommt daher, dass du das Prefab zu ändern versuchst. Also - dein Code versucht das.

Im Instantiate-Kontext gibt es halt das Prefab. Das ist ein GameObject, das in den Assets liegt statt in der Szene. Man hat entsprechend all die Eigenschaften und Methoden von GameObjects zur Verfügung.

Dann gibt es das, worauf Instantiate eine Referenz zurückgibt - das ist eine Kopie dieses GameObjects, das in der Szene existiert. Das ist das Objekt, das du verändern willst.

Mit eventueller Korruption meint Unity hier, dass du versuchst, das Prefab zu ändern. Dieses existiert in den Assets und eine Änderung wäre entsprechend ein Eingriff in die Assets, der mit hoher Sicherheit nicht gewollt ist.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

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

×
×
  • Neu erstellen...