I ran into an problem with my collider for the gravity controller I have been modifying, by EgoMoose, and some reason the BodyGyro is having an conflict with Shiftlock causing an weird rotation problem going to left or right the third image shows character standing but need that to work with the wall surfaces
What I am trying to achieve is an wall walking for Naruto game I am working on and is an feature required.
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local Importances = require(script.Parent.Importances)
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Whitelist
local params2 = RaycastParams.new()
params2.FilterType = Enum.RaycastFilterType.Blacklist
-- CONSTANTS
local CUSTOM_PHYSICAL = PhysicalProperties.new(0.7, 0, 0, 1, 100)
local SLATE_PHYSICAL = PhysicalProperties.new(0.75, 0.05, 0, 1, 90) -- Balanced for slate
-- FIXED: Material-specific gyro settings
local MATERIAL_GYRO_SETTINGS = {
[Enum.Material.Slate] = {P = 22000, MaxTorque = Vector3.new(85000, 85000, 85000)},
[Enum.Material.Ice] = {P = 18000, MaxTorque = Vector3.new(70000, 70000, 70000)},
[Enum.Material.Water] = {P = 15000, MaxTorque = Vector3.new(60000, 60000, 60000)},
-- Default settings for other materials
Default = {P = 25000, MaxTorque = Vector3.new(100000, 100000, 100000)}
}
local ColliderClass = {}
ColliderClass.__index = ColliderClass
ColliderClass.ClassName = "Collider"
-- Public Constructors
function ColliderClass.new(controller)
local self = setmetatable({}, ColliderClass)
self.Model = Instance.new("Model")
local sphere, vForce, floor, floor2, gyro = create(self, controller)
self._maid = Importances.Maid.new()
self.Controller = controller
self.Sphere = sphere
self.VForce = vForce
self.FloorDetector = floor
self.JumpDetector = floor2
self.Gyro = gyro
self.HRP = controller.Character.HumanoidRootPart
-- FIXED: Track last material for optimization
self._lastMaterial = nil
self._lastPhysicalProperties = nil
self._lastGyroSettings = nil
-- FIXED: Track rotation state to prevent unwanted changes
self._targetRotation = nil
self._rotationLocked = false
init(self)
return self
end
-- Private Methods
local function getHipHeight(controller)
if controller.Humanoid.RigType == Enum.HumanoidRigType.R15 then
return controller.Humanoid.HipHeight + 0.05
end
return 2
end
local function getAttachement(controller)
if controller.Humanoid.RigType == Enum.HumanoidRigType.R15 then
return controller.HRP:WaitForChild("RootRigAttachment")
end
return controller.HRP:WaitForChild("RootAttachment")
end
function create(self, controller)
local hipHeight = getHipHeight(controller)
local attach = getAttachement(controller)
local sphere = Instance.new("Part")
sphere.Name = "Sphere"
sphere.Massless = true
sphere.Size = Vector3.new(2, 2, 2)
sphere.Shape = Enum.PartType.Ball
sphere.Transparency = 1
sphere.CustomPhysicalProperties = CUSTOM_PHYSICAL
local floor = Instance.new("Part")
floor.Name = "FloorDetector"
floor.CanCollide = false
floor.Massless = true
floor.Size = Vector3.new(2, 1, 1)
floor.Transparency = 1
local floor2 = Instance.new("Part")
floor2.Name = "JumpDetector"
floor2.CanCollide = false
floor2.Massless = true
floor2.Size = Vector3.new(2, 0.2, 1)
floor2.Transparency = 1
-- Floor detector weld
local weld = Instance.new("Weld")
weld.C0 = CFrame.new(0, -hipHeight, 0.1)
weld.Part0 = controller.HRP
weld.Part1 = sphere
weld.Parent = sphere
-- Floor detector weld
local weld2 = Instance.new("Weld")
weld2.C0 = CFrame.new(0, -hipHeight - 1.5, 0)
weld2.Part0 = controller.HRP
weld2.Part1 = floor
weld2.Parent = floor
-- Jump detector weld
local weld3 = Instance.new("Weld")
weld3.C0 = CFrame.new(0, -hipHeight - 1.1, 0)
weld3.Part0 = controller.HRP
weld3.Part1 = floor2
weld3.Parent = floor2
local vForce = Instance.new("VectorForce")
vForce.Force = Vector3.new(0, 0, 0)
vForce.ApplyAtCenterOfMass = true
vForce.RelativeTo = Enum.ActuatorRelativeTo.World
vForce.Attachment0 = attach
vForce.Parent = controller.HRP
local gyro = Instance.new("BodyGyro")
gyro.P = 25000
gyro.MaxTorque = Vector3.new(100000, 100000, 100000)
gyro.CFrame = controller.HRP.CFrame
gyro.Parent = controller.HRP
-- Initialize touched connections
floor.Touched:Connect(function() end)
floor2.Touched:Connect(function() end)
-- Parent parts to model
sphere.Parent = self.Model
floor.Parent = self.Model
floor2.Parent = self.Model
return sphere, vForce, floor, floor2, gyro
end
function init(self)
self._maid:Mark(self.Model)
self._maid:Mark(self.VForce)
self._maid:Mark(self.FloorDetector)
self._maid:Mark(self.Gyro)
self.Model.Name = "Collider"
self.Model.Parent = self.Controller.Character
end
-- FIXED: Helper function to get appropriate physical properties
local function getPhysicalPropertiesForMaterial(material)
if material == Enum.Material.Slate then
return SLATE_PHYSICAL
elseif material == Enum.Material.Ice then
return PhysicalProperties.new(0.5, 0.02, 0, 1, 120)
elseif material == Enum.Material.Water then
return PhysicalProperties.new(0.4, 0, 0, 1, 150)
else
return CUSTOM_PHYSICAL
end
end
-- FIXED: Helper function to get gyro settings for material
local function getGyroSettingsForMaterial(material)
local settings = MATERIAL_GYRO_SETTINGS[material]
return settings or MATERIAL_GYRO_SETTINGS.Default
end
local CameraModule = nil
local function getCameraModule()
if not CameraModule then
local success, result = pcall(function()
local playerScripts = player:WaitForChild("PlayerScripts")
local playerModule = playerScripts:WaitForChild("PlayerModule")
return require(playerModule:WaitForChild("CameraModule"))
end)
if success then
CameraModule = result
end
end
return CameraModule
end
-- FIXED: Helper function to check if shift lock is active
local function isShiftLockActive()
-- Try to get mouse lock status from CameraModule first (most reliable method)
local cameraModule = getCameraModule()
if cameraModule and cameraModule.activeMouseLockController then
local success, isLocked = pcall(function()
return cameraModule.activeMouseLockController:GetIsMouseLocked()
end)
if success then
return isLocked
else
warn("Didn't success and failed!")
end
end
-- Fallback to UserGameSettings
local userGameSettings = UserSettings():GetService("UserGameSettings")
if userGameSettings then
return userGameSettings.RotationType == Enum.RotationType.CameraRelative
end
-- Final fallback: mouse position method
local mouse = player:GetMouse()
if mouse then
local screenCenter = Vector2.new(mouse.ViewSizeX/2, mouse.ViewSizeY/2)
local mousePos = Vector2.new(mouse.X, mouse.Y)
local distanceFromCenter = (mousePos - screenCenter).Magnitude
return distanceFromCenter < 5
end
return false
end
-- Public Methods
function ColliderClass:Update(force, cframe, isMoving)
if not self.HRP then warn("HRP is nil in ColliderClass:Update") return end
if not self.VForce then warn("VForce is nil in ColliderClass:Update") return end
if not self.Gyro then warn("Gyro is nil in ColliderClass:Update") return end
-- Material-based physics adjustments
local standingPart = self:GetStandingPart()
local currentMaterial = standingPart and standingPart.Material or nil
if currentMaterial ~= self._lastMaterial then
self._lastMaterial = currentMaterial
local newPhysicalProperties = getPhysicalPropertiesForMaterial(currentMaterial)
if newPhysicalProperties ~= self._lastPhysicalProperties then
self._lastPhysicalProperties = newPhysicalProperties
self.Sphere.CustomPhysicalProperties = newPhysicalProperties
end
end
local gyroSettings = getGyroSettingsForMaterial(currentMaterial)
self.Gyro.P = gyroSettings.P
self.Gyro.MaxTorque = gyroSettings.MaxTorque
self.Gyro.CFrame = cframe
-- Simplified force application
if not isMoving then
local currentVelocity = self.HRP.AssemblyLinearVelocity or self.HRP.Velocity
local gravityUp = self.Controller._gravityUp or Vector3.new(0, 1, 0)
local characterMass = self.Controller._characterMass or 50
local horizontalVelocity = currentVelocity - currentVelocity:Dot(gravityUp) * gravityUp
if horizontalVelocity.Magnitude > 0.05 then
local dampingStrength = 800
local horizontalDamping = -horizontalVelocity * characterMass * dampingStrength * 0.01
force = force + horizontalDamping
end
end
-- Apply force with reasonable limits
local forceMagnitude = force.Magnitude
if forceMagnitude > 10000 then
force = force.Unit * 10000
end
self.VForce.Force = force
self._targetRotation = cframe
end
function ColliderClass:IsGrounded(isJumpCheck)
local detector = isJumpCheck and self.JumpDetector or self.FloorDetector
if not detector then return false end
local parts = detector:GetTouchingParts()
for _, part in pairs(parts) do
if not part:IsDescendantOf(self.Controller.Character) and part.CanCollide then
return true
end
end
return false
end
function ColliderClass:GetStandingPart()
if not self.Controller._gravityUp then return nil end
params2.FilterDescendantsInstances = {self.Controller.Character}
local gravityUp = self.Controller._gravityUp
local rayOrigin = self.Sphere.Position
local rayDirection = -1.2 * gravityUp -- Slightly longer ray for better detection
local result = workspace:Raycast(rayOrigin, rayDirection, params2)
return result and result.Instance
end
-- FIXED: New method to reset rotation state
function ColliderClass:ResetRotationState()
self._targetRotation = nil
self._rotationLocked = false
end
-- FIXED: New method to lock rotation (useful for shift lock)
function ColliderClass:LockRotation(enabled)
self._rotationLocked = enabled
end
function ColliderClass:Destroy()
self._maid:Sweep()
end
return ColliderClass


