Questions from a Unity newbie

I am quite new to game engine programming, coming from the animation/modelling end of the field. I recently found out about Unity, and realised this application is a great tool to finally get into interactive 3D. I have gone through a fair number of tutorials, and purchased a licence for Unity Pro.

What I am trying to put together at the moment has turned out to be not entirely straightforward, so I need some advice.
Imagine for example a car model that you can spin around in space by dragging over it with the mouse. The model will have hotspots that you can interact with: for example if you click on the bonnet, an animation is triggered that opens it up, and overlayered pop-up information appears. How would I go about doing this?

I found this “grabNRotate” java script by DannyJ in the Unity Web forum that took care of the spinning function (Thanks Danny!).

var numberAverages : int = 3; 

private var originalRotation : Quaternion; 
private var offsetRotation : Quaternion; 

// Make sure there is always a Rigidbody 
@script RequireComponent (Rigidbody) 
@script RequireComponent (SphereCollider) 


function Awake () { 
    
   numberAverages = Mathf.Clamp (numberAverages, 1, numberAverages); 
    
} 


function OnMouseDown () { 
   var hit : RaycastHit; 
   var dir : Vector3; 
    
   // Stop spinning 
   rigidbody.angularVelocity = Vector3.zero; 
    
   // Record initial variables 
   if (Physics.Raycast (camera.main.ScreenPointToRay(Input.mousePosition), hit)) { 
      originalRotation = transform.rotation; 
      dir = hit.point - transform.position; 
      offsetRotation = Quaternion.Inverse (Quaternion.LookRotation (dir)); 
      Spin (dir); 
   } 
} 


function Spin (dir : Vector3) { 
   var hit : RaycastHit; 
   var previousDirList : Array = new Array (); 
   var currentDir : Vector3; 
    
   // Initialize previous dir list 
   for (var i : int = 0; i < numberAverages; i++) { 
      previousDirList.Add (currentDir); 
   } 
    
   currentDir = dir; 
    
   // Make the object rotate with the cursor while we are grabbing it 
   while (Input.GetButton ("Fire1")  Physics.Raycast (camera.main.ScreenPointToRay(Input.mousePosition), hit)) { 
      // Remove first element of the array 
      previousDirList.RemoveAt (0); 
      // Add current dir to the end 
      previousDirList.Add (currentDir); 
      currentDir = hit.point - transform.position; 
      transform.rotation =  Quaternion.LookRotation (currentDir) * offsetRotation * originalRotation; 
      yield; 
   } 
    
   // User let go of the mouse so make the object spin on its own 
   var avgPreviousDir : Vector3 = Vector3.zero; 
   for (dir in previousDirList) { 
      avgPreviousDir += dir; 
   } 
   avgPreviousDir /= numberAverages; 
   Kick (currentDir, avgPreviousDir); 
} 


function Kick (r2 : Vector3, r1 : Vector3) { 
   var linearVelocity : Vector3; 
   var angVelocity : Vector3; 
    
   // Calculate the angular velocity:  omega = r x v / r^2 
   linearVelocity = (r2 - r1) / Time.deltaTime; 
   rigidbody.angularVelocity = Vector3.Cross (r2, linearVelocity) / r2.sqrMagnitude; 

}

To achieve the hotspot funcionality I have tried adding child objects (cubes) with simple test scripts attached to them (for example switching a colour on mouseDown), but they become inactive when parented to the main object (the sphere), and furthermore they inherit the grabNRotate behavior instead.

Another couple of problems I have encountered with the grabNRotate script:

  1. When I build a Windows standalone, it works differently on different computers. On some, the object goes on spinning on its own (as it should) when you drag off the object/let go of the mouse, on others the object will only rotate with the mouse drag movement and stops when you let go. My guess is that that this is java script related, but I haven’t been able to find any setting that rectifies it.
    I should mention that the functionality is fine when I test it in the editor.

  2. I have also tried using a mesh collider instead of the sphere collider, but this results in occasional rapid shivering/vibrating movements of the object when you drag.

I know, I am very much a programming newbie, so please bear with me. Maybe there are some basic bits that I have missed.
Any suggestions/hints/pointers in the right direction would be really appreciated!

Cheers,
Mats Bjorklund,
Melbourne, Australia

Well just to get you started (although i haven’t even run this script yet) here are my thoughts.

First note that Game objects receive an OnMouseDown event when the ray Unity casts into the scene hits its collider. Also only the first game object with a collider that is hit is sent the event.

Because this script uses a sphere collider, to make this script work for your give situation I think you’re going to have to use unity’s layers. You’ll need to put all your car parts on a layer then on a right mouse click (i.e. Fire2) do a ray cast against all the objects in the car layer. If your ray hits a car part then you could just call some script’s function on that car part to perform the required animation.

Hope it helps a bit.

Many thanks for your suggestions Damien!
I will look into this and see where it takes me.

Cheers,
Mats

Hello !

Do you think you can send me the project file ?
I need to study it !

Thank you

Just want to let you know I have sorted out the problem with differentiating parent and child actions.
Just needed to add rigid body components to the children, I only had that on the main (parent) object before, resulting in all the colliders turning into a compound collider.

The other two problems (with the grabNRotate script) remain.

Cheers,
Mats