2016-07-05 32 views
0

Ich habe etwas für eine Weile versucht, und kann nicht herausfinden, warum es nicht funktioniert. Ich habe einen einfachen Pfad leerer Objekte in einem PathHolder-Elternobjekt und ein Zeichenobjekt, das diesem Pfad folgt und sich glatt dreht, um dem Punkt zu begegnen, auf den es hinweist. Mein Problem ist, dass die Hälfte der Zeit, das Charakter-Objekt, nicht den ganzen Weg dreht und sich dennoch auf den Punkt zubewegt, wie es sein sollte. Die andere seltsame Sache ist, dass die Bewegung des Punktes verringert, wie viel das Objekt drehen wird, und wenn es weiter bewegt, wird der Charakter tatsächlich dem Punkt gegenüberstehen. Der Pfad muss jedoch so flexibel sein, dass er in jeder Situation funktionieren kann. Daher kann ich nicht zulassen, dass die Entfernung die Rotation beeinflusst.Quaternion.LookRotation Winkel funktioniert nicht richtig

Idealerweise möchte ich, dass der Charakter vollständig und sanft in Richtung des Punktes rotiert, wenn die Pfeiltaste gedrückt wird, damit der Charakter nicht mitten in der Drehung festsitzt, wenn der Spieler den Schlüssel loslässt. Hier ist der Code, den ich bisher habe:

using UnityEngine; 
using System.Collections; 

public class CharacterControllerPath : MonoBehaviour 
{ 
    enum Direction {Forward, Backward}; 
    Direction charDirection; 

    public PathEditor pathToFollow; 

    private Vector3 targetPosition; 

    public string pathName; 
    public int wayPointID = 0; 
    public float speed; 
    public float rotationSpeed = 7.0f; 

    private float reachDistance = 1.0f; 
    private float distanceX; 
    private float distanceY; 

    void Start() 
    { 
     transform.position = new Vector3(pathToFollow.pathObj[wayPointID].transform.position.x, transform.position.y, pathToFollow.pathObj[wayPointID].transform.position.z); 
     charDirection = Direction.Forward; 
     Vector3 targetPosition = new Vector3(pathToFollow.pathObj[wayPointID + 1].transform.position.x, transform.position.y, pathToFollow.pathObj[wayPointID + 1].transform.position.z); 
     transform.LookAt(targetPosition); 
    } 

    void FixedUpdate() 
    { 
     Movement(); 
    } 

    void Movement() 
    { 
     if(Input.GetKey(KeyCode.RightArrow)) 
     { 
      charDirection = Direction.Forward; 

      //Move 
      targetPosition = new Vector3(pathToFollow.pathObj[wayPointID].transform.position.x, transform.position.y, pathToFollow.pathObj[wayPointID].transform.position.z); 
      transform.position = Vector3.MoveTowards(transform.position, targetPosition, speed * Time.deltaTime); 

      //Rotate 
      targetPosition = new Vector3(pathToFollow.pathObj[wayPointID].transform.position.x, 0, pathToFollow.pathObj[wayPointID].transform.position.z); 
      var rotation = Quaternion.LookRotation(targetPosition); 
      transform.rotation = Quaternion.Slerp(transform.rotation, rotation, speed * Time.deltaTime); 

      if(transform.position.x == targetPosition.x && transform.position.z == targetPosition.z) 
       wayPointID++; 
     } 
     else if(Input.GetKey(KeyCode.LeftArrow)) 
     { 
      charDirection = Direction.Backward; 

      //Move 
      targetPosition = new Vector3(pathToFollow.pathObj[wayPointID - 1].transform.position.x, transform.position.y, pathToFollow.pathObj[wayPointID - 1].transform.position.z); 
      transform.position = Vector3.MoveTowards(transform.position, targetPosition, speed * Time.deltaTime); 

      //Rotate 
      targetPosition = new Vector3(pathToFollow.pathObj[wayPointID - 1].transform.position.x, 0, pathToFollow.pathObj[wayPointID - 1].transform.position.z); 
      var rotation = Quaternion.LookRotation(targetPosition); 
      transform.rotation = Quaternion.Slerp(transform.rotation, rotation, speed * Time.deltaTime); 

      if(transform.position.x == targetPosition.x && transform.position.z == targetPosition.z) 
       wayPointID--; 
     } 

     if(wayPointID >= pathToFollow.pathObj.Count) 
     { 
      //Put code to finish the level 
      wayPointID = (pathToFollow.pathObj.Count - 1); 
     } 
     else if(wayPointID <= 0) 
      wayPointID = 0; 
    } 
} 
+0

Ich nehme an, dass die Punkte in 'pathToFollow' zu Weltrelativ sind? Wenn du möchtest, dass ein Charakter in diese Richtung schaut, musst du sicherstellen, dass du einen Vektor gibst, der relativ zu diesem Charakter ist. – rutter

+0

Vielen Dank für Ihre schnelle Antwort! Aber ich bin mir nicht sicher, ob ich wirklich verstehe, was Sie sagen. Haben Sie ein Beispiel dafür? – Septos

+0

niemals Quaternionen aus irgendeinem Grund in Unity verwenden. Verwenden Sie einfach "LookAt" https://docs.unity3d.com/ScriptReference/Transform.LookAt.html – Fattie

Antwort

0

Wenn Sie einen Vektor sanft zwischen zwei Vektoren zu bewegen, verwenden Sie

Vector3.Lerp(firstPosOrRotation, secondPosOrRotation, Time.deltaTime*Input.GetInputRaw("Horizontal")*speed); 

Input.GetInputRaw („horizontal“) wird nur ein Wert zwischen - 1 und 1 abhängig von den gedrückten Pfeiltasten. Jetzt erhalten Sie einfach jeden Punkt und den nächsten Punkt im Pfad und Lerp zwischen ihnen.

  • bearbeiten Für Rotation anstelle des Time.deltaTime und all das, tun dies

    Rotation = Vector3.Lerp (rotationA, rotationB, Mathf.Clamp (dist (pos, finalPos), 0, 1);

    dist (po, finalPos) = Menge gereist zwischen Punkt A und B

I hoffen, dies ist klar en ough, Ich bin mir nicht sicher, ob du das meinst oder ob das Objekt auf dem Pfad nach vorne zeigen soll.

+0

Vielen Dank für Ihre Antwort, aber wie erwähnt, funktioniert die Bewegung ganz gut und ich kann von einem Punkt zum anderen bewegen, das Problem ist, dass der Charakter manchmal nicht richtig mit meiner Quaternion konfrontiert ist.LookRotation(). Ich habe einen Pfad, der geradeaus geht, dann rechts, dann links, und der Charakter folgt ihm einfach durch Drücken des rechten Pfeils. Wenn er sich jedoch zum ersten Punkt hin bewegt, dreht sich der Charakter nicht vollständig und liegt bei 232,52 Grad Winkel, dann nach diesem Punkt, wenn es sich zum nächsten Punkt wendet, ist es perfekt gegenüber. – Septos

+0

Okay, für die Position tue was ich gesagt habe, aber für die Rotation mach die Vector3.Lerp aber Time.deltaTime und all diese anderen Sachen mit wie weit sich das Objekt zwischen den beiden Wegpunkten bewegt hat und klemme das zwischen 0 und 1 –