Moving Models to Random Positions Not Working

I am trying to move Animals (Model Objects) to a random Position on a Part.

The problem is that I think the rotation of the part can mess with the positions, and some Animals move outside of the Part. (Probably because of the rotation of the part)

I looked for any posts about this but I didn’t find any.

Here’s the current algorithm:

self:StartMovement(Vector3.new(
    math.random(math.ceil(self.SPAWN_PLATFORM.CFrame.Position.X - self.SPAWN_PLATFORM.Size.X/2), math.floor(self.SPAWN_PLATFORM.CFrame.Position.X + 
self.SPAWN_PLATFORM.Size.X/2)),

    self.MODEL.PrimaryPart.CFrame.Position.Y,

math.random(math.ceil(self.SPAWN_PLATFORM.CFrame.Position.Z - self.SPAWN_PLATFORM.Size.Z/2), math.floor(self.SPAWN_PLATFORM.CFrame.Position.Z + self.SPAWN_PLATFORM.Size.Z/2))
))

I think if someone can make the Animals move on the part with the part at any rotation will fix the problem, but I’m not 100% sure.

1 Like

Changed Vector3.new() to CFrame.new() alongside making everything local to the script:

local workspaceService = game.Workspace
local Model = workspaceService.Model
local spawnPlatform = workspaceService.SpawnPlatform

local function Move(Object: Model, Platform: BasePart)
	local newCFrame = CFrame.new(math.random(math.ceil(Platform.CFrame.Position.X - Platform.Size.X/2), math.floor(Platform.CFrame.Position.X + Platform.Size.X/2)),
		Object.PrimaryPart.CFrame.Position.Y,
		math.random(math.ceil(Platform.CFrame.Position.Z - Platform.Size.Z/2), math.floor(Platform.CFrame.Position.Z + Platform.Size.Z/2)))
	Object:PivotTo(newCFrame)
end
	
Move(Model, spawnPlatform)

You could do all this using your module, but I didn’t have access to it, so I made the changes necessary. You can sub out model:PivotTo() in favor of model:MoveTo(), to ensure no collision, but because you are using random values within the range of the platform it shouldn’t happen.

Btw all your math was right.

2 Likes

Alright I’ll test if this works in a few hours and give the solution if it works :happy2:

1 Like

Oh also Humanoid:MoveTo() only takes Vector3, here’s the :StartMovement function if you need it:

-- Start Movement
function Animal:StartMovement(Position: Vector3)
	
	if self.IsMoving == true then warn("Animal: " .. self.MODEL.Name .. " Is Already Moving") return end
	
	self.IsMoving = true
	
	self.IDLE_ANIM_TRACK:Stop()
	self.WALK_ANIM_TRACK:Play()
	
	
	self.HUMANOID:MoveTo(Position)
	
	local reached = self.HUMANOID.MoveToFinished:Wait()
	--if not reached then
	--	warn("Animal: " .. self.MODEL.Name .. " Didn't Reach the Target Position")
	--end
	
	
	self.IsMoving = false
	
	self.WALK_ANIM_TRACK:Stop()
	self.IDLE_ANIM_TRACK:Play()
	
end
1 Like

Humanoid:MoveTo() and Model:MoveTo() are different methods. I had assumed since you said you were moving models to different positions that you were using Model:MoveTo() which does take in a Vector3, but Model:PivotTo() is equivalent to it sub the guarantee of no part collision.

I’ll change my function to account for this in a bit.

1 Like

This worked for me:

local workspaceService = game.Workspace
local Animal = workspaceService.Animal
local spawnPlatform = workspaceService.SpawnPlatform

local function StartMovement(Animal: Humanoid, Position: Vector3)
	local Humanoid = Animal:WaitForChild("Humanoid")
	
	if Animal.IsMoving.Value == true then warn("Animal: " .. Animal.Name .. " Is Already Moving") return end

	Animal.IsMoving.Value = true

	--Humanoid.IDLE_ANIM_TRACK:Stop()
	--Humanoid.WALK_ANIM_TRACK:Play()

	Humanoid:MoveTo(Position)

	Humanoid.MoveToFinished:Wait()

	--Humanoid.WALK_ANIM_TRACK:Stop()
	--Humanoid.IDLE_ANIM_TRACK:Play()

	Animal.IsMoving.Value = false
end

local function MoveToNew(Animal: Humanoid, Platform: BasePart)
	local Position = Vector3.new(math.random(math.ceil(Platform.Position.X - Platform.Size.X/2), math.floor(Platform.Position.X + Platform.Size.X/2)),
		Animal.PrimaryPart.Position.Y,
		math.random(math.ceil(Platform.Position.Z - Platform.Size.Z/2), math.floor(Platform.Position.Z + Platform.Size.Z/2)))
	StartMovement(Animal, Position)
end

MoveToNew(Animal spawnPlatform)

Albeit I don’t have the animations or methods for starting/stopping you have for them so you will have to improvise for that part. IsMoving is something I didn’t have either so I created a boolvalue within the humanoid model.

1 Like

Seems to be doing the same thing as before, here’s what I mean:

(The yellow circles are the arrows to move parts in studio)
See how the yellow circles are global, but the platform is rotated locally?

I think the problem is that the position calculation only works if the platform aligns globally.

Basically I think the position and size is calculated, but it’s off by a lot because it doesn’t account for the rotation, since it’s only assuming it’s aligned perfectly.

I see what you’re talking about:
image

You would need to set your bounds for the rotated area by doing more math unfortunately. I can try to set this up in a bit, but I’m also working on filtering some new problems that have come with Roblox’s new TextChatService using Rich Text.

1 Like

I fixed it using this:

--Get a random position from a part
local function getRandomPositionOnPart(part, animal)
	-- Get the part's size and CFrame
	local size = part.Size
	local cframe = part.CFrame

	-- Generate random X and Z values within the local bounds
	local randomX = math.random() * size.X - size.X / 2
	local randomZ = math.random() * size.Z - size.Z / 2

	-- Convert the local position to world space
	local localPosition = Vector3.new(randomX, animal.PrimaryPart.Position.Y, randomZ)
	local worldPosition = cframe:PointToWorldSpace(localPosition)

	return worldPosition
end

Thanks for helping :happy2:

That all checks out! Sorry, I wasn’t more of a help though!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.