I’m writing my own collision response system. I want the player position to be set a certain distance away from the wall after colliding with it.
I’m projecting a spherecast a slight distance in front of the player (velocity * dt), and then setting the root.CFrame using the returned data.
The issue is on seemingly random frames, the player position is set closer to the wall than intended. Video:
I’ve also included a .rbxl file.
I know for sure this isn’t a result of the spherecast not being cast/not returning anything, because valid data can be returned and the jitter still occurs.
I know for sure it’s not linked the my use of dt, because even when the code is frame dependant (meaning * dt isn’t used at all) the jitter occurs.
This is the relevant code:
local function collide(vel: Vector2, pos: Vector3, dt: number)
-- convert velocity to vec3 so it can be used to spherecast
local velVec3 = Vector3.new(vel.X, 0, vel.Y)
-- speed moved per frame, so sphere can be cast in front of player (where you're about to be)
local extension = velVec3.Magnitude * dt
-- startPos is behind player because whatever is inside where the sphere is initially cast
-- isn't returned by the spherecast
local startPos = pos - velVec3.Unit * radius
local dir = velVec3.Unit * (radius + extension)
local raycastResult = workspace:Spherecast(startPos, radius, dir, raycastParams)
vis:SphereCast(startPos, radius, dir, raycastParams)
if raycastResult ~= nil then
local oldCFrame = root.CFrame
local newPosition = raycastResult.Position + (raycastResult.Normal.Unit * radius)
-- this SHOULD place the player at the edge of the sphere radius
root.CFrame = CFrame.new(newPosition) * oldCFrame.Rotation
else
print("nothing returned")
end
end
function update(_, dt)
local origin = root.Position
local moveDirection = Vector2.new(humanoid.MoveDirection.X, humanoid.MoveDirection.Z)
local targetVelocity
local deltaVelocity
local accelerationRate
targetVelocity = Vector2.new(moveDirection.X, moveDirection.Y) * 32
accelerationRate = if moveDirection.Magnitude > 0 then 10 else 4
deltaVelocity = targetVelocity - linearVelocity.PlaneVelocity
linearVelocity.PlaneVelocity += deltaVelocity * accelerationRate * dt
local velocity = Vector2.new(linearVelocity.PlaneVelocity.X, linearVelocity.PlaneVelocity.Y)
-- collisions
local getParts = workspace:GetPartBoundsInRadius(origin, radius, overlapParams)
if #getParts > 0 then
collide(velocity, origin, dt)
end
end
RunService.Stepped:Connect(update)
[jitter.rbxl|attachment](upload://hOignGjTKNqAxfVF6S08et8RrN6.rbxl) (59.6 KB)