- Home /
transform.LookAt() function isn't working properly
First of all, greetings Unity community. This is my first post here. I'm a total beginner. I tried making a showroom, adapting the scripts from the "Stealth Project Tutorial" + what I could gather from the Documentation.
I want to make an Art-Gallery, where NPCs walk around staring at pictures. The NPCs walk through the assigned wayPoints. When they hit the picture collider, they stay for a couple of seconds looking at the picture. I've got everything working so far, except for them looking at the different pictures.
I've tried different solutions suggested here (unityAnswers), but so far nothing has worked.
I'd appreciate any help. Here is my code so far (you can ignore the Patrolling() function, since it was taken from the Stealth Project and should be correct):
public class NPCAI : MonoBehaviour
{
public bool pictureInSight;
public int StartAdmiration;
public int StopAdmiration;
public float angleBetween = 0.5f;
public float patrolSpeed = 2f;
public float patrolWaitTime = 1f;
public Transform[] patrolWayPoints;
//I've tried it with Transform and Gameobject, neither works
public Transform trans4;
public GameObject target1;
public GameObject target2;
public GameObject target3;
public GameObject target4;
private NavMeshAgent nav;
private float patrolTimer;
private int wayPointIndex;
private int targetIndex;
void Awake()
{
nav = GetComponent<NavMeshAgent>();
}
void Update()
{
if (pictureInSight == false)
{
Patrolling();
}
}
void Patrolling()
{
nav.speed = patrolSpeed;
if(nav.remainingDistance < nav.stoppingDistance)
{
patrolTimer += Time.deltaTime;
if(patrolTimer >= patrolWaitTime)
{
// ... increment the wayPointIndex.
if(wayPointIndex == patrolWayPoints.Length - 1)
wayPointIndex = 0;
else
wayPointIndex++;
// Reset the timer.
patrolTimer = 0;
}
}
else
patrolTimer = 0;
nav.destination = patrolWayPoints[wayPointIndex].position;
}
void OnTriggerEnter (Collider other)
{
if (other.gameObject == target1)
{
pictureInSight = true;
Debug.Log ("Collision with target1");
//This was my first try.
//The result is, that it rotates my NPC at a weird angle.[watch photo1]
/*transform.LookAt(trans1);*/
//I found this solution in the Forums. [watch photo2]
//The result, looks in a random direction, but NPC doesn't have a weird angle anymore
//if I do the same with x and z it makes no difference
var targetPos1 = target1.transform.position;
targetPos1.y = transform.position.y;
transform.LookAt(targetPos1);
Vector3 destination = target1.transform.position - transform.position;
angleBetween = Vector3.Angle(transform.forward, destination);
int admirationTime = (Random.Range(StartAdmiration, StopAdmiration));
Debug.Log ("Waiting time is");
Debug.Log(admirationTime);
Invoke("ResetValues", admirationTime);
}
if (other.gameObject == target2)
{
pictureInSight = true;
Debug.Log ("Collision with picture");
var targetPos2 = target2.transform.position;
targetPos2.y = transform.position.y;
targetPos2.z = transform.position.z;
transform.LookAt(targetPos2);
Vector3 destination = target2.transform.position - transform.position;
angleBetween = Vector3.Angle(transform.forward, destination);
int admirationTime = (Random.Range(StartAdmiration, StopAdmiration));
Debug.Log ("Waiting time is");
Debug.Log(admirationTime);
Invoke("ResetValues", admirationTime);
}
if (other.gameObject == target3)
{
pictureInSight = true;
Debug.Log ("Collision with picture");
transform.LookAt(target3.transform.position);
Vector3 destination = target3.transform.position - transform.position;
angleBetween = Vector3.Angle(transform.forward, destination);
int admirationTime = (Random.Range(StartAdmiration, StopAdmiration));
Debug.Log ("Waiting time is");
Debug.Log(admirationTime);
Invoke("ResetValues", admirationTime);
}
if (other.gameObject == target4)
{
pictureInSight = true;
Debug.Log ("Collision with target4");
transform.LookAt(new Vector3(trans4.position.x, transform.position.y, trans4.position.z));
Vector3 destination = target4.transform.position - transform.position;
angleBetween = Vector3.Angle(transform.forward, destination);
int admirationTime = (Random.Range(StartAdmiration, StopAdmiration));
Debug.Log ("Waiting time is");
Debug.Log(admirationTime);
Invoke("ResetValues", admirationTime);
}
}
void ResetValues()
{
pictureInSight = false;
Patrolling ();
//transform.LookAt (Vector3.zero);
}
}
PS: I know I should make arrays instead of drag&drop each target, but I tried and failed miserably. Thank you in advance. Best Regards.
Answer by ZeFirestarter · Apr 14, 2015 at 05:27 PM
Since I'm a retarded mofo, I just realized that the Animation script was conflicting with this NPC-AI script. Both scripts are on the NPCs. The "nav.updaterotation" was set to false, I changed it to true and now it doesn't tilt my NPCs anymore. But the NPCs were still looking in a random direction instead of the object they should be looking at. After that I tried it with Quaternion and giving the Vector3 like Cherno suggested and it worked.
Answer by Cherno · Apr 13, 2015 at 10:46 PM
It's possible that the pivot of the model doesn't conform to Unity's standard and hence while technically the LookAt function works right, effectively the models rotates the wrong way from a realism standpoint. Other than that, there's always the possibility to set one or more of the axes to zero immediately after calling LookAt:
transform.LookAt(trans1);
transform.rotation.eulerAngles = new Vector3(0f, transform.rotation.eulerAngles.y, 0f);
Note that the Scripting API for Transform.LooAt also states that the function accepts a Vector3 parameter "worldUp", so you can try passing it Vector3.up and see if that helps.
As for using arrays and collections:
Thank you for your help. I tried what you said with the eulerAngles, but it gives me the following error:
error CS1612: Cannot modify a value type return value of `UnityEngine.Transform.rotation'. Consider storing the value in a temporary variable
I already tried the Vector3.up, but it has no effect. I took the model and Animator from the S$$anonymous$$lth-Project, after what you said I tried with my own models. Still the same problem.
Thank you for your time and the links. I'll definitely check the arrays and collections wiki later.
Try this ins$$anonymous$$d:
transform.LookAt(trans1);
Quaternion q = transform.rotation;
q.eulerAngles = new Vector3(0f, transform.rotation.eulerAngles.y, 0f);
transform.rotation = q;
Also try Vector3.right, Vector3.forward, -Vector3.right etc.
Thank you very much Cherno. You got me thinking that I had to search for the problem outside of the script. I found out that the other script which animates the NPCs was conflicting with it.
I know this is old but this answer will help the community.