Making random movement AI?

I’m trying to make AI that will move around a players ‘tycoon base’ just at random. Almost all videos/wiki pages, etc. On AI focus on pathfinding, but none of them show you how to make the AI actually just move to random spots within a squared area. I’ve thought about maybe using BodyGyro or BodyPosition but not entirely sure what I am doing.

Any help would be greatly appreciated :slight_smile:

8 Likes

given that you know how to pick the position/vector3 values so that they are within the desired place, you could use a Humanoid’s MoveTo method to tell it to go towards a certain point, or Move method which makes them go in a direction rather than at a target

3 Likes

Another method is for the humanoid to have a 10 stud limit on movement distance. It will of course check if the movement is out of the desired zone.

2 Likes
local character = script.Parent
local humanoidRootPart = character:WaitForChild('HumanoidRootPart')
local humanoid = character:WaitForChild('Humanoid')

local base = character.Parent.Parent.Base

local step = 2

while wait(step) do
	humanoid:Move(Vector3.new(math.random(base.Position.X), 0, math.random(base.Position.Z)))
end

This is what I wrote up. AI moves, but just picks a direction and runs until they fall of the map. Base is the players Tycoon area btw (So I only want the AI to stay within that area)

2 Likes

given that you have the base part, I’d use MoveTo with given points like this

while wait(step) do
    humanoid:MoveTo(
        (base.CFrame * 
        CFrame.new(
            math.random(-base.Size.x,base.Size.x),
            humanoid.HipHeight,
            math.random(-base.Size.z,base.Size.z),
        )).p
    )
end

the code has been split in lines so that it is easier to see, but it should be doable in one line
one issue I can see with this is if the “base” part has an unusual rotation, let us say, 90 degrees in either x or z axis

3 Likes

Seems to be working a lot better!

Small problem, is on the odd occasion, some of them drift off onto the brown part. The base part is the green (light green, there are darker green spots on top of the base, which I’ll eventually have it so the AI can only walk on the light green grass, instead off all of the grass) But yeah, I don’t know why they drift into the brown area. It’s not common, but still a noticeable amount do it

EDIT Is there also a way of making them stand still for a period? Atm they just run around constantly. Would just setting their walkspeed to 0 be the best way of accomplishing this?

NVM I tried, and they just don’t walk (guessing it’s setting their walkspeed to 0 before they reach the set spot)

1 Like
local character = script.Parent
local humanoidRootPart = character:WaitForChild('HumanoidRootPart')
local humanoid = character:WaitForChild('Humanoid')

local base = character.Parent.Parent.Base

local walkTime = math.random(3, 5)
local waitTime = math.random(1, 3)

while true do
humanoid:MoveTo((base.CFrame * CFrame.new(math.random(-base.Size.x,base.Size.x), humanoid.HipHeight, math.random(-base.Size.z,base.Size.z)).p))
	wait(walkTime)
	humanoid.WalkSpeed = 0
	wait(waitTime)
	humanoid.WalkSpeed = 10
end

Edited code to have them stop walking and walk for random periods of time each. Noticed that they seem to still fall off the base as well, as well as walking on the brown part

2 Likes

Is the area you wish for them to walk on rotated? If so, the specific coordinates won’t work how you intend for them to work.

Also, this is much nicer IMO
local base = character.Parent.Parent.Base
local sizeX,sizeZ = base.Size.X / 2, base.Size.Z / 2

while true do
humanoid:MoveTo(base.Position + Vector3.new(math.random(-sizeX, sizeX), 0, math.random(-sizeZ, sizeZ))

2 Likes

Yeah it is rotated. What coordinates would I use to make it work on the rotation (each base has different rotations, so needs to work for all of those)

1 Like

@Zarkonan_Zenheart @aramix273 bump

1 Like

I used position based on a CFrame value so that it accounts for the base’s rotation, and only downside to that is if it’s rotated and resized in a way that I didn’t expect, which I suppose is not
if you use MoveTo method, and not Move, then it should move strictly to that position and then stop when the humanoid reached that position
if I overlooked something in my example above, is that an npc might sometimes decide to move on the edge of the base and might fall from that, so I’d change it into something like

local dis = 5 – minimum distance from edges of base
humanoid:MoveTo((base.CFrame * CFrame.new(math.random(-base.Size.x+dis,base.Size.x-dis), humanoid.HipHeight, math.random(-base.Size.z+dis,base.Size.z-dis)).p))

1 Like

Forgive me if my solution is not the most elegant. I’ve not messed around with CFrames for a while and I moved away from vectors in my further maths module so :smile: it might be awful

From everything I’ve seen, you understand the problem. The rotation of the part doesn’t affect the translation of the random size, and that’s the issue.

local sizeX, sizeZ = base.Size.X/2, base.Size.Z/2
local randomDisplacement = Vector3.new(math.random(-sizeX, sizeX), 0, math.random(-sizeZ, sizeZ))
humanoid:MoveTo(base.CFrame:vectorToWorldSpace(randomDisplacement) + base.Position)

If you’ve a basic understanding of scripts, I hope these lines of code help you to achieve your aim :slight_smile:

2 Likes


AI still walking off the green :confused:

1 Like

another thing I noticed is that I didn’t divide the base.Size.x or base.Size.z by 2, since it will count from the center of the base

local dis = 5 – minimum distance from edges of base
humanoid:MoveTo((base.CFrame * CFrame.new(math.random(-base.Size.x/2+dis,base.Size.x/2-dis), humanoid.HipHeight, math.random(-base.Size.z/2+dis,base.Size.z/2-dis)).p))

thanks to @Zarkonan_Zenheart since that example does so

2 Likes

I’m glad to have done something useful haha. I forgot that mutliplying a CFrame with another CFrame is the same as a translation in object space. Thanks for the reminder :slight_smile:

2 Likes