Limit rotation towards goal

I have a part moving in a loop, the part rotates to face its target, my problem is the rotation gets set automatically so it looks very unnatural. I want to change this so the part rotates a small amount every step of the loop, so it appears to rotate smoothly to face the direction of a target.

Visual example:

Code Snippet:

local castPos = cast:GetPosition()
local aim = CFrame.lookAt(castPos, target.Position, baseCFrame.UpVector)
		
local relativeDir = baseCFrame:VectorToObjectSpace(aim.LookVector)

Im basically trying to clamp the aim variable so it only slightly rotates to that direction.

You can lerp,

I have done something similar for my turret module.

There is also an extra formula to make it go constant speed by calculating the lerp alpha:

local adjustedLerpAlpha
		if step and self.ConstantSpeed then
			local angularDistance = VectorUtil.AngleBetween(currentRotation.LookVector,goalRotationCFrame.LookVector)
			local estimatedTime = self.AngularSpeed/angularDistance
			adjustedLerpAlpha = math.min(step*estimatedTime,1)
		elseif step then
			adjustedLerpAlpha = step
		end

		local newRotationCF = currentRotation:lerp(goalRotationCFrame, adjustedLerpAlpha or self.LerpAlpha)

		self.JointMotor6D.C0 = CFrame.new(originalC0Position)*newRotationCF

Modified something I made quite a while ago to make this, hopefully, it helps

local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()

local function QuaternionMultiplacation(Q1,Q2)
	local a1 = Q1[1]
	local a2 = Q2[1]
	local v1 = Q1[2]
	local v2 = Q2[2]
	local Q3 = {a1*a2-v1:Dot(v2),a1*v2+a2*v1+v1:Cross(v2)}
	return Q3
end
local function QuaternionAngleAxis(Axis, Angle, Vector)
	Angle = -Angle/2
	Axis = Axis.Unit
	local Cos = math.cos(Angle)
	local Sin = math.sin(Angle)
	local Q = {Cos,Axis*Sin}
	local U = {0,Vector}
	local Qp = {Cos,Axis*-Sin}
	local QU = QuaternionMultiplacation(Q,U)
	local QUQp = QuaternionMultiplacation(QU,Qp)
	return QUQp[2]
end

local Part = Instance.new("Part") -- the part to be rorated
Part.Parent = workspace
Part.Anchored = true
Part.Position = Vector3.new(0,4,0)

local Rate = math.rad(90) -- Degrees per second




RunService.RenderStepped:Connect(function(DT)
	local Current = Part.CFrame.LookVector.Unit
	local Goal = (Mouse.Hit.Position-Part.Position).Unit
	local Axis = Goal:Cross(Current).Unit
	if Axis == Axis then
		local AngleBetween = math.acos(math.min(Current:Dot(Goal),1))
		local Rotation = math.clamp(Rate*DT,0,AngleBetween)
		local NewVector = QuaternionAngleAxis(Axis,Rotation,Current)
		Part.CFrame = CFrame.lookAt(Part.Position,Part.Position+NewVector)
	end
end)
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.