Rotating an NPC to face the Player Character

In the game we're creating, the PC can approach various NPCs and initiate a text-based conversation with them. What i'd like to do is when the player starts a conversation with an NPC, have that NPC turn to face the player. I've got it half working: The NPC successfully rotates the first time but not any time after that, despite calling my rotateTowards function from within Update(). I thought it was a to do with my use of triggers (the player would have to exit the trigger for it to update, I thought), but i'm now using a raycast and it still exhibits the same problem.

The relevant excerpt from the player interaction script:

if (Input.GetButtonDown("Interact")) {

        if(!npcDialogue.isTalking){
            print("I am attacking");
            GetComponent(playerCombat).performAttack();
        }

        var hit : RaycastHit;

        // if we cast a ray forward and it hits something
        if(Physics.Raycast(transform.position, transform.forward, hit)){

            if(hit.collider.gameObject.tag == "npc"){
                currentNPC = hit.collider.gameObject;

                var dist = Vector3.Distance(currentNPC.transform.position, transform.position);

                if(dist <= talkProximity){
                    print("I am talking to "+currentNPC.name);
                    currentNPC.GetComponent(npcDialogue).startConversation();
                }
            }
        }
    }

The NPC dialogue script:

var myName : String;
var myDialogue : String[];
private var currentLine : int = 0;
static var isTalking : boolean = false;

var myRespawn : GameObject;
private var player : GameObject;
var rotationSpeed = 3.0;

// artificial gravity since we are not using a rigidbody
var gravity = 20.0;
// variable to store the player's current forward direction (set to 0,0,0 at initialisation)
private var moveDirection = Vector3.zero;

function Start(){
    player = GameObject.Find("Player Character");
}

function Update(){
    if(isTalking){
        RotateTowards(player.transform.position);
        print("Called rotate");
    }

// Subtract the value of gravity once a second to bring the player back down to the ground
    moveDirection.y -= gravity * Time.deltaTime;
    // Move the controller
    // store a reference to the CharacterController component of this object in a variable called 'controller'
    var controller : CharacterController = GetComponent(CharacterController);

    // move the controller along the heading specified by moveDirection and in metres per second (store this movement in a variable called 'flags')
    var flags = controller.Move(moveDirection * Time.deltaTime);
}

function startConversation(){
    if(!isTalking){
        currentLine = 0;
        dialogueGUI2.mySpeaker = myName;
        dialogueGUI2.showDialogue = true;
        isTalking = true;
        moveChar.allowMove = false;
    } else {
        if(currentLine < myDialogue.Length-1){
            currentLine++;
        } else {
            isTalking = false;
            dialogueGUI2.showDialogue = false;
            moveChar.allowMove = true;
            player.GetComponent(respawnControl).saveProgress(myRespawn);
        }
    }

    dialogueGUI2.myDialogue = myDialogue[currentLine];

}

function RotateTowards (position : Vector3) {

    position.y = 0;
    //var targetRotation = Quaternion.LookRotation(position - transform.position, Vector3.up);
    var targetRotation = Quaternion.LookRotation(position);
    transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);

}

I assume you want to do something like what the sentry gun does on the FPS tutorial, which is something like this:

function Update () {
    if (target == null)
        return;

    if (!CanSeeTarget ())
        return;

    // Rotate towards target    
    var targetPoint = target.position;
    var targetRotation = Quaternion.LookRotation (targetPoint - transform.position, Vector3.up);
    transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 2.0);

    // If we are almost rotated towards target - fire one clip of ammo
    var forward = transform.TransformDirection(Vector3.forward);
    var targetDir = target.position - transform.position;
    if (Vector3.Angle(forward, targetDir) < shootAngleDistance)
        SendMessage("Fire");

Notice that by using this function you don't even need to use raycast. The shootAngleDistance variable is inicially set to 10.0 and the target variable is a public Transform which is the player.

I hope that helps!

So simply subtracting the NPC's position from the player's position has fixed it.

function RotateTowards (position : Vector3) {

    position.y = 0;
    var myPosition = transform.position;
    myPosition.y = 0;

    var targetRotation = Quaternion.LookRotation(position - myPosition);
    transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);

}

However, there seems to be an issue with registering a raycast hit to initiate a conversation. Even with a large box collider, it doesn't always register the hit. Works fine on a simple cube primitive. Anyone have any ideas?

couldn't u make a script that would just activate a 'Smooth Lookat' script on the NPC, put it in an `OnTriggerStay()` function and make the target the player? simples.