Ball won't bounce correctly in the 3d space

Summary

So I want to make a ball in a box bounce like a DVD logo, but in a 3d space or one of those cube screen savers from the 90s. The problem is that the ball bounces back and forth as it reaches the bottom until it hits the corner and goes slow, instead of bouncing up and back and forth like the DVD logo. I have tried adding wedges for some reason that only works a little but then goes downhill.

Attachments (the script is at the bottom)

local ball = script.Parent
local Vspeed = 20
local velocity = Vector3.new(Vspeed, 5, Vspeed)

ball.Anchored = false
ball.CanCollide = true
ball.Position = ball.Position + Vector3.new(0, 0, 0) 

ball.Massless = true

ball.Velocity = velocity

local function bounce(hit)
	
	
	
    local hitNormal = (hit.Position - ball.Position).unit
    local horizontalNormal = Vector3.new(hitNormal.x, 0, hitNormal.z).unit
    local verticalNormal = Vector3.new(0, hitNormal.y, 0).unit

    if horizontalNormal.magnitude > 0 then
        velocity = Vector3.new(-velocity.x, velocity.y, -velocity.z)
    end

    if verticalNormal.magnitude > 0 then
        velocity = Vector3.new(velocity.x, -velocity.y, velocity.z)
    end

    ball.Velocity = velocity
end

ball.Touched:Connect(function(hit)
    if hit:IsA("Part") then
        bounce(hit)
    end
end)

while true do
    ball.Velocity = velocity
    task.wait()
end


Maybe try inverting the velocity:

if horizontalNormal.magnitude > 0 then
        velocity = -Vector3.new(-velocity.x, velocity.y, -velocity.z)
    end

    if verticalNormal.magnitude > 0 then
        velocity = -Vector3.new(velocity.x, -velocity.y, velocity.z)
    end

Still nothing I even tried removing the wedges but it didn’t work

  if horizontalNormal.magnitude > 0 then
        vector = Vector3.new(-velocity.x, velocity.y, -velocity.z)
velocity = vector -2 * vector:Dot(horizontalNormal) * horizontalNormal
    end

    if verticalNormal.magnitude > 0 then
        vector = Vector3.new(velocity.x, -velocity.y, velocity.z)
velocity = velocity = vector -2 * vector:Dot(verticalNormal) * verticalNormal
    end

were would I put that in again?

local ball = script.Parent
local Vspeed = 20
local velocity = Vector3.new(Vspeed, 5, Vspeed)

ball.Anchored = false
ball.CanCollide = true
ball.Position = ball.Position + Vector3.new(0, 0, 0) 

ball.Massless = true

ball.Velocity = velocity

local function bounce(hit)
	
	
	
    local hitNormal = (hit.Position - ball.Position).unit
    local horizontalNormal = Vector3.new(hitNormal.x, 0, hitNormal.z).unit
    local verticalNormal = Vector3.new(0, hitNormal.y, 0).unit

    if horizontalNormal.magnitude > 0 then
      local  vector = Vector3.new(-velocity.x, velocity.y, -velocity.z)
velocity = vector -2 * vector:Dot(horizontalNormal) * horizontalNormal
    end

    if verticalNormal.magnitude > 0 then
       local vector = Vector3.new(velocity.x, -velocity.y, velocity.z)
velocity  = vector -2 * vector:Dot(verticalNormal) * verticalNormal
    end

    ball.Velocity = velocity
end

ball.Touched:Connect(function(hit)
    if hit:IsA("Part") then
        bounce(hit)
    end
end)

while true do
    ball.Velocity = velocity
    task.wait()
end

change
vector
to
local vector

change

velocity = velocity = ...

to

velocity = ...

Couldnt you just make it so everytime it hits a wall or something it travels in a different direction each time?

thats what i am trying to do lol

Better it stays at the bottom though heres what i have in my code so far

local ball = script.Parent
local Vspeed = 20
local velocity = Vector3.new(Vspeed, 0, Vspeed)

ball.Anchored = false
ball.CanCollide = true
ball.Position = ball.Position + Vector3.new(0, 0, 0) 

ball.Massless = true

ball.Velocity = velocity
local function reflectVector(vector: Vector3, normal: Vector3)
	return vector -2 * vector:Dot(normal) * normal -- r = v - 2n(v ⋅ n) * n
end

local function bounce(hit)



	local hitNormal = (hit.Position - ball.Position).unit
	local horizontalNormal = Vector3.new(hitNormal.x, 0, hitNormal.z).unit
	local verticalNormal = Vector3.new(0, hitNormal.y, 0).unit

	if horizontalNormal.magnitude > 0 then
		local  vector = Vector3.new(-velocity.x, velocity.y, -velocity.z)
		velocity = reflectVector(vector,horizontalNormal)
	end

	if verticalNormal.magnitude > 0 then
		local vector = Vector3.new(velocity.x, -velocity.y, velocity.z)
		velocity = reflectVector(vector,verticalNormal)
	end

	ball.Velocity = velocity
end

ball.Touched:Connect(function(hit)
	if hit:IsA("Part") then
		bounce(hit)
	end
end)

while true do
	ball.Velocity = velocity
	task.wait()
end

ok, could you please mark my code as the solution then?

Yes thank you also the game im making is based on breakout

1 Like

Ok, glad I could help you out. Good at making your game and I hope you have a nice day/ evening!