How would I change the direction of the Body Velocity on based off the orientation of a part?

I’m currently making a Wall Running System and I’m scripting in the Physics and I got stuck at this. I’ve already fixed all the other problems. I’ve tried using the parts CFrame, Orieantation, LookVector, etc. This is what’s happening right now:

	function WallRun()
		if not LeftWallCheck() and not RightWallCheck()  then return end -- needs to go through these casts first.

		local Speed = Humanoid.WalkSpeed
		local IsWallRunning = false
		local WallRunL = false
		local WallRunR = false
		
		local DebounceR = false
		local DebounceL = false
		local CD = 2.5
	
		if Speed > 20 then -- can't wallrun if no speed
			print (Speed)
			if LeftWallCheck() then
			local LPart = LeftWallCheck().Instance
			print (HoldingSpace)
				if IsWallRunning or DebounceL or not HoldingSpace then return end
				
				DebugAttatchment(LeftWallCheck().Position)
				IsWallRunning = true
				
				--[[
				local weld = Instance.new("WeldConstraint")
				weld.Parent = LeftWallCheck().Instance
				weld.Part0 = HRP
				weld.Part1 = LPart
				weld.Enabled = true
				--]]
				
				WallRunL = true
				DebounceL = true
				
				Humanoid.AutoRotate = false
				Humanoid:ChangeState(Enum.HumanoidStateType.Climbing)
				
			
			
			local bv = Instance.new("BodyVelocity",HRP)
			bv.MaxForce = Vector3.new (math.huge,math.huge,math.huge)
			bv.Velocity = HRP.CFrame.LookVector * Speed + -HRP.CFrame.UpVector * 15
			AnimWallRunL:Play()
			--]]
			Humanoid.StateChanged:Connect(function(old,new)
				if new == Enum.HumanoidStateType.Landed then
					bv:Destroy()
					AnimWallRunL:Stop(.5)
					
					IsWallRunning = false
					WallRunL = false
					Humanoid.AutoRotate = true
				end
			end)
			
			-- try a loop next
				RunService.RenderStepped:Connect(function()
					task.wait(.1)
					if LeftWallCheck() == nil then
						
					   bv:Destroy()
					   AnimWallRunL:Stop(.5)

					   IsWallRunning = false
					   WallRunL = false
					   Humanoid.AutoRotate = true
					elseif LeftWallCheck() then
						
					
						--print ("Changing Direction")
					--bv.Velocity = HRP.CFrame.LookVector * Speed + LeftWallCheck().Instance.Orientation + -HRP.CFrame.UpVector * 15
						
					end	
					
					
				end)

			
			UIS.InputEnded:Connect(function(input,gpe)
				if gpe then return end

				if input.KeyCode == Enum.KeyCode.Space and IsWallRunning then
					print ("WallJumped")
					bv:Destroy()
					-- HRP.Velocity = HRP.CFrame.RightVector * 2 and HRP.CFrame.UpVector * Speed * 2 -- I'll add actual physics later
					
					AnimWallRunL:Stop(.5)
					-- AnimWallJumpL:Play()
					
					Humanoid.AutoRotate = true 
					IsWallRunning = false
					WallRunL = false
				end
			end)
			
				task.wait(EndTime)
			Humanoid.AutoRotate = true 
			
			
			--weld:Destroy()
			bv:Destroy()
			AnimWallRunL:Stop()
			WallRunL = false



				-- Physics & If they press space they stop Wall Running they Jump off the walL.
				-- Their velocity will go down after 3s and End Specific to that person. (EndTime)
				-- If they don't press space they keep going.
				-- If they are wall running and touch the floor they stop.
			
			else
				DebugAttatchment(RightWallCheck().Position)
			local RPart = RightWallCheck().Instance

				--HRP.Anchored = true -- They cannot move and Face the wall they are against.
				Humanoid.AutoRotate = false -- Face Direction they are moving so it doesn't look weird.

				task.wait(EndTime)

				--HRP.Anchored = false
				Humanoid.AutoRotate = true 

				-- Physics & If they stop Wall Running they Jump off the walL. Play The Anim too.
			     UIS.InputBegan:Connect(function(input, GPE)
				 if input.KeyCode == Enum.KeyCode.Space and IsWallRunning then
					 -- They Jump off and End the Wall Run.
					HRP.Velocity = -HRP.CFrame.RightVector and HRP.CFrame.UpVector * Speed * 2
					 IsWallRunning = false
					 WallRunR = false
				    end
				 end)
				 
			end
			
		end
	end

	
	UIS.InputBegan:Connect(function(Input, GPE)
		if GPE then return end
	if Input.KeyCode == Enum.KeyCode.A or Enum.KeyCode.D then
		if not Humanoid:GetState(Enum.HumanoidStateType.Freefall) then return end
		WallRun()
		end
	end)
1 Like

Are you able to post a video of exactly what you’re looking for? What the end result is.

1 Like

Something like this is what I’m looking for.

is the problem that you’re having that the player keeps wallrunning even if they’re not actually wall running beside a wall? if so, can you show the LeftWallCheck() and RightWallCheck() functions code which should have something to do with the player staying on the wall or not.
btw in this line:

just Enum.KeyCode.D alone won’t work, instead do the same thing as the condition before it:
Input.KeyCode == Enum.KeyCode.D

