Mathematics, including player position & a part position

Hi, If you look at the video at the bottom, you can see that the player get’s a “pickup” interaction box when 10 studs from the part…

When the player interacts with it I want the player to automatically walk, no input given from client, literally right on the side of the part using the closest absolute direction, as in If North is closer then the player will walk to the north side of it, and such…

I am not sure what kind-of math I should use to have the player walk towards the box using the closest direction.

1 Like

You can get the position just outside each face by using the size and cframe. Using the relative cframe, just create a position on each face.

part.CFrame:ToObjectSpace(CFrame.new(0, part.Size.Y/2, 0))

should get a position of the top face, and I think you can figure out the rest. Then use magnitude to check the distance of these faces to the player.

1 Like

Ah okay thanks, not to sure about CFrame yet, not my strong suit. Going to look into it, so I know exactly what I’m doing. I’ll let you know if I need any help.

1 Like

Wait let me make sure I understand this, so first we make get the position of all the sides and then we get the distance from all of those, and then we walk towards the closest one?

You are right.

30 characters 30 characters

1 Like

How would I keep track of what side it’s getting the position of?

You could use a table, or just use variables.

local Faces = {
 North = ...
 South = ...
...
}
1 Like

Sorry for so many questions,

The variables would be set in a for loop?

Basically for sides do this, and disregard the top or bottom side… But then leaves me with the issue of so many if statements in one for loop that checks oh if it’s this side, then lets +Size.X or oh it’s this side so we’re going to -Size.Z

I hope that makes sense for what I’m having an issue understanding.

I’m not sure why you need if statements for this.

local Faces = {
North = part.CFrame:ToObjectSpace(CFrame.new(0, 0, part.Size.Z/2));
South = part.CFrame:ToObjectSpace(CFrame.new(0, 0, (part.Size.Z/2)*-1));
...
}
1 Like

Oooooooooh. :man_facepalming:
Thank you, I will see what I can do.

1 Like

Well this is what I’ve got but the player will go the complete opposite way.

local function GetClosestFace(Player, Part)
	local PartFace = {
		North = Part.CFrame:PointToObjectSpace(Vector3.new(0, 0, Part.Size.Z/2)),
		South = Part.CFrame:PointToObjectSpace(Vector3.new(0, 0, (Part.Size.Z/2)*-1)),
		West = Part.CFrame:PointToObjectSpace(Vector3.new(Part.Size.X/2, 0, 0)),
		East = Part.CFrame:PointToObjectSpace(Vector3.new((Part.Size.X/2*-1), 0, 0))
	}
	print(PartFace.North, PartFace.South, PartFace.West, PartFace.East)
	local Distances = {
		North = Player:DistanceFromCharacter(PartFace.North),
		South = Player:DistanceFromCharacter(PartFace.South),
		West = Player:DistanceFromCharacter(PartFace.West),
		East = Player:DistanceFromCharacter(PartFace.East)
	}
	print(Distances.North, Distances.South, Distances.West, Distances.East)
	local ClosestFace = math.min(Distances.North, Distances.South, Distances.West, Distances.East)
	local Face
	if ClosestFace == Distances.North then
		Face = PartFace["North"]
	elseif ClosestFace == Distances.South then
		Face = PartFace["South"]
	elseif ClosestFace == Distances.West then
		Face = PartFace["West"]
	elseif ClosestFace == Distances.East then
		Face = PartFace["East"]
	end
	print("Face:", Face)
	return Face
end

local function ForcePlayerWalk(Player, Position)
	Player.Character.Humanoid:MoveTo(Position)
end

diffmessage

If they go the opposite way, then make it either a negative or positive number.

Yeah U changed that and it still happened the same way.

try placing parts at each face position to make sure that you’re actually getting the correct position. There’s a chance my math could be wrong.

Edit: You’re using PointToObjectSpace, not ToObjectSpace. Try using that instead.

MoveTo uses Vector3 and DistanceFromCharacter uses Vector3,

You can convert a CFrame to a Vector3 though?


This implies it does the that right?

local function GetClosestFace(Player, Part)
	local PartFace = {
		North = Part.CFrame:ToWorldSpace(CFrame.new(0, 0, Part.Size.Z/2)),
		South = Part.CFrame:ToWorldSpace(CFrame.new(0, 0, (Part.Size.Z/2)*-1)),
		West = Part.CFrame:ToWorldSpace(CFrame.new(Part.Size.X/2, 0, 0)),
		East = Part.CFrame:ToWorldSpace(CFrame.new((Part.Size.X/2*-1), 0, 0))
	}
	-- Enable to see position of faces.
--	for i,v in pairs(PartFace) do
--		local newpart = Instance.new("Part");
--		newpart.Anchored = true;
--		newpart.CFrame = v;
--		newpart.Size = Vector3.new(1,1,1);
--		newpart.Parent = workspace;
--	end
	local Distances = {
		North = Player:DistanceFromCharacter(Vector3.new(PartFace.North)),
		South = Player:DistanceFromCharacter(Vector3.new(PartFace.South)),
		West = Player:DistanceFromCharacter(Vector3.new(PartFace.West)),
		East = Player:DistanceFromCharacter(Vector3.new(PartFace.East))
	}
	local ClosestFace = math.min(Distances.North, Distances.South, Distances.West, Distances.East)
	local Face
	if ClosestFace == Distances.North then
		Face = PartFace["North"]
	elseif ClosestFace == Distances.South then
		Face = PartFace["South"]
	elseif ClosestFace == Distances.West then
		Face = PartFace["West"]
	elseif ClosestFace == Distances.East then
		Face = PartFace["East"]
	end
	print("Face:", Face)
	return Face
end

local function ForcePlayerWalk(Player, Position)
	Player.Character.Humanoid:MoveTo(Position)
end

Try this instead. I replaced ToObjectSpace with ToWorldSpace, my bad.

1 Like

Change to the code you gave me.

23:02:07.199 - Unable to cast CoordinateFrame to Vector3
23:02:07.199 - Stack Begin
23:02:07.199 - Script 'ServerScriptService.PickupScript', Line 13 - function GetClosestFace
23:02:07.200 - Script 'ServerScriptService.PickupScript', Line 42
23:02:07.200 - Stack End

Because it’s a CFrame now. Vector3.new(cframe.X, cframe.Y, cframe.Z)

Edit: you can change it to use PointToWorldSpace to avoid this.

1 Like