In my tower defense game, I use parts for waypoints and then collect their positions to form a path using the BezierPath module. Using the path, I calculate the uniform CFrame at a point then set the model’s primary part there. Here’s the code:
function BaseMonster:UpdatePosition(dt)
if not self.path or self.stunned then return end
-- Lifting head so that the feet are not in the ground
local boundingBoxCFrame, boundingBoxSize = self.model:GetBoundingBox()
local bottomPosition = boundingBoxCFrame.Position - Vector3.new(0, boundingBoxSize.Y / 2, 0)
local difference = self.model.PrimaryPart.Position - bottomPosition
self.pathPosition = math.min(self.pathPosition + self.speed * dt, 1)
local newPos = self.path:CalculateUniformCFrame(self.pathPosition) + difference
self.model:SetPrimaryPartCFrame(newPos)
if self.pathPosition >= 1 then
self:ReachEndOfPath()
end
end
This is done every time RunService.Stepped occurs and uses the deltaTime to determine how far to travel. So far, this works fine, other than the optimization issues. The main problem that I have using this method is the jitter of animations. Here’s what the animation is supposed to look like:
Here is what it ends up looking like:
I assume that the jitter comes from setting the CFrame of the primary part of the model, but I have no idea what other movement method to use that preserves animation.
Here’s the code that I used to set the animation (the script is a child of the enemy model for convenience at the moment):
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://18298531920"
local rig = script.Parent
local humanoid = rig:FindFirstChildOfClass("Humanoid") or rig:FindFirstChildOfClass("AnimationController")
local animator = humanoid:FindFirstChildOfClass("Animator")
if not animator then
animator = Instance.new("Animator")
animator.Parent = humanoid
end
local animationTrack = animator:LoadAnimation(animation)
animationTrack:Play()
I’d love to hear of any alternatives to my current method because mine seems extremely flawed.