Sure! Do you need the place file?
local Raycast = require(RaycastModuleThingy)
--Physics.MACHINE_EPSILION = 0.02
export type Character = {
name: string,
bbox: Vector3,
position: Vector3,
velocity: Vector3,
modelPose: {
["RootJoint"]: {
C0: CFrame,
C1: CFrame
},
["Neck"]: {
C0: CFrame,
C1: CFrame
},
["Left Hip"]: {
C0: CFrame,
C1: CFrame
},
["Left Shoulder"]: {
C0: CFrame,
C1: CFrame
},
["Right Hip"]: {
C0: CFrame,
C1: CFrame
},
["Right Shoulder"]: {
C0: CFrame,
C1: CFrame
}
},
ownerUserId: number,
ownerOnly: {
jumpBias: number,
airControl: number,
airControlRecoveryDelay: number,
airControlLock: boolean,
grounded: boolean,
stance: number,
crouching : boolean,
health: number,
primaryFireBuffer: boolean,
secondaryFireBuffer: boolean,
jumpBuffer: boolean,
currentSlot: number,
inventory: {[number]: string},
},
serverOnly: {
healthDecay: number,
recentDamage: {[number]: number},
},
Think: Think,
Control: Control
}
Step = function(self: Character, fraction: number)
local ownerOnly = self.ownerOnly
local resolutionAttempts = 0
local maxAttempts = 16
local previousNormal = Vector3.zero
local stepDist = 1.1
local model = nil
local params = Raycast.newRaycastParams({model})
local previousPosition = self.position
repeat
resolutionAttempts += 1
local travel = self.velocity * Physics.DELTA_TIME * fraction
local flatTravel = Vector3.new(travel.X, 0, travel.Z)
local miniOffset = self.velocity.Unit * Physics.MACHINE_EPSILON
local sweepcastResult = Raycast:blockCast(self.position - miniOffset, travel + miniOffset, self.bbox, params)
if not sweepcastResult then
self.position += travel
if ownerOnly.grounded then
local groundStickCheck = Raycast:blockCast(self.position, Vector3.new(0, -stepDist - Physics.MACHINE_EPSILON, 0), self.bbox, params)
if groundStickCheck and groundStickCheck.Distance >= Physics.MACHINE_EPSILON and groundStickCheck.Normal.Y > module.MaxSlope then
self.position += groundStickCheck.Position + Vector3.new(0, Physics.MACHINE_EPSILON, 0)
end
end
break
else
if sweepcastResult.Normal.Y > module.MaxSlope then
if not ownerOnly.grounded then
--We just landed
ownerOnly.grounded = true
ownerOnly.airControlLock = false
print(self.position - miniOffset)
print(travel + miniOffset) --something like 0, -0.1923, 0
end
else
if ownerOnly.grounded then
local stepUpCast1 = Raycast:blockCast(self.position, Vector3.new(0, stepDist, 0), self.bbox, params)
if not stepUpCast1 then
local upPos = self.position + Vector3.new(0, stepDist, 0)
local stepUpCast2 = Raycast:blockCast(upPos, flatTravel, self.bbox, params)
if not stepUpCast2 then
local acrossUp = upPos + flatTravel
local stepUpCast3 = Raycast:blockCast(acrossUp, Vector3.new(0, -stepDist - Physics.MACHINE_EPSILON, 0), self.bbox, params)
if stepUpCast3 and stepUpCast3.Distance <= stepDist + Physics.MACHINE_EPSILON and stepUpCast3.Normal.Y > module.MaxSlope then
self.position = stepUpCast3.Position + Vector3.new(0, Physics.MACHINE_EPSILON, 0)
break
end
end
end
end
end
local position, normal = sweepcastResult.Position, sweepcastResult.Normal
self.position = position - miniOffset
self.velocity = Physics.ClipVector(self.velocity, normal) + (normal * Physics.MACHINE_EPSILON)
--If we are jammed between two spaces, then try to squeeze out
if previousNormal:Dot(normal) < 0 then
local comboNormal = (previousNormal + normal).Unit
self.velocity = Physics.ClipVector(self.velocity, previousNormal)
self.velocity = Physics.ClipVector(self.velocity, comboNormal) + (comboNormal.Unit) - miniOffset
self.velocity += (normal * Physics.MACHINE_EPSILON) + (comboNormal.Unit * Physics.MACHINE_EPSILON) - miniOffset
self.position += comboNormal.Unit * Physics.MACHINE_EPSILON
print("jammed!")
end
previousNormal = normal
end
if resolutionAttempts >= maxAttempts then
warn("Stuck! Giving up on collision resolution!")
end
until resolutionAttempts >= maxAttempts
--[[
if stuck then
self.position = previousPosition
end
]]--
end,