Need Help - 'Look at Target' - Rotating Objects on 'up' axis

I watched a tutorial that showed me how to get objects to rotate smoothly towards another ‘target’ object, but there I am getting some undesirable results and need some help fixing this…

So far, I have this basic script:

private var myTransform : Transform;
public var Target : Transform;
public var rotationSpeed=1;

function Awake(){
    myTransform = transform;
}

function Update(){
    //Make sure we have a target
    if(!Target){
        var go : GameObject = GameObject.FindGameObjectWithTag("Enemy");
        Target = go.transform;
    }
	Debug.DrawLine(Target.position,myTransform.position,Color.green);
    //Look at target
    myTransform.rotation = Quaternion.Slerp(myTransform.rotation,Quaternion.LookRotation(Target.position - myTransform.position),rotationSpeed * Time.deltaTime);
}

I have that script attached to an “NPCCube” and have some “EvilCubes” runnin around with the “Enemy” tag for my NPC to target. It works perfectly, the NPC picking the first target it finds and rotating to follow said enemy perfectly. Now, imagine both the enemy cube and NPC cube are a perfect “1 unit” cube. The above code works flawlessly. Now image we make the NPC cube be 2 units tall (Y axis)… Whenever an enemy cube gets close, the NPC cube tilts as if “looking down” at the enemy. For the game I am making, this is BAD… I need my NPC to never tilt downward or upward, but ONLY rotate on it’s vertical (Y) axis. Any ideas?

i generally wouldn’t capitalize any variables, try to reserve CamelCase for function definitions and camelCase for variables, its good practice.

I think its a little unnecessary to cache a reference to the transform component rather than using .transform, I don’t think it saves any cpu cycles (eg: instead of using myTransform, just use transform).

That said, I would do something like this:

var targetPos = target.position;
targetPos.y = transform.position.y; //set targetPos y equal to mine, so I only rotate on my own plane
targetDir = Quaternion.LookRotation(transform.position - targetPos);
transform.rotation = Quaternion.Slerp(transform.rotation, targetDir, rotationSpeed*Time.deltaTime);

Code works great, except you got the subtraction backwards:

targetDir = Quaternion.LookRotation(transform.position - targetPos);

Should be:

targetDir = Quaternion.LookRotation(targetPos - transform.position);

Otherwise the object “looks at” the target with their back side :stuck_out_tongue:

Thanks for the tips on camelCasing vs CamelCasing!

ahh my bad, wrote it off the cuff :slight_smile: glad to help!

Caching a transform is certainly a speed increase. Using gameObject.transform is analogous to calling GetComponent.

It’s mentioned a few times throughout the documentation, as well was emphasized in the old 2007 Unite video on performance tuning.

Interesting, I see it now. I didn’t realize it was just a shortcut for GetComponent; I wonder why you hardly ever see it done like that in standard assets and pretty much any page of the documentation besides the performance optimization page?

In something like a character controller in the standard assets, where you have only one in a game, the connivence far outweighs the dozen or so cpu cycles you might shave. Use the connivence properties in an iterative fashion over a large set, like in a boid controller, then you’ll notice it.