Jump to content
Unity Insider Forum

3rd Person Charakter richtig rotieren


ONeillsBude

Recommended Posts

Hallo,

ich baue gerade einen Charakter Controller bei dem man den Charakter mit dem linken Analog Stick in die in den Stick gedrückte Richtung bewegen/drehen und mit dem rechten Stick die Kamera um den Charakter drehen soll. Als Kamera habe ich die Cinemachine Freelook Kamera genommen, da diese sich schon ohne weitere Script-Arbeit  steuern lässt.

Nun habe ich ein Script mit dem sich der Player eigentlich schon richtig steuern lässt....., aber nur solange die Kamera nach Norden guckt. Der Charakter bewegt sich zwar richtig zur Kamera, nur rotiert er nicht zur Kamera - Also eben so als würde die Kamera weiter nach norden gucken.

Ein weiteres Problem ist, wenn die Kamera nach oben oder unten geschwenkt wird versucht der Charakter auch nach oben oder unten zu gehen, was ihn so komisch zittern lässt.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class Adriel : MonoBehaviour
{
    private float LaufenH;
    private float LaufenV;
    private float Geschwindigkeit = 3;
    private float RotationsGeschwindigkeit = 700;
    public Transform Kamera;

    void Update()
    {
        Vector3 Bewegungsrichtung = new Vector3(LaufenV, 0, LaufenH);
        Bewegungsrichtung.Normalize();
        transform.Translate(Bewegungsrichtung * Geschwindigkeit * Time.deltaTime, Kamera);

        if(Bewegungsrichtung != Vector3.zero)
        {
            Quaternion toRotation = Quaternion.LookRotation(Bewegungsrichtung, Vector3.up);
            transform.rotation = Quaternion.RotateTowards(transform.rotation, toRotation, RotationsGeschwindigkeit * Time.deltaTime);
        }
    }

    public void OnLaufenH(InputAction.CallbackContext context)
    {
        LaufenH = context.ReadValue<float>();
    }

    public void OnLaufenV(InputAction.CallbackContext context)
    {
        LaufenV = context.ReadValue<float>();
    }
}

Ich habe schon versucht an einigen Stellen die Kamera als transform einzufügen, aber dann konnte man den Charakter nicht mehr frei drehen oder er  war dann total verdreht.

Wäre toll wenn mich jemand berichtigen und erklären könnte, verstehe das mit den Quaternions auch immer noch nicht wirklich.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich tippe mal auf das hier:

Zitat

The movement is applied relative to relativeTo's local coordinate system.

Das heißt, dass wenn du ein Objekt reinziehst, das relativ zu dessen Parent nicht gedreht ist, dann läufst du immer nach "Norden". Wenn du die World Space-Ausrichtung eines Objekts benutzen willst, dann würde ich den Parameter weglassen und stattdessen schreiben:

var transformedDirection = Kamera.TransformDirection(Bewegungsrichtung);
transform.Translate(transformedDirection * Geschwindigkeit * Time.deltaTime);

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Aah, Verzeihung, verstehe.

In dem Fall kannst du aber trotzdem die erste von meinen beiden Zeilen nehmen und "transformedDirection" statt "Bewegungsrichtung" in Quaternion.LookRotation reinschmeißen.

"Bewegungsrichtung" ist ja einfach nur der Vektor deines Gamepad-Sticks oder WASD oder so. Wenn du den Stick nach oben drückst, dann ist das (0, 0, 1). Völlig egal, was die Kamera in dem Moment macht. Und in diese Richtung drehst du dich aktuell einfach immer.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ja, so funktioniert das schon ganz gut.

Habe noch unter die transform.rotation die Zeile ergänzt damit sich der Charakter nicht mit der Kamera nach vorn oder hinten rotiert:

transform.eulerAngles = new Vector3(0, transform.eulerAngles.y, transform.eulerAngles.z);

Der Charakter bewegt sich ja genau in die Richtung in die die Kamera guckt.

Kann man noch verhindern das der Charakter nach oben oder unten gedrückt wird, wenn man mit der Kamera nach oben oder unten sieht?

Man kann so noch an Wänden hoch klettern, wenn die Kamera nach oben guckt, oder der Charakter versucht immer durch den Boden zu gehen wenn man nach unten guckt, das bringt den Charakter dazu immer etwas zu "zittern" wenn man ihn bewegt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Da würde ich nicht über EulerAngles gehen, das kann schief gehen.

Lieber einmal die Y-Koordinate des Richtungsvektors auf 0 setzen, bevor da eine Rotation draus gemacht wird:

var lookDirection = myCamera.forward;
lookDirection.y = 0;

var lookRotation = Quaternion.LookRotation(lookDirection);

var input = new Vector3(...);
var moveDirection = lookRotation * input;

Mit Cinemachine ist das immer so schön einfach, was kleines zu basteln, aber sobald man da was spezifisches von will, wird's immer gleich hakelig. Deswegen benutz ich das Ding nie. Ich mag's z.B. viel lieber, mir eine kleine GO-Hierarchie zu bauen und da als Parent der Kamera ein Objekt zu haben, das sowieso schon horizontal ausgerichtet ist. Dann spart man sich solche Umwege im Code.

Link zu diesem Kommentar
Auf anderen Seiten teilen

So spezifisch ist das was ich machen will ja gar nicht, so eine Steuerung ist doch schon seit Jahren Standard (kommt mir jedenfalls so vor) und es liegt auch nicht an Cinemachine, mit jeder anderen Kamera habe ich das selbe Problem.

In der Zeile habe ich bei "Transform relativeTo" die Kamera:

transform.Translate(Bewegungsrichtung * Geschwindigkeit * Time.deltaTime, Kamera);

Von da aus wird dann berechnet wie sich der Charakter bewegt. Wenn die Kamera also nach oben der unten guckt, will der Charakter auch nach oben oder unten was eben zu Problemen wie z.B. durch die Map glitchen führt. Ich glaube ich brauche da nur die rotation.y der Kamera aber ich kann da weder Quaternion, noch Vector3 eintragen.

Ich habe ein Tutorial geguckt, aber wird von der Space.World ausgegangen, was bei mir ja nicht funktioniert.

Ich weiß jetzt auch nicht wie ich das noch anders machen könnte

Wenn ich es mit Kamera.rotation.y versuche kommt das:

error CS1503: Argument 2: cannot convert from 'float' to 'UnityEngine.Space'
 

Edit:

Habs jetzt doch geschafft indem ich die Kamera in einen Quaternion umgewandelt habe die zwei überflüssigen Achsen auf 0 gesetzt und wieder zurück gewandelt habe. Ist das so korrekt oder macht man das anders?

        Quaternion K = Kamera.transform.rotation;
        K.x = 0;
        K.z = 0;
        Kamera.transform.rotation = K;

Danke noch mal für die Hilfe, so konnte ich doch noch richtig zum funktionieren bringen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 3 Stunden schrieb ONeillsBude:

was bei mir ja nicht funktioniert.

Nur, wenn du es nicht richtig machst ;)

Mit der Lösung, die ich dir zuletzt gegeben habe, kannst du Space.World benutzen.

vor 3 Stunden schrieb ONeillsBude:

Ist das so korrekt oder macht man das anders?

Nein, das ist keine gute Idee. Ändere niemals die Koordinaten eines Quaternions direkt. Mach's lieber so wie in meiner Lösung.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

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

×
×
  • Neu erstellen...