Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Making a part face the direction of a vector?

Hello, I've managed to get as far as making the code below to get the direction vector that the player is moving:

while wait(0.2) do
	if root.Velocity.Magnitude == 0 then
		direction = root.Velocity
	else
		direction = root.Velocity.Unit
	end

	-- applying the direction vector to the part

	print(direction)
	

end

However, I have a part welded to the character's humanoid root part that I want to constantly rotate to face this direction vector. I'm not sure how I would go about doing this. The only concept I can think of is trying to get some sort of vector from the part and setting it to the direction vector then maybe using dot product to verify that the two lines are parallel or maybe I'm talking complete bollocks.

This may not be the most efficient way to do it, however I'm still in the process of learning the language and am open to any concepts and methods you may have.

Any form of help is greatly appreciated.

1 answer

✓ Accepted answer

Since you said your welding your part to the player via the root part of the humanoid you can't use the velocity like for instance if the player was stationary the Vector3.unit would be dividing by zero so you're positioning Vector will return NAN or not a number. to get around this problem you could record the position of your part each tick then save the previous position to get the direction from subtracting one from the other and if we're not moving use the lookvector of the root part as reference.

Something like:

local root = script.Parent
local Pos = root.Position
local OldPos = Pos -- just a way to record the previous position. its best to update this at the last thing in your loop, see below!

-- a debug brick for debugging 
local DBug_Part = (function()
	local P = Instance.new("Part",workspace)
	P.Anchored = true
	P.Size = Vector3.new(1,1,1)
	return P
end)()
while true do
	
	Pos = root.Position
	local DeltaPos = (Pos - OldPos)
	
	-- check to see if (Pos - OldPos).magnitude isnt 0 if it is set the direction to the root.CFrame.LookVector if it not then set it to the unit of those two vector3
	direction  = DeltaPos.magnitude ~= 0 and DeltaPos.unit or root.CFrame.LookVector

	DBug_Part.Position = Pos + (direction *2)
    -- applying the direction vector to the part

	print(direction)
	
	OldPos = Pos
	wait(0.2) -- most important bit we need the wait before the loop restarts to get the offset between Pos and OldPos otherwise it would return NAN or a magnitude of 0
end

a Much nicer way to make sure your part 'Remembers' which way it was pointing is to change the above code to the following:

local root = script.Parent
local Pos = root.Position
local OldPos = Pos
local OldDir = Vector3.new() -- Remember the last direction we had!

local DBug_Part = (function()
	local P = Instance.new("Part",workspace)
	P.Anchored = true
	P.Size = Vector3.new(1,1,1)
	P.CanCollide = false
	return P
end)()
while true do
	
	Pos = root.Position
	local DeltaPos = (Pos - OldPos)
	
	
	direction  = DeltaPos.magnitude ~= 0 and DeltaPos.unit or OldDir -- this is changed to the previous Dir Change if we're not moving!

	DBug_Part.Position = Pos + (direction *2)
    -- applying the direction vector to the part

	--print(direction)
	
	OldPos = Pos
	OldDir = direction
	wait()
end

Kinda related to this but I've made a little example from the above code that moves a part in a sine wave in 3 directions and positions a part in the direction the part is travelling. Both parts are anchored!

Code: (your free to use this code however you want. I just threw it together lol

local root = script.Parent

local Pos = root.Position
local OldPos = Pos
local OldDir = Vector3.new()
local OffsetPos = root.Position
local DBug_Part = (function()
	local P = Instance.new("Part",workspace)
	P.Anchored = true
	P.Size = Vector3.new(1,1,1)
	P.CanCollide = false
	
	return P
end)()

local tx = 0
local ty = 0
local tz = 0
root.FrontSurface = Enum.SurfaceType.Hinge
while true do
	
	
	local ax = tx * math.pi/180
	local ay = ty * math.pi/90
	local az = tz * math.pi/45
	
	local X = 10 * math.cos(ax)
	local Y = 10 * math.sin(ay)
	local Z = 10 * math.sin(az)
	

	root.CFrame = CFrame.new(OffsetPos+Vector3.new(X,Y,Z), Pos)*CFrame.Angles(0,math.rad(180),0)
	Pos = root.Position
	local DeltaPos = (Pos - OldPos)
	
	
	direction  = DeltaPos.magnitude ~= 0 and DeltaPos.unit or OldDir

	DBug_Part.Position = Pos + (direction *3)
    -- applying the direction vector to the part

	--print(direction)
	
	OldPos = Pos
	OldDir = direction
	wait()
	tx = tx+0.5
	ty = ty+0.7
	tz = tz+0.2
end

2 comments

0

That's great. I'm still going over it to make sure I understand it fully. Thank you for taking the time to explain it in such depth.

0

your welcome mate! :)

This discussion is preserved as it was. New answers, comments, and votes are closed.