Jump to content
Unity Insider Forum

Verschiedene Rotationen kombinieren


uumli

Recommended Posts

Hallo, ich habe hier 2 Skripte, die mir ein Problem bereiten.

Das erste Skript "FPS_MouseRotation" ist eine Adaption für meinen PlayerController, um meinen Spieler um die Y-Achse mit der Maus zu rotieren. (Und für die Kamera das gleiche mit der X-Achse)

Das zweite Skript: "InverseGravity" sorgt dafür, dass die Gravitation des Spielers invertiert wird, sobald dieser "R" drückt. Damit die Rotation für den Nutzer erkennbar und "smooth" abläuft (außerdem verbessert das die Verständlichkeit, dass sich nun die Orientierung des Spielers verändert hat) verwende ich Vector3.Lerp mit Time.deltaTime.

Nun zum Problem: Die beiden Skripte überschreiben jeweils die Rotation des Spielers, wodurch diese, um die Y-Achse immer wieder auf 0 gesetzt wird und das Bild somit "wackelt". Ich muss also beide Rotationen zu einer zusammen fassen. Meine Versuche sind dort an 2 Problemen  gescheitert.

1. Trotz kombination beider Rotationen, wackelte das "Bild" bzw. der Spieler weiter vor sich hin.

2. Time.deltaTime wurde auch auf die Rotation der Y-Achse bezogen, was ich unbedingt vermeiden möchte, da der Input des Spielers (der Maus) direkt sein muss.

Vieleicht hat jemand eine Idee, wie man das ganze Lösen könnte. Beide Skripte beziehen sich auf das selbe GameObject. Die Skripte können zusammen gefasst werden.

Vielen Dank, für die Hilfe. :)

 

using System.Collections.Generic;
using UnityEngine;

public class FPS_MouseRotation : MonoBehaviour {
    public float mouseSensitivityX = 1;
    public float mouseSensitivityY = 1;
    Transform cameraTransform;
    float verticalLookRotation;


    // Use this for initialization
    void Start() {
        cameraTransform = Camera.main.transform;
    }

    // Update is called once per frame
    void Update() {
        transform.Rotate(0, Input.GetAxis("Mouse X") * mouseSensitivityX, 0); // <-
        verticalLookRotation += Input.GetAxis("Mouse Y") * mouseSensitivityY;
        verticalLookRotation = Mathf.Clamp(verticalLookRotation, -60, 60);
        cameraTransform.localEulerAngles = Vector3.left * verticalLookRotation;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(FPS_CharacterController))]
public class InverseGravity : MonoBehaviour {

    private FPS_CharacterController fpscontroller;

    public float rotationAmount = 180f;
    public float rotationSpeed = 10f;
    public Vector3 destEuler = new Vector3(0, 0, 0);
    private Vector3 currEuler = new Vector3(0, 0, 0);

    // Use this for initialization
    void Start () {
        fpscontroller = GetComponent<FPS_CharacterController>();
        transform.eulerAngles = destEuler;
    }

    // Update is called once per frame
    void Update () {

        if (Input.GetKeyDown(KeyCode.R)) {
            destEuler.z += rotationAmount;
            fpscontroller.gravity = -fpscontroller.gravity;
            fpscontroller.jumpSpeed = -fpscontroller.jumpSpeed;
        }

        currEuler = Vector3.Lerp(currEuler, destEuler, Time.deltaTime * rotationSpeed); // <-
        transform.eulerAngles = currEuler;
    }
}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 10 Stunden schrieb Sascha:

Was hältst du davon, ein GameObject zu haben, das sich einfach nur nach der Gravitation ausrichtet, und diesem Objekt die Spielfigur unterzuordnen - diese dreht sich dann relativ zu ihrem Parent?

Das habe ich versucht. Wenn sich nun der Spieler bewegt und das übergeordnete Objekt rotiert, rotiert der Spieler um die Achse von dem Objekt und nicht um die eigene. 

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 9 Stunden schrieb Sascha:

Hast du Bilder? Ich kann mir das gerade nicht vorstellen.

Ich habe hier einmal ein Video des unerwünschten Effekts gemacht. Der Spieler rotiert sich um die Achse des Würfels (als übergeordnetes Objekt), anstatt um seine eigene. Dadurch kann ich das so nicht machen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Okay, also VVVVVV in 3D...?

Ich muss zugeben, dass ich

Am 8.1.2019 um 10:12 schrieb Vermentex:

Wenn sich nun der Spieler bewegt und das übergeordnete Objekt rotiert, rotiert der Spieler um die Achse von dem Objekt und nicht um die eigene. 

nicht verstehe. Denn genau das war doch das Ziel, oder nicht? Du willst, dass deine Spielfigur sich um die eigene Y-Achse dreht, und dazu noch um eine weitere Achse (hier die des Würfels), damit sie am Ende kopfüber ist und an der Decke läuft?

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 6 Stunden schrieb Sascha:

Okay, also VVVVVV in 3D...?

Ich muss zugeben, dass ich

nicht verstehe. Denn genau das war doch das Ziel, oder nicht? Du willst, dass deine Spielfigur sich um die eigene Y-Achse dreht, und dazu noch um eine weitere Achse (hier die des Würfels), damit sie am Ende kopfüber ist und an der Decke läuft?

Nein, das ist leider nicht mein Ziel. 

