Daniel Lip
Daniel Lip

Reputation: 11341

How can I check if the transform see the target ? And how to keep the transform looking at the target when moving the transform?

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

public class LookAtTarget : MonoBehaviour
{
    public Transform lookAt;
    public Vector3 defaultFacing;
    public float angleLimit = 60f;
    public float rotationDamping = 3f;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Using late update so animations don't overwrite my transform manipulations...
    void LateUpdate()
    {
        // For this example i'll be using the root objects forward vector as what i want to be my reference constraint vector.
        // You might want to use something else though.
        defaultFacing = transform.root.forward;

        // The direction from this transform, pointing at the look at target.
        Vector3 directionToLookAtTarget = lookAt.position - transform.position;


        float angle = Vector3.Angle(directionToLookAtTarget, defaultFacing);

        // Since i'm just using the root objects forward vector as a constraint, i can just use its rotation as my default rotation instead of calculation a Quaternion.LookAt.
        Quaternion defaultRotation = transform.root.rotation;
        // The look at rotation to the target if it were completely unrestrained.
        Quaternion lookAtCompleteRotation = Quaternion.LookRotation(directionToLookAtTarget);

        Quaternion finalRotation = Quaternion.identity;

        // If the angle is greater than our limit, return a rotation that is in the direction of the lookAtCompleteRotation but is limited to the angle we chose as a limit.
        // Otherwise, if its within our limit, we just return the rotation as is.
        if (angle > angleLimit)
            finalRotation = Quaternion.Euler(transform.forward);
        //finalRotation = Quaternion.Slerp(defaultRotation, lookAtCompleteRotation, angleLimit / angle);
        else
            finalRotation = lookAtCompleteRotation;

        transform.rotation = Quaternion.Slerp(transform.rotation, finalRotation, Time.deltaTime * rotationDamping);
    }
}

I have an object my player when I'm running the game and moving the target(lookAt variable) the player head is smoothly rotating looking at the target with the limitations.

but now I want to make more two things :

If there is an object that block the target then the player should stop looking at the target and I want somehow that only if the player can see the target then look at it so the player will not look at the target through a wall or a rock only if there is a direct look then the player should look at it.

To make that if I move the player around that the player will keep looking at the target depending on the conditions in the first rule but when I'm moving the player around to add a distance variable and if the player is inside the distance and moving around that he will keep looking at the target even if behind the target or from the sides. from any direction and if the player is too far stop looking at it.

Upvotes: 0

Views: 271

Answers (1)

MarekK
MarekK

Reputation: 438

You should use a method to detect if there is anything between you and an object you're looking at. The simplest way to do it is using Physics.Raycast. When it comes to checking the distance between the objects you should use Vector3.Distance.

if (Physics.Raycast(transform.position, lookAt.position, out hit, Mathf.Infinity, layerMask))
{
 // Do not look at
}
else
{
 // Do look at
}

Be aware that the raycasts are computation heavy so you should use layers and call it as infrequent as you can.

About the second condition - you should add proper conditions in code above using Vector3.Distance(transform.position, lookAt.position). Depending on the value you defined it should look at it or not.

Upvotes: 1

Related Questions