Jump to content
Unity Insider Forum

Instantiate, verschiedene Drehachsen auf 0 setzen (gelöst)


KaBau

Recommended Posts

Hi,
ich möchte, dass bei "Instantiate" nicht alle Drehachsen des Spawnpunkt übernommen werden wie es bei

GameObject inst = Instantiate(shotGun, shotSpawnGun.position, shotSpawnGun.rotation);

passiert. Von der "rotation" möchte ich nur die Achsen Y und Z nutzen. Die Achse X soll den Wert 0.0f erhalten. Somit habe ich folgendes eingegeben:

GameObject inst = Instantiate(shotGun, shotSpawnGun.position, (0.0f,shotSpawnGun.rotation.y, shotSpawnGun.rotation.z));

Hierbei wird im Visual Studio der letzte Bereich in der Klammer aber mit einer roten Welle unterstrichen, was ja auf einen Fehler hinweist. In der Scipt Reference von Unity habe ich gelesen, dass die Rotation als Quaternion eingegeben wird. Dieses hat neben "x","y" und "z" auch noch die Variable / den Wert "w". Was ist "w"? Mir scheint ja dieses zu fehlen und deshalb wird der Code als falsch markiert.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi,

du kannst dir mit 'Quaternion.Euler(x, y, z)' deine eulerische Rotiation in einen Quaternion umrechnen lassen.

Also:

GameObject inst = Instantiate(shotGun, shotSpawnGun.position, Quaternion.Euler(0.0f,shotSpawnGun.rotation.y, shotSpawnGun.rotation.z));

Wenn du die drei Komponenten einfach nur in Klammern setzt, bekommst du ein Tripple was soweit ich weiß erst in einer neueren C# Version unterstützt wird (?)

Syntaktisch richtig müsstest du schreiben 'new Quaternion(x, y, z, w)', aber da eh niemand Quaternions versteht, würde ich das lieber lassen.. ^^

 

Wenn du trotzdem wissen willst, was es mit Quaternions auf sich hat, kann ich dir dieses Video empfehlen: 

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo @Mr 3d, irgendwie scheint es nicht gleich zu sein:

Mit

GameObject inst = Instantiate(shotGun, shotSpawnGun.position, shotSpawnGun.rotation);

sieht es so aus (wie es sein sollte):

1.jpg.4286ef8157b5783b66900f647c037e62.jpg

Mit

GameObject inst = Instantiate(shotGun, shotSpawnGun.position, Quaternion.Euler(shotSpawnGun.rotation.x, shotSpawnGun.rotation.y, shotSpawnGun.rotation.z));

(was ja identisch mit dem ersten Code sein sollte), sieht es so aus:

2.jpg.bfb3ddba7087ab7bcef7ac0c48e755c0.jpg

Ich habe hier eine drehende Kanone. Bei dieser funktioniert auch mein ursprünglicher Code. Ich wollte diesen aber etwas abgeändert für eine andere Kanone nutzen. Da diese andere Kanone schräg steht, werden auch die Schüße schräg und somit die Collider, was zu einer ungenauen Kollisionsabfrage führt. Deshalb wollte ich bei der anderen Kanone die X Achse auf 0.0f setzen, damit die Schüsse nicht mehr schräg stehen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 8 Minuten schrieb Jolinah:

ich glaube da fehlt noch das eulerAngles nach rotation

Ja, das fehlte. Nun klappt es wie gewollt. Danke.

Edit:
Ich habe es aber leider noch immer nicht verstanden und werde sicher bei einem nächsten Problem in diesem Bereich wieder fragen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • KaBau changed the title to Instantiate, verschiedene Drehachsen auf 0 setzen (gelöst)

Lange Zeit hatte ich auch keine Ahnung wie man mit den Quaternions umgeht und ich verstehe sie vermutlich auch heute noch nicht 100%. Das Video oben hat diesbezüglich zum Verständnis beigetragen, danke dafür ;)

Meiner Meinung nach muss man sie aber auch nicht wirklich verstehen, sondern nur lernen was damit für Operationen möglich sind, um die gewünschten Rotationen zu erhalten. Und das sind gar nicht viele. Entscheidend ist, dass man 3D-Rotationen entweder mit 3 Winkeln um die entsprechenden Achsen (Euler) darstellen kann, oder als Quaternion. Diese haben nicht viel gemeinsam, aber man kann von einem System in das andere konvertieren.

Das war auch der Grund dass das eulerAngles hinzugefügt werden musste, da du mit Euler-Rotationen arbeiten wolltest. Rotation.eulerAngles konvertiert ein Quaternion in eine Euler-Rotation (Vector3) mit den Drehwinkeln um die Achsen X, Y und Z.

Da Instantiate jedoch eine Rotation in Form eines Quaternions erwartet, müssen die veränderten Euler-Winkel wieder in ein Quaternion konvertiert werden. Das geschieht mit Quaternion.Euler(Vector3 bzw. x, y, z).

Dann gibt es die Konstante Quaternion.identity: Diese steht für keine Rotation, bzw. entspricht auch den Euler-Winkeln (0,0,0).

Ausserdem gibt es weitere statische Methoden wie Quaternion.Angle, Quaternion.FromToRotation etc.. diese erklären sich aber fast von selber, wenn man die Dokumentation liest und die Multiplikation verstanden hat:

Die Quaternion-Multiplikation

Es können entweder 2 Quaternions miteinander multipliziert werden oder ein Quaternion und ein Vector3. Ausserdem ist die Quaternion-Multiplikation nicht kommutativ, das heisst es macht einen Unterschied ob a * b oder b * a geschrieben wird.

Quaternion resultat = quaternion1 * quaternion2;

Zuerst wird die 1. Rotation und danach die 2. Rotation angewendet. Das Resultat ist die End-Rotation, nachdem beide Rotationen nacheinander angewendet wurden.

Vector3 resultat = quaternion * vector3;

Damit kann ein Richtungsvektor relativ zu der Rotation erzeugt werden. Sagen wir auf der Y-Achse soll um 90° gedreht werden. In Unity zeigt die Z-Achse normalerweise nach vorne. Rotiert man nun 90° auf der Y-Achse dann zeigt die Z-Achse anschliessend nach Rechts.

Multipliziert man also Quaternion.Euler(0, 90, 0) mit Vector3.forward (Z-Achse), dann erhält man einen Richtungsvektor der in die Richtung der Z-Achse zeigt, nachdem die Rotation angewendet wurde. In dem Fall bekommt man (1, 0, 0 = Vector3.right = Rechts) heraus, da die Z-Achse nach der Rotation wie oben beschrieben nach Rechts zeigt.

Beim Transform kennt man ja z.B. die Properties transform.forward/right/up. Diese kann man auch so ausrechnen:

Vector3 forward = transform.rotation * Vector3.forward;
Vector3 right = transform.rotation * Vector3.right;
Vector3 up = transform.rotation * Vector3.up;

Hier noch ein paar Beispiele:

// Objekt um eine beliebige globale Rotation drehen
transform.rotation *= Quaternion.Euler(x, y, z);
// Oder eine lokale Rotation in Bezug auf das Parent
transform.localRotation *= Quaternion.Euler(x, y, z);
// Objekt 10 Units 45° schräg nach Vorne bewegen. Es ist so, als würde man
// das Objekt auf Y um 45° drehen und dann erst vorwärts bewegen,
// nur wird das Objekt nicht gedreht, sondern nur die Position verändert.
transform.position += (transform.rotation * Quaternion.Euler(0, 45, 0)) * new Vector3(0, 0, 10);
// Objekt 10 Units nach Rechts bewegen (in das lokale Rechts des Objekts, nicht das der Szene)
transform.position += transform.rotation * new Vector3(10, 0, 0);
// Das geht natürlich auch einfacher über localPosition
transform.localPosition += new Vector3(10, 0, 0);
// Zuerst 30° um die Y-Achse drehen, danach noch zusätzlich 60° um die Z-Achse
transform.rotation *= Quaternion.Euler(0, 30, 0);
transform.rotation *= Quaternion.Euler(0, 0, 60);
// oder
transform.rotation *= Quaternion.Euler(0, 30, 0) * Quaternion.Euler(0, 0, 60);

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

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

×
×
  • Neu erstellen...