Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Honestly I'm not sure where to start with my viewcones?

Asked by
AmVolt 60
9 years ago

I'm not asking for anybody to do anything for me, but I just need a place to learn how to figure out this problem. I'm making a viewcone for AI - basically I attached parts to a humanoids face - and I need to make a script where when the viewcone hits any block it restrains its length all the way up to the block. This is similar to the physics of lighting, when it hits an object it does not pass through. I need this function because I want to make a stealth-based game where you can hide behind an object. Where do I start? Should I use lighting functions instead of blocks? Thank you.

Here is an amazing example: https://gyazo.com/e2c3e2d90e842c12096e50aa1fbdd93a

1 answer

Log in to vote
1
Answered by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
9 years ago

You don't need to think about it as "restraining" the cone against walls.

You can use raycasting combined with simple vector math to see if a point is visible in a cone. Then you can just check the Head.Position and Torso.Position to see if either is "visible" from the cone.


Step One: Cone

Let's define a Cone that has a position, a direction, and an angle (in radians).

We want to ask if a point is insideCone cone:

function insideCone(cone, point)

A cone is defined by all the lines coming from the cone's Origin that are within cone.angle of the cone.direction. Thus we can just ask if the line from cone.position to point is within cone.angle of cone.direction.

You can compute the direction from cone.point to point as just point - cone.point, and throw in a .unit to normalize (ignore distance):

    local direction to = (point - cone.point).unit

There's a handy formula for dealing with angles (for unit vectors): a:Dot(b) == math.cos( angle ) Thus if we want them to be closer than angle, we want a:Dot(b) to be at least math.cos(angle):

    local cosAngle = to:Dot( cone.direction.unit )
    return cosAngle > math.cos( cone.angle )
end

Step Two: Visible

If it's in the cone, we also want to know whether or not the point is visible -- is any object blocking it?

If something is blocking point, then there is an object along the line from cone.position to point. We can ask what is along that ray using raycasting:

function pointVisible(cone, point)
    local Ray = Ray.new(cone.position, (point - cone.position) )
    local _, where = workspace:FindPartOnRay(point)
    return (where - point).magnitude < 0.5
end

You can use FindPartOnRayWithIgnoreList to filter objects out that you don't mind "blocking" the view (a big thing to remember is the thing looking, itself -- you don't want its view blocked by its own hands or hat)

Step Three: Profit

These two functions together can tell you whether or not a point is visible inside a cone:

function visible(cone, point)
    return pointVisible(cone, point) and insideCone(cone, point)
end
0
Thank you. AmVolt 60 — 9y
Ad

Answer this question