[Unity] Problem z obrotem obiektu - Quaternion + SmoothDamp 4266 2

O temacie

Autor Vezo_20

Zaczęty 15.11.2016 roku

Wyświetleń 4266

Odpowiedzi 2

Vezo_20

Vezo_20

Użytkownicy
posty3
ProfesjaKompozytor
  • Użytkownicy
Ostatnio postanowiłem, że krok po kroku zaprogramuję Third Person Controller bez użycia żadnych assetów z zewnątrz. Jestem jak na razie (dopiero) w trakcie pisania skryptu na zoom kamery od/do postaci. Chciałem go dopracować maksymalnie - oprócz ruchu w osi Z i Y, bardzo pragnąłem dodać obrót kamery w osi X. Niestety po napisaniu poniższego kodu, oś obrotu X ma wartość 180. Domniemuję, że jest to spowodowane moim brakiem wiedzy odnośnie Quaternionów, nie wiem po jakiego grzyba nie może być po prostu użyty tu zwykły Vector3 dla osi x, y, z. Musi być tu jeszcze w, którego istoty istnienia nie rozumiem.  :ayfkm: (Po zmianie jego wartości na przykładowo 180, kamera wariuje). Co mam poprawić, aby działało tak, jak powinno?  :hmmm:

using UnityEngine;
using System.Collections;

public class CharCamera : MonoBehaviour {

    //Zmienne odpowiedzialne za przybliżanie kamery:
    [Header("Zoom")]
    public Transform cam;
    public float minY = 1.15f;
    public float maxY = 9.0f;
    public float minZ = -4.0f;
    public float maxZ = -20.0f;
    public float minXRot = 0.0f;
    public float maxXRot = 15.0f;
    public float smoothTime = 0.4f;
    public float szybkosc = 0.4F;
    private float actualY = 2.0f;
    private float actualZ = -6.0f;
    private float actualXRot;
    private Vector3 speedTrans = Vector3.zero;
    private float speedRotX = 0.0f;

    void Update () {

        //Zoom && Smooth Zoom:
        if (Input.GetAxis("Mouse ScrollWheel") < 0) // forward
        {
            if(actualY < maxY)
                actualY = actualY + szybkosc * Mathf.Abs((maxY - minY) / (maxZ - minZ));
            if(actualZ > maxZ)
                actualZ = actualZ - szybkosc;
            if(actualXRot < maxXRot)
                actualXRot = actualXRot + szybkosc * Mathf.Abs((maxY - minY) / (maxZ - minZ));
        }
        if (Input.GetAxis("Mouse ScrollWheel") > 0) // back
        {
            if(actualY > minY)
                actualY = actualY - szybkosc * Mathf.Abs((maxY - minY) / (maxZ - minZ));
            if(actualZ < minZ)
                actualZ = actualZ + szybkosc;
            if (actualXRot > minXRot)
                actualXRot = actualXRot - szybkosc * Mathf.Abs((maxY - minY) / (maxZ - minZ));
        }

        Vector3 basicPosition = new Vector3(0, actualY, actualZ);
        float basicRotationX = actualXRot;
        Vector3 smoothPosition = Vector3.SmoothDamp(cam.localPosition, basicPosition, ref speedTrans, smoothTime);
        float smoothRotationX = Mathf.SmoothDamp(cam.localRotation.x, basicRotationX, ref speedRotX, smoothTime);
        cam.localPosition = smoothPosition;
        cam.localRotation = new Quaternion(smoothRotationX, 0, 0, 0);
    }
}

Z góry dziękuję za pomoc. ;)
 

inż. Avallach

inż. Avallach

Administrator
posty7662
Propsy5238
NagrodyV
ProfesjaProgramista
  • Administrator
Quaternionów nie zmienia się "ręcznie". Używaj przeznaczonych do tego metod. Quaternion to NIE jest wektor rotacji w 4 osiach wyrażonych w stopniach (0* - 360*) - takie osie są tylko trzy. To zupełnie inny sposób wyrażania kąta - i są bardzo ważne powody dla którego używa się go w grafice 3d, nawet jeśli jest nieintuicyjny dla ludzi. Nie musisz rozumieć co jest w środku - zapamiętaj tylko że da się go zamieniać z i na wektor trzech wartości w stopniach (kąty Eulera).

Użyj tej funkcji: https://docs.unity3d.com/550/Documentation/ScriptReference/Transform.Rotate.html

Podobnie nie powinieneś bezpośrednio zmieniać Transform.position - pomimo że to zwykły wektor. Jeśli chcesz otrzymać płynny ruch, w tym przypadku też używaj przeznaczonych do tego funkcji.

Vezo_20

Vezo_20

Użytkownicy
posty3
ProfesjaKompozytor
  • Użytkownicy
Kombinuję z Eulerem - Dziwny zrywany ruch kamery (znowu)
transform.Rotate(...) (w tym przypadku cam.Rotate(...)) - także nie działa jak powinno...
Nie wiem już sam, co jest dobrze, co źle, niby te funkcje rozumiem, ale jak przyjdzie coś zrobić, to nie potrafię wszystkiego ogarnąć. Może rzucam się za szybko na głęboką wodę. Chciałbym jednak dobrze zrozumieć czemu to nie działa i jak powinienem to napisać. (Przepraszam za małą ułomność, ale jak za coś się wezmę, to nie odpuszczę xD)
 


0 użytkowników i 1 Gość przegląda ten wątek.
0 użytkowników
Do góry