The ball flies through walls/floors at high speed/altitude

You can write your topic however you want, but you need to answer these questions:
Hi!
I want to fix the bug where the ball just goes through objects when it is flying at a high height or speed.

I tried making the hitboxes of my ball bigger, making larger raycasts and shapecasts, but nothing helped.

Video that showing my bug:

And theres is my code block with the physic

function BallPhysics:step(dt)
    if (self.resting) then return end
    self.lastPosition = self.position

    if not self.grounded then
        self.velocity = self.velocity + self.gravity * dt
	end
	
    -- Predict next position
    local nextPos = self.position + self.velocity * dt
    local hit = false

	local rayOrigin = nextPos
	local rayDirection = vector.create(0, -self.radius + 0.2, 0)
	
    local rayParams = RaycastParams.new()
    rayParams.FilterType = Enum.RaycastFilterType.Include
    rayParams.FilterDescendantsInstances = {workspace.Map}

    local rayResult = Workspace:Raycast(rayOrigin, rayDirection, rayParams)
    if rayResult then
        
		self.position = vector.create(nextPos.X, rayResult.Position.Y + self.radius, nextPos.Z)
		self.velocity = vector.create(self.velocity.X, -self.velocity.Y * self.bounce, self.velocity.Z) * self.friction

		hit = true

		if math.abs(self.velocity.Y) <= self.originalY then
			self.velocity = vector.create(self.velocity.X * self.friction, self.originalY, self.velocity.Z * self.friction)
			hit = false
		end
		
		if not self.firstTouch then
			self.firstTouch = true
		end
		
		self.grounded = true
	else
		if (self.position - nextPos).Magnitude <= 0.1 then
			self.resting = true
			self.ball:AddTag("Resting")
			self.ball.PrimaryPart.Anchored = true
			hit = false
		end
		
        self.grounded = false
        self.position = nextPos
	end
	
	local horizontalVelocity = vector.create(self.velocity.X, 0, self.velocity.Z)
	if horizontalVelocity.Magnitude >= 0.1 then
		local wallRayOrigin = self.position
		local wallRayDirection = horizontalVelocity.Unit * self.radius
		local wallRayParams = RaycastParams.new()
		wallRayParams.FilterType = Enum.RaycastFilterType.Include
		wallRayParams.FilterDescendantsInstances = {workspace.Map}

		local wallRayResult = Workspace:Shapecast(self.ball.PrimaryPart, wallRayDirection, wallRayParams)
		if wallRayResult then
			hit = true
			
			if wallRayResult.Position.Y == self.originalY then
				hit = false
			end

			local normal = wallRayResult.Normal
			local incoming = horizontalVelocity
			local reflected = incoming - 2 * incoming:Dot(normal) * normal
			
			self.velocity = vector.create(reflected.X, self.velocity.Y, reflected.Z) * self.bounce * self.friction
			self.position = wallRayResult.Position + normal
		end
	end

	if (self.grounded and (self.lastPosition - self.position).Magnitude <= 0.1) then
        self.resting = true
		self.ball:AddTag("Resting")
		self.ball.PrimaryPart.Anchored = true
		hit = false
	end

	self.ball:MoveTo(self.position)
	
    return hit
end
1 Like

Nevermind i just add some raycast checks lol

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.