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.
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.
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
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.
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.
(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.
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.
--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