1 Like

The problem is that they’re not running along side the wall whenever a new wall comes. Instead it runs into it. Anyways here’s the LeftWallCheck() and RightWallCheck() functions:

local function LeftWallCheck() -- Checks if There is a wall to your Left.
		return workspace:Raycast(HRP.Position, -HRP.CFrame.RightVector * RayLength, raycastParmas)
	end

	local function RightWallCheck() -- Checks if There is a wall to your Right.
		return workspace:Raycast(HRP.Position, HRP.CFrame.RightVector * RayLength, raycastParmas)
	end

	local function FloorCheck() -- Checking If you are on the floor or not.
		return workspace:Raycast(HRP.Position, -HRP.CFrame.UpVector * RayLength, raycastParmas)
	end 

I like the bug can you keep it?

1 Like

Do you want to ram into walls? And not run alongside them?

Sorry

This text will be blurred

1 Like

I know you said you’ve tried orientation and cframe and stuff, but can you please give me an example of how you were doing it?

1 Like

I don’t really know if I did it correctly or not. I tried doing it like this:

bv.Velocity = HRP.CFrame.LookVector * Speed + LeftWallCheck().Instance.Orientation + -HRP.CFrame.UpVector * 15
-- or 
bv.Velocity = HRP.CFrame.LookVector * Speed + LeftWallCheck().Instance:GetPiviot() + -HRP.CFrame.UpVector * 15

bv.Velocity = HRP.CFrame.LookVector * Speed + LeftWallCheck().Instance.CFrame + -HRP.CFrame.UpVector * 15

If you want to try something else, you can set the HRP X/Y/Z (you would need to figure out which one works when) orientation to that of the wall or any offset that you wish to, and this may give you the result you’re looking for.

Edit: I tested this and it will change the player’s rotation. Here is how I’ve done it to test, though for your script you will have to obviously change it. It is the Y orientation you want to change.

game.Players.PlayerAdded:Connect(function(Player)
	Player.CharacterAdded:Connect(function()
		local Character = Player.Character
		local HRP: Part = Character.HumanoidRootPart
		wait(10)
		local YOrientation = -20
		HRP.Orientation = Vector3.new(HRP.Orientation.X, YOrientation, HRP.Orientation.Z)
	end)
end)

This then has the end result of the character turning to -20.

1 Like

Although this does sort of work turning the body, it doesn’t change the body velocity and, I’m aiming to change the body velocity direction to the Parts Direction. In the video I sent you can see it change the direction of where he’s headed with the Players Rotation getting changed to the walls orientation so I’d say this is half of that. I’ve been trying to do this:

bv.Velocity = (HRP.CFrame.LookVector - HRP.CFrame.UpVector) * Speed
-- or 
bv.Velocity = (HRP.CFrame.LookVector + HRP.CFrame) * Speed
 

If you want I could make a baseplate where you use the script. Without the need of coming and asking me to try it out.

I don’t know if you can change the direction of the body velocity without making a new one.

I can’t say much about bv’s but I’d assume you could do it the way you did it to originally set it, which appears to be like this (after you’re reset the orientation)

bv.Velocity = HRP.CFrame.LookVector * Speed + -HRP.CFrame.UpVector * 15

The important thing if my method is correct is this will only work after the orientation is changed and properly set. You might already be doing something like that, or tried, but I’m simply making a guess here since I can’t dive much further at the moment.

1 Like


Yeah uh I don’t know if I did it wrong or something but I made the Y Direction the Orientation Y direction of the part you’re wall running.

You do go in the direction of the Look Vector but the Look Vector is all over the place. Which makes you fling out, glitch etc.

local YOrientation = LeftWallCheck().Instance.Orientation.Y
HRP.Orientation = Vector3.new(HRP.Orientation.X, YOrientation, HRP.Orientation.Z)
			
			local bv = Instance.new("BodyVelocity",HRP)
			bv.MaxForce = Vector3.new (math.huge,math.huge,math.huge)
			bv.Velocity = HRP.CFrame.LookVector * 24 + -HRP.CFrame.UpVector * 15

Would you mind trying this to see if this type of CFrame method fixes it? I tried it almost micing your script and it sent the character straight from the orientation.

HRP.CFrame = CFrame.new(HRP.Position) * CFrame.Angles(0, YOrientation, 0)

Edit: I forgot to mention, remove the old orientation line.

2 Likes


You basically slide off the wall. This is when I put it after the Body Velocity.

This is what happens when I put it before Body Velocity:


It goes in random directions.

Is it possible (unrelated to what I sent you) that the attachment points could have something to do with this?

It appears to make a bunch of attachments when you first start and then after that on the other walls it doesn’t do that.

1 Like

That’s a debugging thing. It’s to see whenever it started and it see where it started.

local function DebugAttatchment(Position: Vector3) -- Using An Attachment to detect Where the wall is. (Debugging)
	if not Debug then return end

	local DebugAttachment = Instance.new("Attachment") 
	DebugAttachment.Visible = true

	DebugAttachment.CFrame = CFrame.new(Position)
	DebugAttachment.Parent = workspace.Terrain

	task.delay(5, function()
		DebugAttachment:Destroy()
	end)

Okay. Can you send me the code you were using to achieve the 2nd result in the video?