Der Spieler dreht sich um seine Y-Achse um sich umzuschauen und um seine Z-Achse um sich kopfüber zu rotieren. Wenn er sich um die Achse des Würfels dreht, liegt auch der Mittelpunkt beim Würfel. Somit ist die Position des Spielers nach der Rotation eine andere!

 

Als Beispiel:

Ich stehe auf dem Würfel und Rotiere nun.

Richtig wäre, ich stehe immer noch auf dem Würfel, nur ist mein Kopf auf dem Würfel und die Beine in der Luft.

Falsch ist, ich bin jetzt unter dem Würfel.

 

Um das mal so zu sagen, es funktioniert, wenn ich einfach sage, dass der Spieler 180 Grad um die Z-Achse rotiert wird, sobald R gedrückt wird. Ich möchte das aber Animiert haben, damit der Spieler nicht die Orientierung verliert. Auf dem Weg, wie ich das gemacht habe, kollidiert es mit meiner anderen Rotation. Wenn es also eine Möglichkeit gibt, den Spieler über Zeit (1s) zu rotieren, auf einen Input, ohne meine andere Rotation um die Y-Achse dauerhaft zu stören, ist das die Lösung.

 

Nochmals aber Danke für die Unterstützung.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ah... vielleicht habe ich dich jetzt besser verstanden. Meine Idee war leicht anders. Der Würfel ist ja hier an einer bestimmten Stelle in der Map. Mein Vorschlag war, dass der Würfel (der dann keiner mehr wäre, sondern ein leeres GameObject mit Script(s)) das Root-GameObject des Spieler ist. Du bewegst also nicht die Kapsel, sondern den Würfel, als Spielfigur durch die Gegend. Die Bewegungsrichtung ist allerdings von der untergeordneten Kapsel abhängig, die du um ihre lokale Y-Achse drehst.

Eine andere Idee, die ich gerade hatte, ist: Du speicherst die Blickrichtung, zum Beispiel als float (Drehung um die Y-Achse) in deinem Script. Anstatt die Transform-Komponente zu beeinflussen oder ihre Drehung gar auszulesen, änderst du in jedem Frame diesen float-Wert in Abhängigkeit des Inputs. Zusätzlich hast du einen Wert dafür, inwiefern der Spieler kopfüber ist. Die Rotation der Spielfigur berechnest du jeden Frame komplett neu aus diesen beiden Werten.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Am 9.1.2019 um 22:29 schrieb Sascha:

Ah... vielleicht habe ich dich jetzt besser verstanden. Meine Idee war leicht anders. Der Würfel ist ja hier an einer bestimmten Stelle in der Map. Mein Vorschlag war, dass der Würfel (der dann keiner mehr wäre, sondern ein leeres GameObject mit Script(s)) das Root-GameObject des Spieler ist. Du bewegst also nicht die Kapsel, sondern den Würfel, als Spielfigur durch die Gegend. Die Bewegungsrichtung ist allerdings von der untergeordneten Kapsel abhängig, die du um ihre lokale Y-Achse drehst.

Eine andere Idee, die ich gerade hatte, ist: Du speicherst die Blickrichtung, zum Beispiel als float (Drehung um die Y-Achse) in deinem Script. Anstatt die Transform-Komponente zu beeinflussen oder ihre Drehung gar auszulesen, änderst du in jedem Frame diesen float-Wert in Abhängigkeit des Inputs. Zusätzlich hast du einen Wert dafür, inwiefern der Spieler kopfüber ist. Die Rotation der Spielfigur berechnest du jeden Frame komplett neu aus diesen beiden Werten.

Die 2. Idee hätte ich so ähnlich schon Probiert. Da hätte ich Probleme mit dem Time.deltatime, jedoch klingt die erste wirklich perfekt für mich. 

Leider fällt es mir gerade schwer zu verstehen, wie ich aus der Rotation des untergeordneten Objekts die Bewegungsrichtung des übergeordneten Objekts beeinflusse. 

 

Ich habe folgendes Skript, welches meine Spielfigur bewegt. Zusätzlich habe ich einen float-Wert, aus dem anderen Script, welcher mir die gewünschte Rotation um die Y-Achse gibt: mouseRotation.y_Rotation.

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

[RequireComponent(typeof(CharacterController))]
public class FPS_CharacterController : MonoBehaviour {

    public float speed = 5f;
    public float jumpSpeed = 7f;
    public float gravity = 20.0f;

    private Vector3 moveDirection = Vector3.zero;
    private bool groundedB = false;
    private bool groundedA = false;

    public FPS_MouseRotation mouseRotation;

    void FixedUpdate() {
        if (groundedB || groundedA) {
            moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
            moveDirection = transform.TransformDirection(moveDirection);
            moveDirection *= speed;

            if (Input.GetButton("Jump"))
            moveDirection.y = jumpSpeed;
        }

        moveDirection.y -= gravity * Time.deltaTime;

        CharacterController controller= GetComponent<CharacterController>();
        CollisionFlags flags = controller.Move(moveDirection * Time.deltaTime);
        groundedB = (flags & CollisionFlags.CollidedBelow) != 0;
        groundedA = (flags & CollisionFlags.CollidedAbove) != 0;
    }
}

Ich muss das also irgendwie auf meine moveDirection drauf rechnen, richtig?

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

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

×
×
  • Neu erstellen...