See if object is in field of view and how far from the center of the screen

I’m coding an AI and I want them to take cover based on a calculated risk.
Every AI has a raycast at the center of their head, I want to see how far the selected cover is from that center and if it is in the field of view, is it possible?

EDIT: One more question.

When the AI is walking to a waypoint and it sees the player its rotation gets messed up and it keeps rotating, how can I prevent that? I’m using LookAt at the moment but can I fix this by using transform.rotation? If yes how?

first one: should be, have a look at Vector3.angle Unity - Scripting API: Vector3.Angle

second one, going to need to see code for that…

Uhm it’s not working I think, it’s returning a value based on the distance

Vector3 targetDirection = target.transform.position - transform.position;
        float angle = Vector3.Angle(targetDirection, Vector3.forward);
        Debug.Log(angle);

The dot product of the agent’s normalized forward vector and the normalized vector of the agent to the cover point will tell you how much he is “facing” the cover point - essentially telling you if it’s front of him, next to him, or behind him.

Could you explain that in simple words? :stuck_out_tongue:

he’s referring to: Unity - Scripting API: Vector3.Dot

you don’t want to use Vector3.forward in the arguments for Vector3.angle… use transform.forward (i.e. the forward facing of the transform, not “global” forward").

It works fine but there’s still a problem, I tested it on the player and when the object is behind me the value is > 0, when I’m looking at his side and it’s not in the fov it’s lower than 0.

A value less than 0 means that it is behind him. A value of exactly 0 means that it is perpendicular to him. You’ll have to decide what your FOV is and test against a value within the -1 to 1 range that represents that value. There is a diagram in the Vector Cookbook in the manual that gives you some of those values. You can probably find it in wiki entries for Dot Products as well.

I still can’t get it to work :frowning: even tried raycast

You’re going to have to be more specific than that.

Values are not correct, if the object is in front of the AI sometimes it’s negative, and if it’s behind him it’s negative as well.

This is the dot product way, not sure if it is correct though

Vector3 objectNormalized = Vector3.Normalize(transform.position);
Vector3 targetNormalized = Vector3.Normalize(target.position);
Vector3 forward = transform.TransformDirection(transform.forward);
Vector3 pos = targetNormalized - objectNormalized.position;

EDIT: I inverted the pos values(updated the code) and now it’s negative when the object is behind him but still when it’s on his side and he can’t see it the value is positive.

If a your actor is heading another target u can take a look at andeeees post:

private bool IsHeading(Vector3 pTargetPosition)

        {
var direction = pTargetPosition - transform.localPosition;
           var headingN = pDirection.normalized;
            var sightN = transform.forward.normalized;
            var dot = Vector3.Dot(headingN, sightN);
            return (dot > 0.5f && dot <= 1.0f);
        }

By the way I wouldn’t raycast for coverObstacles permanently. Hold a List of coverObstacle transforms and ask them via lazy update for the nearest e.g. top 5 obstacles via sort by actor position (just use the magnitude). Then run through those until a raycast hits one of them.

Alright, I will try later. I’m trying to fix the field of view at the moment.

yep, just use the method above.

Er - that’s not how you calculate directions :slight_smile:

Vector3 toTarget = (coverObject.transform.position - agent.transform.position).normalized;
if (Vector3.Dot(agent.transform.forward, toTarget) > 0)
{
    // cover object is in front of agent
}
else
{
    // cover object is behind agent
}

Oh, it’s fine now, thanks :stuck_out_tongue:

@KelsoMRK how do I determine if agent is directly in front, or directly behind? When I test, my dot product values are all over the place, sometimes directly in front = 6, sometimes, its 23, etc.

Here is how I am getting the dot product:

float UpdateAndGetHeadingDotProduct()
 {
    _Heading = transform.GetChild(0).transform.position - mainCam.transform.position;
    return Vector3.Dot(mainCam.transform.forward, _Heading);
 }

This is a thread from TEN YEARS AGO.

If you want the Dot product to give you meaningful information about the angle, you need to normalize the vectors you give it. A transform.forward is already normalized, so line 5 needs _Heading.normalized.

Directly in front would give values approaching 1.

1 Like

Why does it matter how old the thread is? I found the thread, it was useful, and I had another question. Why waste a new post? Anywho, thanks, that fixed my issue.

Because

  • it raises old topics in the search ranks
  • the old conversations ping all the people who chatted on the topic years ago
  • the old conversations include people who have not been around for years
  • they include solutions which have long been deprecated, or are plain wrong
  • they include features or problems of Unity which have drastically changed over the years
  • those people who answer these threads instead of tacking on new questions don’t like it
  • everyone else starts arguing over all the wrong information instead of your new question
  • it’s super easy to post your own fresh new thread with none of this baggage
2 Likes