Hi so i have a Car NPC, which follows a certain target. and somehow i want a alternative MoveToFinished, because putting humanoid and connecting the torso does not work, it only works on regular roblox rigs, but my npc’s are humanoid-less, how do i give them like a Alternative MoveToFinished-like function?
Do i just like carbody:PivotTo(target.position):Wait(), is that how it works?
Yes, something like that. I’d recommend it be a CFrame though.
So you’d do carbody:PivotTo(target.CFrame):Wait()
But the car npc uses the same system as players car, does it count as cframe though?
Yea, are you trying to move it to the position of a block or just a vector in general?
No, i just want a wait(pivot) trigger so my car npc can get accurate time in pathfinding.
The :wait() at the end should work, test it out, or you can use a repeat until the Position is the position you wanna tween it to.
Its not working, it didn’t even print. What did i do wrong?
I don’t know but is PivotTo event related to MoveToFinished in a non humanoid way?
When you tell the car to go to a point, you set an attribute on the car’s primary part, such as ‘MoveCounter’ and set it to its value + 1, so that each time you tell the car to go to a new point, this is increased by 1
Also, when telling the car to go to a new point do a spawn(), and in that spawn have a loop
This loop will keep looping until any of the 4 conditions are met…
- if the car is destroyed or parent set to nil
- is the move counter is > than the current move counter (meaning we are moving to another point)
- if a timeout is reached, such as if we are still in this loop and timer > distance to the target / speed
- if the magnitude of the cars primary part, and the target goal are < a certain value, such as 5 (or you can modify this value based on the car’ s size, and the speed traveling)
When one of these conditions are met, the spawned loop exits
I would set the loop to a … if pass < 1 then loop, and when there is a reason to exit, set pass to a value 1-4 so after the loop you can check why the loop exited and do something…
such as…
spawn(function()
local pass = 0
while pass < 1 do
1) if the car is destroyed or parent set to nil pass= 1
2) is the move counter is > than the current move counter (meaning we are moving to another point) pass = 2
3) if a timeout is reached, such as if we are still in this loop and timer > distance to the target / speed pass = 3
4) if the magnitude of the cars primary part, and the target goal are < a certain value, such as 5 pass = 4
wait()
end
if pass == 1 then <do something for a dead car>
elseif pass == 2 then
elseif pass == 3 then car:PivotTo(targetPosition.CFrame)
elseif pass == 4 then <we reached the goal, so move to next one>
end)
Just some ideas on how you might do it.
Hey… Magnitude doesn’t sound a bad idea? but how do i make if a numbervalue that replicates magnitude, and you put it and like how do you like add a wait to make it wait until it gets below 5.0 magnitude?
well in that loop, in the spawn, you would just check it each pass
local mag = (Car.PrimaryPart.Position - Target.Position).Magnitude
if mag <= 0.5 then
<reached target>
end
yeah but, i want the mag to have a :Wait() on it, so when it exactly gets below 5.0 and like instantly makes new waypoint and repeats so on.
I guess you could have a wait on it somehow, but really just having a loop, with a wait, and that loop checking for multiple things, magnitude being just one of them, is probably a better way to go, so you can check for unexpected things, such as the car destroyed or timeouts in case somehow the car cant reach the goal, or in case you assign a new point, before the car reached the current point.
alr ill try your advice!
just gotta hope it works…
YO THANK YOU.
Summary
Many thanks!
I realize you already marked this as solved, but I wanted to give an actual place example, for other people who might find this and need something more ‘hands on’
In the example, when you sit on the ufo, it goes through the waypoints, when you stop sitting, it returns to the start.
Also the brick wall, is to show that if you have an obstacle, the timout will teleport you to the next waypoint, if you are stuck for too long.
FollowWaypoints.rbxl (74.4 KB)
local waypoints = {}
for n = 1,# workspace.Points:GetChildren() do
table.insert(waypoints,workspace.Points:WaitForChild("Part"..n).CFrame)
end
local car = workspace:WaitForChild("Car")
local alignPosition = car.PrimaryPart:WaitForChild("AlignPosition")
alignPosition.Position= car.PrimaryPart.CFrame.Position
alignPosition.Enabled = true
local alignOrientation = car.PrimaryPart:WaitForChild("AlignOrientation")
function MoveToPoint(cframe,Speed)
Speed = Speed or 10
local MoveCounter = car.PrimaryPart:GetAttribute("MoveCounter") or 0
MoveCounter = MoveCounter + 1
car.PrimaryPart:SetAttribute("MoveCounter",MoveCounter)
car.PrimaryPart:SetAttribute("WaypointReached") --clears the waypoint reached attribute
local Waypoint =cframe
spawn(function()
local moveCounter = MoveCounter
local waypoint = Waypoint
local distance = (car.PrimaryPart.Position - waypoint.Position).Magnitude
local speed = Speed
local timeout = (distance /speed) + 2 --give an extra 5 seconds to try and reach point
alignPosition.MaxVelocity = Speed
alignOrientation.CFrame = CFrame.lookAt(car.PrimaryPart.Position,waypoint.Position,Vector3.new(0,1,0))
while true do
if car and car.Parent then
--Do your own movement code here
alignPosition.Position = waypoint.Position+Vector3.new(0,2,0)
--
if car.PrimaryPart:GetAttribute("MoveCounter")> moveCounter then --a new waypoint has been selected
break
elseif timeout < 1 then --took too long to reach waypoint
car:PivotTo(waypoint+Vector3.new(0,2,0))
car.PrimaryPart:SetAttribute("WaypointReached",true)
break
elseif ((car.PrimaryPart.Position*Vector3.new(1,0,1)) - (waypoint.Position*Vector3.new(1,0,1)) ).Magnitude < 4 then --we reached the goal
car.PrimaryPart:SetAttribute("WaypointReached",true)
break
end
else --car is destroyed
break
end
timeout = timeout - wait()
end
end)
end
local homePosition = car.PrimaryPart.CFrame
local max = #waypoints
local current = 1
local speed = 40
car.PrimaryPart:GetAttributeChangedSignal("WaypointReached"):Connect(function()
if car.PrimaryPart:GetAttribute("WaypointReached") == true then
current = current + 1
if current > max then current = 1 end
if waypoints[current] then
MoveToPoint(waypoints[current],speed)
end
end
end)
car.Seat.ChildAdded:Connect(function()
current = 1
MoveToPoint(waypoints[current],speed)
end)
car.Seat.ChildRemoved:Connect(function()
current = -1
MoveToPoint(homePosition,speed*2)
end)