I have an NPC who can “wander” from an origin point.

Blue is the origin

Yellow is the “npc”

Red is the radial limit the NPC can travel within

I want to be able to take the NPC’s (yellow) current position and generate directions (2D, ignore the Y axis) all around it. However, the directions must have a length that does not extend outwards from - say - 20 studs from the origin (Blue).

I do not want the NPC to be able to wander outside the circle (20 studs) from the center origin.

Given

local origin = Vector2.new(10,10)
local currentPosition = Vector2.new(15,0)
local maxRadiusAroundOrigin = 20

How can I generate a set of directions around the currentPosition that have lengths that would not extend 20 studs past the origin? The amount of directions generated is arbitrary. I will choose to generate 5 or 100 directions around the currentPosition. That part doesn’t matter.

You could have some code which checks the magnitude between the orginpart and the NPC’S torso if the magnitude between them is greater then 100 (as the radius) then it’ll move back to the circle. This might not work but here’s an example.

if (game.Workspace.NPC.Torso.Position - game.Workspace.OrginPart.Position).magnitude >= distance then
game.Workspace.NPC.Humanoid:MoveTo(game.Workspace.OrginPart.Position)

I’d like to have a mathematical solution that doesn’t rely on this because I have about 100 NPCs utilizing this and I’d rather not have to check them every certain amount of time while they are moving. I’ll keep this in mind if I absolutely can’t find a solution though.

local radius = 8;
local function getDirections(n,point,center)
local directions = {};
for i=0,n,1 do
local angle = i / n * math.pi * 2
local yDist = math.sin(angle) * radius
local zDist = math.cos(angle) * radius
local edgePoint = center + Vector3.new(yDist,center.y,zDist);
directions[#directions + 1] = (edgePoint - point) -- If you want the length to the edge, take the magnitude of this
end
return directions
end

Not necessarily. There is a relationship between a point in the circle and the edge from the origin. I just haven’t figured it out yet. That way I could tell the NPC where to go without going out of the circle. The exact point where to go.

You might want to look into parabolic functions and the equations of an ellipse/circle then. These would give actual functions for the values of the ellipse, and you can use an inequality to get the set of points which satisfy the equation within that ellipse or circle.

This code will allow an NPC to wander around themself, but not outside the bounds of their origin. It works by generating wanderpoints, and checking if they are within range of the origin. If it fails to find a point 10 times, the NPC will likely need to be reset.

local NPC_HumanoidRootPart = script.Parent.NPC
local spawnOrigin = Vector3.new(0,0,0) --script.Parent.SpawnLocation.Position
local rng = Random.new()
local tau = math.pi*2
local MAX_WANDER_RANGE = 30 -- Studs from origin
local WANDER_DISTANCE = 12 -- Distance from current location that NPC can wander
local AVERAGE_WANDER_WAIT = 7 -- NPC decides to wander this often on average
local WANDER_LOCATION_ATTEMPTS = 10 -- How many attempts NPC will try to find a wander point before resetting.
while true do
wait(AVERAGE_WANDER_WAIT * rng:NextNumber(.5,1.5))
local wanderPoint = nil
for i=1, WANDER_LOCATION_ATTEMPTS do
-- wanderPointAttempt = NPC current location + (random angle * random distance)
local wanderPointAttempt = NPC_HumanoidRootPart.Position + (
CFrame.Angles(0,tau*rng:NextNumber(0,1),0) * CFrame.new(0,0,(rng:NextNumber(0,1)^.5)*WANDER_DISTANCE)
).p
-- Check if new point is inside of originRange
if (spawnOrigin-wanderPointAttempt).magnitude < MAX_WANDER_RANGE then
wanderPoint = wanderPointAttempt
break -- No more attempts, we've found a valid point
end
end
if wanderPoint then
--todo: move NPC to wanderPoint
else
--todo: unable to find a wanderpoint. Either reset NPC or have them walk to origin.
end
end

If you do not care about the NPC wandering around itself, then you could simply choose random points inside of the origin. With this method, you don’t need to use any kind of attempts since all points would be valid. Just use the code that generates a point around the NPC to generate a point around the origin instead.

Does it matter if the directions are perfectly divided by x degrees around npc or not?

If not then just generate a random postition within radius from center then calculate direction using that point. (This would favour walking towards the center rather than the edge tho)