Raycast Not Accurately Tracking

Me AGAIN…sorry, but you guys are great!

So, this time I’m trying to get my enemy to look at my player. I have tried all kinds of scripts but for some reason I can not get this thing to rotate on it’s y axis to face the players transform.position

So I tried to use the raycast script using the players transform.position as the point to cast the ray, but this is what I get…

The blue ray is the one for my player script, accurately casting to a point defined by the mouse position. The red ray is supposed to track the player then orient the enemy towards it…

So, in the end I think I’m overcoding a fairly simple thing. I have tried things like transform.LookAt(new Vector3(player.transform.position.x, transform.position.y, player.transform.position.z); and enemyRb.AddForce((player.transform.position - transform.position).normalized * speed); because at the end I want the enemy to move in the direction of the player always. Nothing. With the second one I got this back and forth effect, moving on the z but never the x and never rotating. That’s why I went raycast because it worked for my player.

Here is my enemy script currently (corresponding with the photo above)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyController : MonoBehaviour
{
    public float speed;
    private GameObject player;
    private Rigidbody enemyRb;
    private Camera mainCamera;

    // Start is called before the first frame update
    void Start()
    {
        enemyRb = GetComponent<Rigidbody>();
        player = GameObject.Find("Player");
        mainCamera = Camera.main;
    }

    // Update is called once per frame
    void Update()
    {
        Ray cameraRay = mainCamera.ScreenPointToRay(player.transform.position);
        Plane ground = new Plane(Vector3.up, Vector3.zero);
        float rayLength;

        if (ground.Raycast(cameraRay, out rayLength))
        {
            Vector3 pointToLook = cameraRay.GetPoint(rayLength);
            Debug.DrawLine(cameraRay.origin, pointToLook, Color.red);

            // Makes the enemy face the direction of intersection

            transform.LookAt(new Vector3(pointToLook.x, transform.position.y, pointToLook.z));
        }
    }
}

Thanks in advance guys!

mainCamera.ScreenPointToRay is convert a Screen Point to a ray in world space
but player.transform.position is not a Screen Point to begin with so the whole thing just work with the wrong return result.

do you really need ray?
does this do the job?

void Update()
{
        Vector3 lookDir = new Vector3(player.transform.position.x, transform.position.y, player.transform.position.z);
        transform.LookAt(lookDir, Vector3.up);
}

that (..., Vector3.up) might have been what I was missing. I will try tomorrow. I have tried just LookAt a Vector3 –

essentially the same just without the cleanup of declaring a variable. That caused no movement. And, no, I actually didn’t want the raycast, just used it because LookAt.Vector3 wasn’t working for some strange reason.

Ughhh! It was late last night, I should have just gone to bed. I saw the problem this morning. I had added an empty GameObject to the scene to hold the player gameobjects (body, faceplate, arms) and named it Player. Problem is my movement script was attached to the PlayerCap gameObject. so the tracking was perfect. The “Player” was just standing still while it’s body moved around. Lol!

EDIT – I should clarify. Not tracking as in raycast tracking. I meant the script you suggested caused the enemy to track the players movements fine. This is the end result –

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyController : MonoBehaviour
{
    public float speed;
    private GameObject player;


    // Start is called before the first frame update
    void Start()
    {
        player = GameObject.Find("Player");
    }

    // Update is called once per frame
    void Update()
    {
        Vector3 lookDir = new Vector3(player.transform.position.x, transform.position.y, player.transform.position.z);
        transform.LookAt(lookDir, Vector3.up);
       
    }
}

and just as you predicted it was a simple 2 line code. :wink:

1 Like

in case transform.LooAt didn’t work well when you implement some kind of rigidbody moment
i have look at target sample here that cover many way of doing it including rigidbody.MoveRotation for Interpolate rigidbody.

[RequireComponent(typeof(Rigidbody))]
public class LookAtMePlz : MonoBehaviour
{
    public Transform target;

    public UpdateType updateType = UpdateType.update;
    public RigidBodyRotationAPI rigidBodyRotationAPI = RigidBodyRotationAPI.rotation;
    public RotationAPIOptions rotationAPIOptions = RotationAPIOptions.tran_LookAt;

    Rigidbody rb;

    public enum RotationAPIOptions
    {
        tran_LookAt, tran_QuaternionLookRot, rb_QuaternionLookRot, tran_QuaternionAngleAxis, rb_QuaternionAngleAxis,
        tran_QuaternionEuler, rb_QuaternionEuler, tran_eulerAnglesVector3, tran_localEulerAnglesVector3
    }

    public enum UpdateType
    {
        update, fixedUpdate
    }

    public enum RigidBodyRotationAPI
    {
        rotation, moveRotation
    }

    private void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void Update()
    {
        if(updateType == UpdateType.update)
        {
            ProcessRotationLookAtAPI();
        }
    }

    private void FixedUpdate()
    {
        if (updateType == UpdateType.fixedUpdate)
        {
            ProcessRotationLookAtAPI();
        }
    }

    private void ProcessRotationLookAtAPI()
    {
        switch (rotationAPIOptions)
        {
            case RotationAPIOptions.tran_LookAt:
                {
                    Vector3 lookDir = new Vector3(target.position.x, transform.position.y, target.position.z);

                    transform.LookAt(lookDir, Vector3.up);
                }
                break;
            case RotationAPIOptions.tran_QuaternionLookRot:
                {
                    Vector3 lookDir = target.position - transform.position;
                    lookDir.y = transform.position.y;
                    Quaternion result = Quaternion.LookRotation(lookDir, Vector3.up);

                    transform.rotation = result;
                }
                break;
            case RotationAPIOptions.rb_QuaternionLookRot:
                {
                    Vector3 lookDir = target.position - transform.position;
                    lookDir.y = transform.position.y;
                    Quaternion result = Quaternion.LookRotation(lookDir, Vector3.up);

                    if (rigidBodyRotationAPI == RigidBodyRotationAPI.rotation)
                    {
                        rb.rotation = result;
                    }
                    else
                    {
                        rb.MoveRotation(result);
                    }
                }
                break;
            case RotationAPIOptions.tran_QuaternionAngleAxis:
                {
                    Vector3 lookDir = target.position - transform.position;
                    float angle = Mathf.Atan2(lookDir.z, lookDir.x) * -Mathf.Rad2Deg; //calculate the invert of an angle
                    Quaternion result = Quaternion.AngleAxis(angle + 90, Vector3.up);//right axis pointing at target by default plus 90 for for forward pointing at target

                    transform.rotation = result;
                }
                break;
            case RotationAPIOptions.rb_QuaternionAngleAxis:
                {
                    Vector3 lookDir = target.position - transform.position;
                    float angle = Mathf.Atan2(lookDir.z, lookDir.x) * -Mathf.Rad2Deg; //calculate the invert of an angle
                    Quaternion result = Quaternion.AngleAxis(angle + 90, Vector3.up);//right axis pointing at target by default plus 90 for for forward pointing at target

                    if (rigidBodyRotationAPI == RigidBodyRotationAPI.rotation)
                    {
                        rb.rotation = result;
                    }
                    else
                    {
                        rb.MoveRotation(result);
                    }
                }
                break;
            case RotationAPIOptions.tran_QuaternionEuler:
                {
                    Vector3 lookDir = target.position - transform.position;
                    float angle = Mathf.Atan2(lookDir.z, lookDir.x) * -Mathf.Rad2Deg; //calculate the invert of an angle
                    Quaternion result = Quaternion.Euler(0,angle + 90, 0);//right axis pointing at target by default plus 90 for for forward pointing at target

                    transform.rotation = result;
                }
                break;
            case RotationAPIOptions.rb_QuaternionEuler:
                {
                    Vector3 lookDir = target.position - transform.position;
                    float angle = Mathf.Atan2(lookDir.z, lookDir.x) * -Mathf.Rad2Deg; //calculate the invert of an angle
                    Quaternion result = Quaternion.Euler(0, angle + 90, 0);//right axis pointing at target by default plus 90 for for forward pointing at target

                    if (rigidBodyRotationAPI == RigidBodyRotationAPI.rotation)
                    {
                        rb.rotation = result;
                    }
                    else
                    {
                        rb.MoveRotation(result);
                    }
                }
                break;
            case RotationAPIOptions.tran_eulerAnglesVector3:
                {
                    Vector3 lookDir = target.position - transform.position;
                    float angle = Mathf.Atan2(lookDir.z, lookDir.x) * -Mathf.Rad2Deg; //calculate the invert of an angle
                    Vector3 result = new Vector3(0, angle + 90, 0);//right axis pointing at target by default plus 90 for for forward pointing at target

                    transform.eulerAngles = result;
                }
                break;
            case RotationAPIOptions.tran_localEulerAnglesVector3:
                {
                    Vector3 lookDir = target.position - transform.position;
                    float angle = Mathf.Atan2(lookDir.z, lookDir.x) * -Mathf.Rad2Deg; //calculate the invert of an angle
                    Vector3 result = new Vector3(0, angle + 90, 0);//right axis pointing at target by default plus 90 for for forward pointing at target

                    transform.localEulerAngles = result;
                }
                break;
        }
    }
}

this is just standard version without smooth implement
if want to some kind of smooth feel free to ask me.

6980702–823589–LookAtMePlz.cs (6.27 KB)

I am going to be completely honest. Half of that code is still a foreign language to me. I just started with Unity about 6 weeks ago, with next to little background with languages like Visual Basic and JavaScript, and I haven’t studied the mathematical concepts of Euler angles, Quaternions, and the like. Furthermore, much of the jargon and solutions are still alien to me as well. I will learn though, and I will start by trying to figure out that 155 line beast up there :smile:

Just be patient with me and thank you!!!

its a all might look at target sample script only focus the part between case and break that where the magic happen:smile: