Unity 2018 - NPC smoothly turning to face the Player while within range

Multi tool use
Multi tool use


Unity 2018 - NPC smoothly turning to face the Player while within range



With the current code the NPC will detect the and turn towards the player with the desired animation playing. However, the NPC only snaps to face the player and does not continue to rotate as the player walks around the NPC while they are in range.



I would like to modify this so that the NPC consistently and smoothly turns to face the character while the player is in range of the collider. I figured it would have something to do within void update, but since the function to turn is currently in onTriggerEnter it's a little confusing to a beginner such as myself.


onTriggerEnter


public class helloTrigger : MonoBehaviour
{
public Animator anim;
public CharacterController player;
public Transform Player;

void Start()
{
player = GameObject.FindObjectOfType<CharacterController>();
anim = GetComponent<Animator>();
}

void OnTriggerEnter(Collider other)
{
if (other.tag != "Player") return;

anim.Play("Hello");
Vector3 lookAt = Player.position;
lookAt.y = transform.position.y;
transform.LookAt(lookAt);
}

void OnTriggerExit(Collider other)
{
if (other.tag == "Player")
{
anim.Play("Idle");
}
}
}





If you're not gonna use Update, then delete it. Unity, at compile time, creates a list of objects to call Update on if it is defined. Therefore, having Update when you aren't using it is bad for performance.
– AustinWBryan
Jul 2 at 2:10


Update


Update


Update




1 Answer
1



If you want a GameObject to face another GameObject smoothly, use Quaternion.LookRotation to calculate the destination rotation then use Quaternion.Lerp to lerp between the current rotation and the destination rotation calculated with Quaternion.LookRotation. Finally, do the lerping over time. See this post to understand how lerping over rotation work. You can do this in the Update function but I will use it in a coroutine function since it gives you more control.


Quaternion.LookRotation


Quaternion.Lerp


Quaternion.LookRotation


Update



A simple Look-at smoothly function:


IEnumerator LookAtSmoothly(Transform objectToMove, Vector3 worldPosition, float duration)
{
Quaternion currentRot = objectToMove.rotation;
Quaternion newRot = Quaternion.LookRotation(worldPosition -
objectToMove.position, objectToMove.TransformDirection(Vector3.up));

float counter = 0;
while (counter < duration)
{
counter += Time.deltaTime;
objectToMove.rotation =
Quaternion.Lerp(currentRot, newRot, counter / duration);
yield return null;
}
}



Your new script:


public class helloTrigger : MonoBehaviour
{
public Animator anim;
public CharacterController player;
public Transform Player;
Coroutine smoothMove = null;

// Use this for initialization
void Start()
{
player = GameObject.FindObjectOfType<CharacterController>();
anim = GetComponent<Animator>();
}

void OnTriggerEnter(Collider other)
{
if (other.tag == "Player")
{
anim.Play("Hello");
LookSmoothly();
}

}

void OnTriggerExit(Collider other)
{
if (other.tag == "Player")
{
anim.Play("Idle");
}
}

void LookSmoothly()
{
float time = 1f;

Vector3 lookAt = Player.position;
lookAt.y = transform.position.y;

//Start new look-at coroutine
if (smoothMove == null)
smoothMove = StartCoroutine(LookAtSmoothly(transform, lookAt, time));
else
{
//Stop old one then start new one
StopCoroutine(smoothMove);
smoothMove = StartCoroutine(LookAtSmoothly(transform, lookAt, time));
}
}

IEnumerator LookAtSmoothly(Transform objectToMove, Vector3 worldPosition, float duration)
{
Quaternion currentRot = objectToMove.rotation;
Quaternion newRot = Quaternion.LookRotation(worldPosition -
objectToMove.position, objectToMove.TransformDirection(Vector3.up));

float counter = 0;
while (counter < duration)
{
counter += Time.deltaTime;
objectToMove.rotation =
Quaternion.Lerp(currentRot, newRot, counter / duration);
yield return null;
}
}
}





Top Drawer!!! and helps me see how and why to use Coroutines, a little clearer. THANK YOU!!!
– Confused
Jul 2 at 7:35





Indeed! I wasn't sure what a coroutine was in the first place! Thank you!
– shinjabo
2 days ago






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

RFbeRi,Us er VX RTVUYi0,IJiyZ7h3daR,rgX
xXLbmGQ Kl3t7OZ,m Nrk rRN95JoILppKDX,rNQSfk

Popular posts from this blog

Rothschild family

Cinema of Italy