function Main:CalculateShots(playerwhoshot : Player, typeofshot : string, charge : number,typee) : {Vector3}
local settings : NewSettings = self.Settings
if typeofshot ~= "shootend" then
return
end
local ball = game.Workspace:FindFirstChild("Ball")
if not ball and ball.Thrown.Value and ball.Player.Value ~= playerwhoshot.Name then return end
local CurrentPosition = (typee == "first" and playerwhoshot.Character.HumanoidRootPart.Position) or (typee == "10" and lastknownposition)
local class = playerwhoshot.Class.Value
local BaseForce = (class == "Duck" and 15) or (class == "Fat Bird" and 20) or (class == "Bird" and 25)
local Direction = ball.CFrame.RightVector
local Velocity : Vector3 = (typee == "first" and Direction * (charge * BaseForce) / settings.Normalize) or (typee == "10" and lastknownvelocity)
local positions = {}
local MaxBouncesCondition = (settings.MaxBounces == "BounceUntilFinished") and math.huge or settings.MaxBounces -- if bounce till finished then itll bounce till velocity is gone
local SlidingFriction = 0.7
for i = 1, 10 do
local NextPosition = CurrentPosition + Velocity * settings.TimeStep
if Velocity.Magnitude > 0.5 then
table.insert(positions, CurrentPosition)
Velocity = Velocity + Vector3.new(0, -game.Workspace.Gravity*0.28, 0) * settings.TimeStep
local raycastparams = RaycastParams.new()
raycastparams.FilterType = Enum.RaycastFilterType.Exclude
raycastparams.FilterDescendantsInstances = {ball, playerwhoshot.Character}
local RaycastResult = workspace:Spherecast(CurrentPosition, 1,NextPosition - CurrentPosition, raycastparams)
if RaycastResult then
local normal = RaycastResult.Normal
if math.abs(normal:Dot(Velocity)) < 0.1 then -- Check if the ball is sliding (velocity parallel to normal)
Velocity = Velocity * SlidingFriction -- Apply sliding friction
else
Velocity = Velocity - 2 * Velocity:Dot(normal) * normal -- this reflects the velocity aka bouncing
Velocity = Velocity * settings.BounceDamping
print("bounce")
end
NextPosition = RaycastResult.Position
if math.abs(normal:Dot(Velocity)) >= 0.1 then -- Check if the ball bounced
self.Bounces = self.Bounces + 1
end
end
CurrentPosition = NextPosition
self.CurrentTime = self.CurrentTime + settings.TimeStep
end
end
lastknownposition = CurrentPosition
lastknownvelocity = Velocity
return positions
end
the script is returning 10 simulated positions every time the function is called, however, the ball falls through the floor after losing most of its velocity?
At the end as it calculates your next position to be next to the ball instead of below the ball, it most likely doesn’t detect the ground beneath the ball and lets your gravity force push the ball down again
It depends on how big your ball is (if the radius is bigger than 1 then probably not) but otherwise it should
After rereading your script however it looks like that your sliding friction part simply multiplies the velocity (which is pushed down by gravity) by the sliding force so I’m assuming it would just push the ball down anyways
local GroundRaycast = workspace:Raycast(CurrentPosition,Vector3.new(CurrentPosition.X,CurrentPosition.Y-2,CurrentPosition.Z) , raycastparams)
if GroundRaycast and Velocity.Magnitude< 1 then
Velocity = Velocity + 0*Settings.TimeStep (???)
end
for i = 1, 10 do
local NextPosition = CurrentPosition + Velocity * settings.TimeStep
if Velocity.Magnitude > 0 then
local raycastparams = RaycastParams.new()
raycastparams.FilterType = Enum.RaycastFilterType.Exclude
raycastparams.FilterDescendantsInstances = {ball, playerwhoshot.Character}
local GroundRaycast = workspace:Raycast(CurrentPosition,Vector3.new(0, -1.1, 0) , raycastparams)
table.insert(positions, CurrentPosition)
if GroundRaycast and Velocity.Magnitude < 1 then
Velocity = Velocity + Vector3.new(0, 0, 0) * settings.TimeStep
else
Velocity = Velocity + Vector3.new(0, -game.Workspace.Gravity*0.28, 0) * settings.TimeStep
end
local RaycastResult = workspace:Raycast(CurrentPosition, NextPosition - CurrentPosition, raycastparams)
if RaycastResult then
local normal = RaycastResult.Normal
if math.abs(normal:Dot(Velocity)) < 0.1 then -- Check if the ball is sliding (velocity parallel to normal)
Velocity = Velocity * SlidingFriction -- Apply sliding friction
else
Velocity = Velocity - 2 * Velocity:Dot(normal) * normal -- this reflects the velocity aka bouncing
Velocity = Velocity * settings.BounceDamping
end
NextPosition = RaycastResult.Position
if math.abs(normal:Dot(Velocity)) >= 0.1 then -- Check if the ball bounced
self.Bounces = self.Bounces + 1
end
end
CurrentPosition = NextPosition
self.CurrentTime = self.CurrentTime + settings.TimeStep
end
end
Check if you’re accidently making the next position NaN in any other bits of code because the parts usually disappear if you try set it’s position to NaN