What are you trying to achieve? Keep it simple and clear!
I want to make a tower defense enemy (in this case a default r6 block rig) move respectively to each waypoint. I did the movement itself, but the rotation is a big problem.
What is the issue? Include screenshots / videos if possible!
The rotation is supposed to face the same orientation as the waypoint (to prevent too much complexity). However, instead of rotating how it’s supposed, it spins around and then stays in that orientation for the rest of his journey. robloxapp-20210629-1559151.wmv (716.3 KB)
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I tried to replace Tween2’s ‘subject’ with the NPC’s torso instead of the rootPart. The rotation works, but if a walking animation plays, it breaks and the limbs get into weird un-intended positions.
My second attempt to fix it is to simply use BodyGyro, parenting it to the HumanoidRootPart. No matter if the BodyGyro’s was parented to the HumRootPart or Torso, it doesn’t rotate. However the animation works.
I couldn’t find any DevForum post that matches this problem.
These are the objects of the NPC:
(Animation script is nothing fancy, it just plays the animation.)
nextPoint = 1
-- SETTINGS --
local speed = 6
function moveToPoint()
local TweenService = game:GetService("TweenService")
local Part = script.Parent
local goal = {}
goal.CFrame = CFrame.new(game.Workspace.Waypoints:FindFirstChild(nextPoint).Position.X, Part.Position.Y, game.Workspace.Waypoints:FindFirstChild(nextPoint).Position.Z)
local goal2 = {}
goal2.Orientation = Vector3.new(0, game.Workspace.Waypoints:FindFirstChild(nextPoint).Orientation.Y, 0)
local partDistance = (Part.Position - game.Workspace.Waypoints:FindFirstChild(nextPoint).Position).magnitude
local tweenInfo = TweenInfo.new(partDistance / speed, Enum.EasingStyle.Linear)
local tweenInfo2 = TweenInfo.new(1, Enum.EasingStyle.Quad)
local tween = TweenService:Create(Part, tweenInfo, goal)
local tween2 = TweenService:Create(Part, tweenInfo2, goal2) --Works if i put "Script.Parent.Parent.Torso" instead of Part.
tween2:Play()
tween:Play()
wait(partDistance / speed)
nextPoint = nextPoint + 1
if game.Workspace.Waypoints:FindFirstChild(nextPoint) ~= nil then
moveToPoint()
else
script.Parent.Parent:Destroy()
end
end
moveToPoint()
I wanted to, but i realized Humanoid:MoveTo() stops if the npc is still walking after about 6-8 seconds. This would probably be a problem, especially for the slower enemies.
I also think Humanoid:MoveTo() causes lag if fired too much.
I already had the solution for the timeout, i was just worried if the loop would lag the game. And…
Ah, so the game doesn’t lag if i fire Humanoid:MoveTo() at a interval of very few milliseconds?
Alright, i’ve made the new movement system in which works both movement and rotation thanks to your advice. Animation work too.
Here’s what i did if it interests you:
Instead of using the While Loop to fire the Move function i used Humanoid.Running event, that detects if the NPC stopped moving or not. This is useful for the timeout and probably better than using While Loop.
There was a issue with :MoveTo(), and that is the fact that the NPC doesn’t move to the exact Y axis of the waypoint instead it stops in front of the waypoint. This led me to use magnitude: when the NPC is 1 stud close of the waypoint, it moves to the next point (I moved the waypoint a stud back from the center of the tile so the NPC moves on the center of the road). This can be tricky for the future big enemies but i can just change the required distance for that.
Besides these, thanks for your advice!
Here’s the current code:
nextPoint = 1
db = true
function moveToPoint()
db = false
local NPC = script.Parent
local Point = game.Workspace.Waypoints:FindFirstChild(nextPoint).Waypoint
NPC.Enemy:MoveTo(Point.Position)
local partDistance = (NPC.Torso.Position - game.Workspace.Waypoints:FindFirstChild(nextPoint).Waypoint.Position).magnitude
if partDistance <= 1 then
nextPoint = nextPoint + 1
if game.Workspace.Waypoints:FindFirstChild(nextPoint) == nil then
script.Parent:Destroy()
else
moveToPoint()
end
end
end
script.Parent.Enemy.Running:Connect(function(speed)
if db then return end
if speed == 0 then
print("Firing Function")
moveToPoint()
end
end)
moveToPoint()