Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

LookAt Script

Discussion in 'Scripting' started by Jonathan Czeck, Apr 13, 2005.

  1. Jonathan Czeck

    Jonathan Czeck

    Joined:
    Mar 17, 2005
    Posts:
    1,713
    Here is a simple script that will make one object rotate towards another. Useful for cameras. It requires a Transform component on both.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class LookAt : MonoBehaviour
    6. {
    7.     public Transform lookAt;
    8.  
    9.     void FixedUpdate ()
    10.     {
    11.         Debug.DrawLine(lookAt.position, transform.position, Color.gray);
    12.  
    13.         Vector3 difference = lookAt.position - transform.position;
    14.         Quaternion rotation = Quaternion.LookRotation(difference, Vector3.up);
    15.         transform.rotation = rotation;
    16.     }
    17. }
    18.  
    -Jon
     
  2. NicholasFrancis

    NicholasFrancis

    Joined:
    Apr 8, 2005
    Posts:
    1,587
    To be really cool, try adding a smoothness parameter; instead of just assigning the rotation, use the Quaternion.Slerp function on the rotation
     
  3. Jonathan Czeck

    Jonathan Czeck

    Joined:
    Mar 17, 2005
    Posts:
    1,713
    Ah, yeah, I was a few steps ahead of your suggestion. :D

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class LazyLookAt : MonoBehaviour
    6. {
    7.     public Transform lookAt;
    8.     public float smooth = 5F;
    9.     public float lookAhead = 0F;
    10.  
    11.     Quaternion lastRotation;
    12.     Quaternion goalRotation;
    13.  
    14.     void FixedUpdate ()
    15.     {
    16.         Debug.DrawLine(lookAt.position, transform.position, Color.gray);
    17.  
    18.         Vector3 difference = lookAt.TransformPoint(new Vector3(lookAhead, 0F, 0F)) - transform.position;
    19.         Vector3 upVector = lookAt.position - lookAt.TransformPoint(Vector3.down);
    20.         goalRotation = Quaternion.LookRotation(difference, upVector);
    21.     }
    22.  
    23.     void Awake ()
    24.     {
    25.         lastRotation = transform.rotation;
    26.         goalRotation = lastRotation;
    27.     }  
    28.    
    29.     void LateUpdate ()
    30.     {
    31.         lastRotation = Quaternion.Slerp (lastRotation, goalRotation, smooth * Time.deltaTime);
    32.         transform.rotation = lastRotation;
    33.     }
    34.  
    35. }
    36.  


    -Jon
     
  4. Jonathan Czeck

    Jonathan Czeck

    Joined:
    Mar 17, 2005
    Posts:
    1,713
    Here is the most advanced one I ended up doing in my "exploration". Lately I've been working on other aspects of game development, so really I just need a decent idea that I'd be able to pursue in Unity. Being a lifelong musician, a lot of my thinking comes up with things that require Doppler effect, so I need to avoid those and brainstorm elsewhere at the moment.

    Anyhoo. Put this script on your camera:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class ChangableLookAt : MonoBehaviour
    6. {
    7.     public Transform lookAt;
    8.     public float smooth = 5F;
    9.  
    10.     Quaternion lastRotation;
    11.     Quaternion goalRotation;
    12.    
    13.     void FixedUpdate ()
    14.     {
    15.         if (lookAt != null)
    16.         {
    17.             Debug.DrawLine(lookAt.position, transform.position, Color.gray);
    18.  
    19.             Vector3 difference = lookAt.position - transform.position;
    20.             Quaternion rotation = Quaternion.LookRotation(difference, Vector3.up);
    21.             goalRotation = rotation;
    22.         }
    23.         else
    24.         {
    25.             goalRotation = lastRotation;
    26.         }
    27.     }
    28.  
    29.     void Update ()
    30.     {
    31.         if (Input.GetMouseButtonDown(0))
    32.         {
    33.             Ray ray = camera.ScreenPointToRay (Input.mousePosition);
    34.            
    35.             RayCollision coll = Dynamics.CastRay (transform.position, ray.direction, 100F);
    36.  
    37.             lookAt = null;
    38.  
    39.             if (coll != null)
    40.             {
    41.                 GOComponent goc = (GOComponent) coll.collider;
    42.                 FocusableObject fo = (FocusableObject) goc.GetComponent(typeof(FocusableObject));
    43.  
    44.                 if (fo != null)
    45.                 {
    46.                     lookAt = fo.transform;
    47.                 }
    48.  
    49.             }
    50.         }
    51.     }
    52.  
    53.     void Awake ()
    54.     {
    55.         lastRotation = transform.rotation;
    56.         goalRotation = lastRotation;
    57.     }  
    58.    
    59.     void LateUpdate ()
    60.     {
    61.         lastRotation = Quaternion.Slerp (lastRotation, goalRotation, smooth * Time.deltaTime);
    62.         transform.rotation = lastRotation;
    63.     }
    64. }
    65.  
    And put this script on any object you want the camera to be able to select and focus on:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class FocusableObject : MonoBehaviour
    6. {
    7.  
    8. }
    9.  
    Even though it is an empty class, it seems like the best way to accomplish this in Unity. Now you'll be able to click on objects to focus on them. Works great!

    -Jon
     
  5. NicholasFrancis

    NicholasFrancis

    Joined:
    Apr 8, 2005
    Posts:
    1,587
    Nice job...

    To expand it, you might want to consider rather than checking if the Game Object has a FocusableObject component, you could use Game Object tags (Edit->Project Settings->Game Object tags) Just add a line to 'Tags' in the inspector, and you can select the tag at the top of any game object in the scene...

    Also, you might be interested in going up the parenting chain and searching for focusable objects there, so you can just add Focusable to a root object and have it work for any of its children.
     
  6. marty

    marty

    Joined:
    Apr 27, 2005
    Posts:
    1,170
    Great scripts guys! Thanks for sharing.
     
  7. Vinícius Sanctus

    Vinícius Sanctus

    Joined:
    Dec 14, 2009
    Posts:
    282
    You work made my game possible! Thanks and if u ever want to see your work in action try my game!