How do i get a Non-Humanoid MoveToFinished Alternative?

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?

1 Like

You’d want to use the :PivotTo() function for a model.

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…

  1. if the car is destroyed or parent set to nil
  2. is the move counter is > than the current move counter (meaning we are moving to another point)
  3. if a timeout is reached, such as if we are still in this loop and timer > distance to the target / speed
  4. 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)


image

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)

1 Like