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.
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.
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)