Search Unity

Quaternion.Slerp help (urgent, due date Saturday)

Discussion in 'Editor & General Support' started by lucidcoder, Apr 5, 2013.

  1. lucidcoder

    lucidcoder

    Joined:
    Mar 23, 2010
    Posts:
    138
    Hey guys, I'm coding a small space themed RTS-type project (which got really complicated, really quickly) and in my Unit script, in the portion of the code that has rotate to face a waypoint when the player selects a waypoint on the grid (always on the XZ plane, y always = 0), and Quaternion.Slerp seems to always face the same direction--or rather, it turns part of the way before coming to a stop and never fully completing the rotation.

    Line 107 is where the Slerp is performed. I'm not entirely sure what I'm doing wrong here, and I apologize for the messiness.

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public enum IFFAlignment {
    5.     friendly,
    6.     hostile,
    7.     pirate
    8. };
    9.  
    10. public enum Order {
    11.     blank, waypoint, attack, defend, fortify, follow, construct
    12. };
    13.  
    14. public class Unit : MonoBehaviour {
    15.    
    16.     public IFFAlignment alignment = IFFAlignment.friendly;
    17.    
    18.     [HideInInspector]
    19.     public bool selected = false;
    20.    
    21.     public AudioClip mouseoverSound;
    22.     public AudioClip selectSound;
    23.     public AudioClip deselectSound;
    24.     public AudioClip giveOrderSound;
    25.     public bool useFuel = false;
    26.     public int fuelUsage = 2;
    27.     public bool isCapitalShip = false;
    28.     public bool canConstruct = false;
    29.     public bool isImmobile = false;
    30.     public int maxMovementDistance = 50;
    31.     public float maxVelocity = 5.0f;
    32.     private float maxTurnVelocity = 0.5f;
    33.     public float accelerationRate = 1.0f;
    34.     public string type = "";
    35.     public int health = 100;
    36.     public int strength = 1;
    37.     private Color initialColor;
    38.     private Color friendlyColor = Color.green;
    39.     private Color unfriendlyColor = Color.red;
    40.     private Shader initialShader;
    41.     private bool overrideReset = false;
    42.     private GameObject CameraController;
    43.     private bool doInterpCheck = true;
    44.     private HUD hud;
    45.    
    46.     [HideInInspector]
    47.     public int fuel = 0;
    48.    
    49.     [HideInInspector]
    50.     public Order[] queue = new Order[6];
    51.    
    52.     [HideInInspector]
    53.     public int numOrders = 0;
    54.    
    55.     [HideInInspector]
    56.     public Transform[] transformQueue;
    57.     public GameObject[] gameobjectQueue;
    58.    
    59.     private UnitSelectionMode mode;
    60.     private bool allowMovement = true;
    61.     private bool successfullyRotated = false;
    62.  
    63.     [HideInInspector]
    64.     public float currentVelocity = 0.0f;
    65.    
    66.     // Use this for initialization
    67.     void Start () {
    68.         initialColor = renderer.material.color;
    69.         initialShader = renderer.material.shader;
    70.         CameraController = GameObject.Find ("Camera Controller");
    71.         hud = Camera.main.GetComponent<HUD>();
    72.         for (int i = 0; i < queue.Length; i++) {
    73.             queue[i] = Order.blank;
    74.         }
    75.         transformQueue = new Transform[queue.Length];
    76.         gameobjectQueue = new GameObject[queue.Length];
    77.     }
    78.    
    79.     // Update is called once per frame
    80.     void Update () {
    81.        
    82.         CameraController.GetComponent<CameraMovement>().mode = mode;
    83.        
    84.         string toprint = "";
    85.         for (int i = 0; i < transformQueue.Length; i++) {
    86.             if (transformQueue[i] != null) {
    87.                 toprint += transformQueue[i].position.ToString();
    88.                 toprint += ";";
    89.                 toprint += transformQueue[i].rotation.ToString();
    90.                 toprint += "$";
    91.             }
    92.         }
    93.        
    94.         //print (toprint);
    95.        
    96.         if (queue[0] == Order.waypoint) {
    97.             if (successfullyRotated) {
    98.                 currentVelocity = Mathf.Lerp(currentVelocity, maxVelocity, Time.deltaTime*accelerationRate);
    99.                 transform.Translate(Vector3.right*Time.deltaTime*currentVelocity);
    100.                 if (IsApproximately(transform.position.x, transformQueue[0].position.x, 5.0f)  IsApproximately(transform.position.z, transformQueue[0].position.z, 5.0f)) {
    101.                     currentVelocity = 0;
    102.                     successfullyRotated = false;
    103.                     transformQueue[0] = null;
    104.                     deleteFromQueue(0);
    105.                 }
    106.             } else {
    107.                 transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(transformQueue[0].position, Vector3.up), Time.deltaTime*maxTurnVelocity);
    108.                 print (Quaternion.LookRotation(transformQueue[0].position, Vector3.up));
    109.                 if (Quaternion.Angle(transform.rotation, Quaternion.LookRotation(transformQueue[0].position)) < 1.0f) {
    110.                     successfullyRotated = true;
    111.                 }
    112.             }
    113.         }
    114.        
    115.         if (mode == UnitSelectionMode.selectGrid  selected) {
    116.             if (Input.GetKey("space")) {
    117.                 mode = UnitSelectionMode.normal;
    118.                 Camera.main.audio.PlayOneShot (deselectSound);
    119.                 setHUDToDescription();
    120.             }
    121.            
    122.             if (Input.GetMouseButton(0)  allowMovement) {
    123.                 Camera.main.audio.PlayOneShot (giveOrderSound);
    124.                 giveOrder (Order.waypoint, gameObject, CameraController.GetComponent<CameraMovement>().gotoSelector.transform);
    125.                 mode = UnitSelectionMode.normal;
    126.             }
    127.            
    128.             if (Input.GetMouseButtonDown(0)  !allowMovement) {
    129.                 Camera.main.audio.PlayOneShot (deselectSound);
    130.             }
    131.            
    132.             if (Vector3.Distance (transform.position, CameraController.GetComponent<CameraMovement>().gotoSelector.transform.position) > maxMovementDistance) {
    133.                 CameraController.GetComponent<CameraMovement>().gotoSelector.renderer.material.color = Color.red;
    134.                 allowMovement = false;
    135.                 hud.SmallText = "Cannot move unit this far";
    136.             } else {
    137.                 CameraController.GetComponent<CameraMovement>().gotoSelector.renderer.material.color = Color.green;
    138.                 allowMovement = true;
    139.                 hud.SmallText = "Select where you want to send this ship.\n(Press Spacebar to cancel)";
    140.             }
    141.         }
    142.        
    143.         // These blocks highlight the ship when it's selected depending on its alignment
    144.         if (selected) {
    145.            
    146.             if (mode == UnitSelectionMode.normal) {
    147.                 setHUDToDescription();
    148.             }
    149.            
    150.             if (alignment == IFFAlignment.friendly) {
    151.                 renderer.material.color = friendlyColor;
    152.             } else {
    153.                 renderer.material.color = unfriendlyColor;
    154.             }
    155.            
    156.             renderer.material.shader = Shader.Find ("Self-Illumin/Bumped Specular");
    157.            
    158.             if ((CameraController.transform.position.x >= (transform.position.x-0.2f))  (CameraController.transform.position.x <= (transform.position.x+0.2f))  
    159.                 (CameraController.transform.position.z >= (transform.position.z-0.2f))  (CameraController.transform.position.z <= (transform.position.z+0.2f))
    160.                  doInterpCheck) {
    161.                 CameraController.GetComponent<CameraMovement>().currentSelection = null;
    162.                 doInterpCheck = false;
    163.             }
    164.         } else {
    165.             if (overrideReset) {
    166.                 renderer.material.color = initialColor;
    167.                 renderer.material.shader = initialShader;
    168.             }
    169.         }
    170.        
    171.     }
    172.    
    173.     void OnGUI () {
    174.         GUI.depth = 10;
    175.         // Show the list of possible orders
    176.         GUI.skin.font = Camera.main.GetComponent<HUD>().HUDSmallFont;
    177.         if (selected) {
    178.             // Show the order list
    179.             GUI.Box (new Rect (10,Screen.height-260,100,250), "Order Unit");
    180.             if (!isImmobile) {
    181.                 if (GUI.Button (new Rect (20,Screen.height-220,80,20), "Go To")) {
    182.                     if (mode != UnitSelectionMode.selectGrid) {
    183.                         mode = UnitSelectionMode.selectGrid;
    184.                         Camera.main.audio.PlayOneShot(mouseoverSound);
    185.                         CameraController.GetComponent<CameraMovement>().currentZoom = CameraController.GetComponent<CameraMovement>().zoomLevels.Length-1;
    186.                         hud.BigText = "Select Waypoint";
    187.                     } else {
    188.                         mode = UnitSelectionMode.normal;
    189.                         Camera.main.audio.PlayOneShot(deselectSound);
    190.                         setHUDToDescription();
    191.                     }
    192.                 }
    193.             } else if (isImmobile  canConstruct) {
    194.                 if (GUI.Button (new Rect (20,Screen.height-220,80,20), "Construct")) {
    195.                     giveOrder (Order.waypoint, gameObject, transform);
    196.                 }
    197.             }
    198.            
    199.             if (GUI.Button (new Rect (20,Screen.height-190,80,20), "Attack")) {
    200.                 // do nothing
    201.             }
    202.            
    203.             if (!isImmobile  !canConstruct) {
    204.                 if (GUI.Button (new Rect (20,Screen.height-160,80,20), "Defend")) {
    205.                     // do nothing
    206.                 }
    207.             } else {
    208.                 if (GUI.Button (new Rect (20,Screen.height-160,80,20), "Construct")) {
    209.                     // do nothing
    210.                 }
    211.             }
    212.            
    213.             if (GUI.Button (new Rect (20,Screen.height-130,80,20), "Fortify")) {
    214.                 // do nothing
    215.             }
    216.            
    217.             if (GUI.Button (new Rect (20,Screen.height-100,80,20), "Follow")) {
    218.                 // do nothing
    219.             }
    220.            
    221.             if (GUI.Button (new Rect (20,Screen.height-40,80,20), "Cancel All")) {
    222.                 // do nothing
    223.             }
    224.            
    225.             // Show the order queue
    226.             GUI.Box (new Rect (120,Screen.height-260,100,250), "Queue");
    227.             if (queue[0] != Order.blank) {
    228.                 if (GUI.Button (new Rect (130,Screen.height-220,80,20), getOrderName(0))) {
    229.                     currentVelocity = 0;
    230.                     successfullyRotated = false;
    231.                     deleteFromQueue(0);
    232.                     mode = UnitSelectionMode.normal;
    233.                 }
    234.             }
    235.            
    236.             if (queue[1] != Order.blank) {
    237.                 if (GUI.Button (new Rect (130,Screen.height-190,80,20), getOrderName(1))) {
    238.                     deleteFromQueue(1);
    239.                 }
    240.             }
    241.            
    242.             if (queue[2] != Order.blank) {
    243.                 if (GUI.Button (new Rect (130,Screen.height-160,80,20), getOrderName(2))) {
    244.                     deleteFromQueue(2);
    245.                 }
    246.             }
    247.            
    248.             if (queue[3] != Order.blank) { 
    249.                 if (GUI.Button (new Rect (130,Screen.height-130,80,20), getOrderName(3))) {
    250.                     deleteFromQueue(3);
    251.                 }
    252.             }
    253.            
    254.             if (queue[4] != Order.blank) { 
    255.                 if (GUI.Button (new Rect (130,Screen.height-100,80,20), getOrderName(4))) {
    256.                     deleteFromQueue(4);
    257.                 }
    258.             }
    259.            
    260.             if (queue[5] != Order.blank) { 
    261.                 if (GUI.Button (new Rect (130,Screen.height-70,80,20), getOrderName(5))) {
    262.                     deleteFromQueue(5);
    263.                 }
    264.             }
    265.         }
    266.     }
    267.    
    268.     void OnMouseDown() {
    269.         if (mode == UnitSelectionMode.normal) toggleSelection();
    270.     }
    271.    
    272.     void OnMouseEnter() {
    273.         overrideReset = false;
    274.         renderer.material.shader = Shader.Find ("Self-Illumin/Bumped Specular");
    275.         Camera.main.audio.PlayOneShot(mouseoverSound);
    276.         if (!selected || mode == UnitSelectionMode.selectUnit) hud.SmallText = "Unit Type: " + type;
    277.     }
    278.    
    279.     void OnMouseExit() {
    280.         overrideReset = true;
    281.         if (!selected) hud.SmallText = "No unit currently selected.";
    282.     }
    283.    
    284.     void toggleSelection() {
    285.         if (selected) {
    286.             selected = false;
    287.             CameraController.GetComponent<CameraMovement>().currentSelection = null;
    288.             renderer.material.color = initialColor;
    289.             doInterpCheck = true;
    290.             Camera.main.audio.PlayOneShot(deselectSound);
    291.             hud.BigText = "Select a Unit";
    292.             hud.SmallText = "No unit currently selected";
    293.         } else {
    294.             CameraController.GetComponent<CameraMovement>().currentSelection = transform;
    295.             selected = true;
    296.             Camera.main.audio.PlayOneShot(selectSound);
    297.             setHUDToDescription();
    298.         }
    299.     }
    300.    
    301.     public void deselect() {
    302.         selected = false;
    303.         CameraController.GetComponent<CameraMovement>().currentSelection = null;
    304.         renderer.material.color = initialColor;
    305.         doInterpCheck = true;
    306.         Camera.main.audio.PlayOneShot(deselectSound);
    307.         hud.BigText = "Select a Unit";
    308.         hud.SmallText = "No unit currently selected.";
    309.     }
    310.    
    311.     private bool deleteFromQueue(int index) {
    312.         if (index < 0 || index > queue.Length) {
    313.             print ("UNSUCCESSFUL");
    314.             return false;
    315.         }
    316.        
    317.         if (alignment == IFFAlignment.friendly) Camera.main.audio.PlayOneShot(deselectSound);
    318.        
    319.         print ("deleting:" + index);
    320.         queue[index] = Order.blank;
    321.         gameobjectQueue[index] = null;
    322.         transformQueue[index] = null;
    323.         int currentPos = index;
    324.         while (currentPos + 1 < queue.Length) {
    325.             queue[currentPos] = queue[currentPos+1];
    326.             gameobjectQueue[currentPos] = gameobjectQueue[currentPos+1];
    327.             transformQueue[currentPos] = transformQueue[currentPos+1];
    328.             currentPos++;
    329.         }
    330.        
    331.         currentPos = 0;
    332.         numOrders--;
    333.        
    334.         print ("SUCCESSFUL");
    335.         return true;
    336.     }
    337.    
    338.     public bool giveOrder(Order order, GameObject obj, Transform trans) {
    339.         if (numOrders+2 > queue.Length) {
    340.             print ("not giving order");
    341.             return false;
    342.         }
    343.        
    344.         if (alignment == IFFAlignment.friendly) Camera.main.audio.PlayOneShot(giveOrderSound);
    345.        
    346.         print ("giving order");
    347.        
    348.         queue[numOrders] = order;
    349.         gameobjectQueue[numOrders] = obj;
    350.         transformQueue[numOrders] = trans;
    351.        
    352.         numOrders++;
    353.        
    354.         return true;
    355.     }
    356.    
    357.     private string getOrderName(int index) {
    358.         return queue[index].ToString();
    359.     }
    360.    
    361.     private void setHUDToDescription() {
    362.         hud.BigText = type;
    363.         if (useFuel) {
    364.             hud.SmallText = "Hull: " + health + "% - Fuel: " + fuel + "%";
    365.         } else {
    366.             hud.SmallText = "Hull: " + health + "%";
    367.         }
    368.     }
    369.    
    370.     private bool IsApproximately(float a, float b, float tolerance) {
    371.         return Mathf.Abs(a - b) < tolerance;
    372.     }
    373. }
    374.  
    Any help?
     
  2. Niki.j

    Niki.j

    Joined:
    Oct 17, 2012
    Posts:
    157
    Hello Sigma...



    i have faced a same problem in my very 1st project,i think the problem is with the time limit,
    your rotation needs some time to rotate before start moving from one way point to another.
    so just provide some yield in rotation and movement....
    that is what i have done in my project....

    Niki.j