How can I make the character "bounce" off of walls?

  1. What do you want to achieve?

I want the character to lightly bounce off of walls.

  1. What is the issue?

The character behaves as if it’s on ice at all times, which is intentional, but the issue is that when it gains momentum and crashes into a wall it doesn’t bounce off and instead just hugs the wall and waits for the momentum to deplete before it can turn around off the wall. I’ll attach a link to the gif of what I’m talking about: https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExNnZsN3dsbWVwYzJkeW5peDN3cWhteXc3ZjlsMzE3ZjB2MXVqbDVlMSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/kbIyepr6YGoyq147cf/giphy-downsized-large.gif

  1. What solutions have you tried so far?

I tried using “bouncy” parts like trampoline pads but it would be extremely tedious and not optimal to do that to essentially every wall in the game. Couldn’t find any solutions on the dev hub.

Essentially I’m trying to find a method to make it so the character will lightly bounce off the walls. As you can see in the gif, the time I’m spent just hugging the wall I am literally unable to turn the character around and go away from the wall because it still has momentum from before when it hit the wall.

Code for character movement, if it helps:

-- Here is the current code I have for the characters movement if it helps, got it from the dev hub
local plr = game:GetService("Players").LocalPlayer
local camera = game.Workspace.CurrentCamera
local RunS = game:GetService("RunService")

local targetMoveVelocity = Vector3.new()
local moveVelocity = Vector3.new()
local moveAcceleration = .5

local function lerp(a, b, t) return a + (b - a) * t end

local function getWalkDirectionCameraSpace()
	local walkDir = require(plr:WaitForChild("PlayerScripts").PlayerModule:WaitForChild("ControlModule")):GetMoveVector()

	if walkDir.Magnitude > 0 then
		walkDir = walkDir.Unit
	end

	return walkDir
end

local function getWalkDirectionWorldSpace()
	local walkDir = camera.CFrame:VectorToWorldSpace(getWalkDirectionCameraSpace())
	walkDir *= Vector3.new(1, 0, 1) -- Set Y axis to 0

	if walkDir.Magnitude > 0 then
		walkDir = walkDir.Unit
	end

	return walkDir
end

local function updateMovement(dt)
	local humanoid = character:FindFirstChild("Humanoid")
	if humanoid then
		local moveDir = getWalkDirectionWorldSpace()
		targetMoveVelocity = moveDir
		moveVelocity = lerp(moveVelocity, targetMoveVelocity, math.clamp(dt * moveAcceleration, 0, 1))
		humanoid:Move(moveVelocity)
	end
end

local function onCharacterAdded(char)
	character = char
	character:WaitForChild("Humanoid")
end

plr.CharacterAdded:Connect(onCharacterAdded)

-- Initial setup
if plr.Character then
	onCharacterAdded(plr.Character)
else
	plr.CharacterAdded:Wait()
end

RunS.RenderStepped:Connect(updateMovement)

4 Likes

try raycasting in the direction the player is moving in, and if it hits a wall use :ApplyImpulse() in the opposite direction to push off :stuck_out_tongue:

2 Likes

this works, though the player doesn’t lose momentum after hitting a wall so they sorta get stuck in this loop of hitting the wall, bouncing back, and continuing to slide into the wall:

1 Like

So when they hit the wall u detected, bounce them and decrease the momentum, and or bounce them off related to their speed and stop their velocity after the bounce

1 Like

Try setting the velocity to 0 before doing applyimpulse

1 Like

how would you set the players velocity to 0? I tried doing humanoidRootPart.Velocity = Vector3.new(0,0,0) which obviously doesn’t work. no error message, just didn’t fix the issue

how would you set the players velocity to 0? I tried doing humanoidRootPart.Velocity = Vector3.new(0,0,0) which obviously doesn’t work. no error message, just didn’t fix the issue

Maybe setting AssemblyAngularVelocity and AssemblyLinearVelocity to 0?

1 Like

doesn’t work :confused: could it have something to do with how I did the slippery/sliding movement in the first script I provided?

1 Like