Quaternion.RotateTowards Problem

Hi all, I’m trying to beef up the following script to work for Diablo style movement:

http://wiki.unity3d.com/index.php/Click_To_Move_C

One of the problems I’m running into is in adding in smooth rotating for the character. Currently he’ll instantly snap to face wherever the cursor points.

Instead of the line: myTransform.rotation = targetRotation;

I want to do myTransform.rotation = Quaternion.RotateTowards(myTransform.rotation, targetRotation, rotatespeed)

Now this works in the held down “else if” statement - if the player holds down the button it works smoothly. However if the player just clicks once (first “if” statement) it’ll run through and loop back on update faster than the character can smoothly move to face his direction.

I tried hooking up this line outside of those if statements but I got weird results … I had to define targetRotation outside of the if statements and ran into some problems with that - “conflicts with a declaration in a child block”

I’ve uploaded my script below. I think what I’m trying to do is pretty straightforward, I’m just lacking the skill in the syntax to implement it properly. I want the character to continue to rotate to face the destination even if the player just clicks once.

Any help is very much appreciated!

using UnityEngine;
using System.Collections;

    public class moveOnMouseClick2 : MonoBehaviour {
    private Transform myTransform;          // this transform
    private Vector3 destinationPosition;     // The destination Point
    private float destinationDistance;        // The distance between myTransform and destinationPosition

    public float moveSpeed;                 // The Speed the character will move
    public float rotateSpeed;
    public float tolerance = 0f;

    private Quaternion targetRotation;



    void Start () {
       myTransform = transform;                 // sets myTransform to this GameObject.transform
       destinationPosition = myTransform.position;      // prevents myTransform reset
    }

    void Update () {

       // keep track of the distance between this gameObject and destinationPosition
       destinationDistance = Vector3.Distance(destinationPosition, myTransform.position);

          if(destinationDistance < 1f){     // To prevent shakin behavior when near destination
              moveSpeed = 0;
          }
          else if(destinationDistance > 1f){       // To Reset Speed to default
              moveSpeed = 3;
          }

       // Moves the Player if the Left Mouse Button was clicked
       if (Input.GetMouseButtonDown(0) GUIUtility.hotControl ==0) {

         Plane playerPlane = new Plane(Vector3.up, myTransform.position);
         Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
         float hitdist = 0.0f;

         if (playerPlane.Raycast(ray, out hitdist)) {
          Vector3 targetPoint = ray.GetPoint(hitdist);
          destinationPosition = ray.GetPoint(hitdist);

          Quaternion targetRotation = Quaternion.LookRotation(targetPoint - transform.position);

         }
         Debug.Log ("CLICKED!");
       }

       // Moves the player if the mouse button is hold down
       else if (Input.GetMouseButton(0) GUIUtility.hotControl ==0) {

         Plane playerPlane = new Plane(Vector3.up, myTransform.position);
         Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
         float hitdist = 0.0f;

         if (playerPlane.Raycast(ray, out hitdist)) {
          Vector3 targetPoint = ray.GetPoint(hitdist);
          destinationPosition = ray.GetPoint(hitdist);

          Quaternion targetRotation = Quaternion.LookRotation(targetPoint - transform.position);

         }
       }

       // To prevent code from running if not needed


       myTransform.rotation = Quaternion.RotateTowards(myTransform.rotation, targetRotation, rotateSpeed * Time.deltaTime);


       if(destinationDistance > tolerance){
         myTransform.position = Vector3.MoveTowards(myTransform.position, destinationPosition, moveSpeed * Time.deltaTime);
       }
    }
}

Hmm the interesting thing is you have “private Quaternion targetRotation;” as a class variable and also another one in the if statement… The one in the “if” should only work inside the if, and probably that’s why you’re getting weird results. Why not just update the class variable in the if?

Thanks!

Wow… yeah I just had to turn this:

Quaternion targetRotation = Quaternion.LookRotation(targetPoint - transform.position);

to this:

targetRotation = Quaternion.LookRotation(targetPoint - transform.position);

in the “if” blocks…

man…that’s what happens when you teach yourself how to code - sometimes simple stuff like this slips past. Thanks!