Search Unity

How Rotate Object in Path

Discussion in 'Scripting' started by bear_love_honey, May 27, 2015.

  1. bear_love_honey

    bear_love_honey

    Joined:
    Jan 7, 2015
    Posts:
    31
    Hello i have this simple script.

    Code (CSharp):
    1.     public BaseShip Ship { get; set; }
    2.     public float MoveSpeed { get; set; }
    3.  
    4.     public IEnumerator Movement()
    5.     {
    6.         while (Ship.PathPosition.Count > 0 && Ship.Speed >= 0)
    7.         {
    8.             Vector3 currentPos = new Vector3(Ship.PathPosition.First().PosX, 0, Ship.PathPosition.First().PosZ);
    9.             Vector3 startPos = new Vector3(Ship.PositionX, 0, Ship.PositionZ);
    10.  
    11.             this.gameObject.transform.position = Vector3.Lerp(this.gameObject.transform.position, currentPos, MoveSpeed * Time.deltaTime);
    12.             float checkDist = Vector3.Distance(this.gameObject.transform.position, currentPos);
    13.  
    14.          
    15.             var direction = (currentPos - startPos);
    16.             Quaternion targetRotation = Quaternion.LookRotation(direction.normalized);
    17.  
    18.             while (Quaternion.Angle(this.gameObject.transform.rotation, targetRotation) > 0.05f)
    19.             {
    20.                 yield return new WaitForEndOfFrame();
    21.                 this.gameObject.transform.rotation = Quaternion.Lerp(this.gameObject.transform.rotation, targetRotation, MoveSpeed * Time.deltaTime);
    22.             }
    23.  
    24.             if (Vector3.Distance(this.gameObject.transform.position, currentPos) < 0.05f)
    25.             {
    26.                 Ship.PositionX = Ship.PathPosition.First().PosX;
    27.                 Ship.PositionZ = Ship.PathPosition.First().PosZ;
    28.  
    29.                 this.gameObject.transform.position = currentPos;
    30.                 Ship.PathPosition.Remove(Ship.PathPosition.First());
    31.                 Ship.Speed--;
    32.             }
    33.  
    34.             yield return null;
    35.         }
    36.     }
    This script move and rotate object ( in simple tile grid system ). This work nice but i get one problem.
    When i move object left right or bottom and if he at start look on path ( left right or bottom ) he rotate two times. But in end he every time get true position, but this never happend if i move object on top.
    I put this simple 44 sec video. For show my problem because i think i write some wrong.




    I think my problem in compare Angles but i dont have idia what i doing wrong, i'll try mass solutions but no one help.

    Please help me guys.

    Sorry my bad engl.
     
  2. steego

    steego

    Joined:
    Jul 15, 2010
    Posts:
    969
    Not entirely sure this is what's causing this, but you are using Lerp wrong. Use RotateTowards instead.

    Instead of this

    Code (csharp):
    1. this.gameObject.transform.rotation = Quaternion.Lerp(this.gameObject.transform.rotation, targetRotation, MoveSpeed * Time.deltaTime);
    Try doing this

    Code (csharp):
    1. this.gameObject.transform.rotation = Quaternion.RotateTowards(this.gameObject.transform.rotation, targetRotation, MoveSpeed * Time.deltaTime);
     
  3. bear_love_honey

    bear_love_honey

    Joined:
    Jan 7, 2015
    Posts:
    31
    Thanks dude, but RotateTowards doing the same effect ( but most slowly ).

    My problem wheni'll try move object and he look left, right or bot, he at first rotate on top and after this rotate left right or top.

    This problem never happend if object look on top and i move him on top.
     
  4. steego

    steego

    Joined:
    Jul 15, 2010
    Posts:
    969
    Try logging the value of Quaternion.Angle then.

    Just increase your MoveSpeed. Lerp should not be used with deltaTime, but with a value changing from 0 to 1.
     
  5. Jodon

    Jodon

    Joined:
    Sep 12, 2010
    Posts:
    434
    Have a bit of a feeling it's actually your while statement up top, with you not only checking if you have a move, but the speed... My guess is it completes the move then the speed is not less than zero and it goes through again.
     
    zoeyducoeur likes this.
  6. bear_love_honey

    bear_love_honey

    Joined:
    Jan 7, 2015
    Posts:
    31
    I resolve this problem.
    The problem was in Astar. Every time when i calculate new path for ship, first slot include ship position.
    When i refactor my Astar path finding code and remove ship position from him i resolve this problem.

    Because every time when i compare first slot in Astar with gameObject position he calculate wrong angle.

    Thanks All.
     
  7. IsGreen

    IsGreen

    Joined:
    Jan 17, 2014
    Posts:
    206
    Test this another one:

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class PathScripts : MonoBehaviour {
    6.  
    7.     public Transform PathPosition;
    8.     public Transform Ship;
    9.  
    10.     public float smoothTime = 0.2f;
    11.     public float rotationTime = 0.05f;
    12.  
    13.     Vector3 velocity = Vector3.zero;
    14.     Vector3 rotation = Vector3.zero;
    15.    
    16.     // Update is called once per frame
    17.     void Update () {
    18.  
    19.         Vector3 currentPos = new Vector3(PathPosition.position.x, 0f, PathPosition.position.z);
    20.         Vector3 startPos = new Vector3(Ship.position.x, 0f, Ship.position.z);
    21.  
    22.         Ship.position = Vector3.SmoothDamp(startPos, currentPos, ref velocity, smoothTime);
    23.         Vector3 direction = (currentPos - startPos).normalized;
    24.  
    25.         if(direction != Vector3.zero){
    26.  
    27.             Ship.rotation = Quaternion.LookRotation(Vector3.SmoothDamp(this.transform.forward,
    28.                                                                                            direction,
    29.                                                                                            ref rotation,
    30.                                                                                            rotationTime));
    31.  
    32.         }
    33.    
    34.     }
    35.  
    36. }
    37.  
    38.