Pathfinding to make a dummy move AWAY from character?

I have just recently started learning the pathfinding service, and I have learned how to make a dummy move towards the player, as well as run in a random direction. I have not been able to find out how to make the dummy move directly away from the player, which is something I am interested in using.
Is this possible? Preferably the dummy would move in the easiest immediate direction to run away (say the opposite direction of where the player enters the radius) but having them move in the direction that the player is facing would work too.
If anyone can help it would be greatly appreciated, thank you!

(I am only at an introduction level to CFrame as well, if that’s relevant for calculating movement direction.)

3 Likes

For anyone who does not know, calculating a direction from 1 part to another part is, d = b - a, vector a being the start of the direction, the position, this will be the position of the Dummy and vector b being the position of the Player, which the player will be looking at.

Calculating this vector d will be the end result, this being the direction the Dummy has to walk in to reach the Player.

Basically you will use what you learnt here (check above for an explanation), but instead invert the directon the dummy uses to move towards the player.

Going off that, we will have a Vector3 which would move the Dummy directly towards the player. If you make this direction negative, -direction, you mirrored the Vector over it’s Zero Vector, this being basically O (0, 0, 0).

Making the dummy walk away from the player instead of towards.

E.g.:

The direction of Dummy to Player is equal to (0.707106769, 0, -0.707106769) (this being basically backwards and to the right).

If we want to invert it we would need to make the X negative and the Z positive, basically do both times -1 to get the same result.

Calculation (in “lua form”):
Vector3.new(0.707106769, 0, -0.707106769) * -1 = Vector3.new(-0.707106769, 0, 0.707106769)

The end result would be (-0.707106769, 0, 0.707106769)

3 Likes

I will assume you already understand how to make the dummy move to a location using PathfindingService | Roblox Creator Documentation. Thanks for the info on your understanding of CFrame’s, as that is also important. I recommend you check out CFrames | Roblox Creator Documentation and then checking out CFrame | Roblox Creator Documentation for a more in-depth understanding of them and their functions/properties. For some of the math regarding CFrame’s you can check out CFrames | Roblox Creator Documentation.

For this example you want a variable of the distance the dummy should be from the player to move away from it. I will use Player | Roblox Creator Documentation for simplicity, but you can also use: (DummyBodyPartPosition - PlayerBodyPartPosition).Magnitude to get the distance from the player the dummy is as well.

The CFrame method I will be using is CFrame:PointToObjectSpace.

A rundown of what I’m doing:

  1. Check the distance between dummy and player’s character
  2. If the distance is shorter than the minimum distance we want in-between the player and the dummy we subtract the desired distance by the current distance to get the needed distance to move
  3. We call our function to get the position the dummy needs to move too
  4. You call whatever code or function you use to pathfind the dummy
    Function:
  5. We find the direction facing away from character relative to where the dummy is
  6. We calculate the position needed to be within the minimum distance from the player
  7. You fire whatever function you use to pathfind the dummy to the new position

Make sure that the position you pathfind the dummy to is dynamic and able to be changed, as the player may be moving closer to the dummy, thus recalling the function and spitting out a new position the dummy needs to move too.

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local distanceRequired = 50 -- The distance in studs we want the dummy to be from the player

local Dummy = script.Parent
local dummyHead = Dummy:WaitForChild("Head")
local dummyPos -- Reduces the performance loss due to the `.` pointer

local function  CalculatePosition(playerHead, distance)
	local direction = playerHead.CFrame:PointToObjectSpace(dummyHead.Position).Unit -- .Unit makes the vector only move the total distance of 1 stud if added to a position
	local position = (direction * distance) -- The position the dummy needs to move too
	
	return position
end

-- Returns the distance between the nearest player and the dummy
local function GetNearestPlayer()
	local nearestPlayer
	local nearestDistance = distanceRequired

	for _, player in pairs(Players:GetPlayers()) do
		local plrDist = player:DistanceFromCharacter(dummyPos)

		if (plrDist < nearestDistance) then
			nearestDist = plrDistance
			nearestPlayer = player
		end
	end

	return nearestPlayer, nearestDistance
end

RunService.Stepped:Connect(function()
	dummyPos = dummyHead.Position

	local player, distance = GetNearestPlayer()
	
	if (distance < distanceRequired) then
		local position = CalculatePosition(player.Character.Head, distanceRequired - distance) -- Here we subtract the distance required by the current distance

		-- Here you do your function call or code to pathfind the player
	end
end)


NOTE:
This script is untested so I haven’t had an opportunity to see if it works or optimize it

1 Like

Very helpful, testing out this script setup right now! My current issue is that it seems to only calculate from the direction that the player CFrame is facing, so if I turn my character around, the dummy runs towards me. Would there be a way to substitute the player character’s position for their CFrame?

It’s very helpful to have this explanation of the simple bit too, I’ve been able to use this to edit the script from the other commenter and get to the position that I want. Thank you!

Oops! I completely overlooked the rotation of the player! My bad! I think I forgot to translate object space back into world space! To solve this I will replace CFrame:PointToObjectSpace with a simpler method that doesn’t account for the rotation of the player! I’m sorry that I overlooked this! So this method is much simpler and I should have used it from the start.

To get the direction of the Dummy relative to the position of the player in without accounting for the player rotation replace

With

local direction = (dummyHead.Position - playerHead.Position).Unit

This will basically get the world direction that the position of the dummyHead is relative to the position of the playerHead. On the flip side, if you wanted to get the direction of the Player relative to the position of the Dummy you would do: local direction = (dummyHead.Position - playerHead.Position).Unit. In other words, the first example gets the direction away from the Player and towards the Dummy and the second gets the direction towards the Player and away from the Dummy.

However, as @KJry_s mentioned in his reply, you can multiply the direction value by -1 to flip it towards or away from the player. This means that if you want to change if the Dummy is moving towards or away from the player all you have to do is multiply the direction by negative one. A fun challenge you can do with this is attempt to make the Dummy stay the distanceRequired away from the player but conversely make it so it also follows that player from that distance.

If you want you can read about it here: Object and World Space | Roblox Creator Documentation

So now that we have the direction we have to do something extra. Now we have to multiply the direction by the distance, but then we must also add it to the current position of the dummyHead.

local position = (direction * distance) + dummyHead.Position

So your final command should look like this:

local function  CalculatePosition(playerHead, distance)
	local direction = (dummyHead.Position - playerHead.Position).Unit
	local position = (direction * distance) + dummyHead.Position
	
	return position
end

Also, if you want to learn about Vector math you can go here: Vector3 | Roblox Creator Documentation and then go to the Math Operations section.



PS - Again, I can’t state how sorry I am for making such a dumb mistake.

3 Likes

It’s no problem at all, it only does more to help me learn. :slight_smile: Thank you very much!