Ways to clamp this CFrame?

Hey all, I’m working on a tail inertia system for my game. I’ve got a script that creates a drag effect on my playables.

Everything looks good until you start spinning really fast, then the illusion is ruined. What’s some ways I can clamp this, and ensure these don’t over rotate?

Here’s my script. Any help is greatly appreciated!

--Services
local RunService = game:GetService("RunService")

--Player
local character = game.Players.LocalPlayer.Character
local root = character:WaitForChild("HumanoidRootPart")

--Other
local tailMotors = {}
local tailInertia = character:GetAttribute("TailInertia")
local lastCF = root.CFrame

for i,v in pairs(character:GetDescendants()) do
	if v:IsA("Motor6D") and v.Name == "TailMotor" then
		table.insert(tailMotors,v)
	end
end

if #tailMotors > 0 and tailInertia then
	RunService.RenderStepped:Connect(function(deltaTime)
		local currentCF = root.CFrame
		local lastRot = lastCF - lastCF.Position
		for i,v in pairs(tailMotors) do
			v.C0 = v.C0:Lerp(CFrame.new(v.C0.X,v.C0.Y,v.C0.Z) * lastRot:ToObjectSpace(currentCF - currentCF.Position):Inverse(),tailInertia * deltaTime)
		end
		lastCF = root.CFrame
	end)
else
	warn("Prerequisites not met; ending thread")
end
2 Likes

First you can simplify the goal CFrame formula

local goalCFrame = lastRot:ToObjectSpace(currentCF.Rotation):Inverse() + v.C0.Position
v.C0 = v.C0:Lerp(goalCFrame, tailInertia * deltaTime)

Then for the clamping just convert to orientation and clamp the orientation values, I’m not sure how your model is setup and which axis to rotate so you gotta play around that yourself.

local x, y, z = goalCFrame:ToOrientation()
--Remember this function returns in radians
newX = math.clamp(x, math.rad(someValue1), someValue)
local newClampedGoalCFRame = CFrame.fromOrientation(newX, y, z)
4 Likes