Howdy! I followed this YouTube video on how to create a character kinematic look effect and I came across a twitching issue and I was wondering if anyone knew how to fix it?
local RunService = game:GetService('RunService')
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local Players = game:GetService('Players')
local parts = {}
function characterAdded(character)
task.wait()
local ik = Instance.new('IKControl')
ik.Type = Enum.IKControlType.LookAt
ik.ChainRoot = character.UpperTorso
ik.EndEffector = character.Head
ik.Target = parts[Players:GetPlayerFromCharacter(character)]
ik.Weight = .999
ik.Parent = character.Humanoid
end
function playerAdded(player)
local part = Instance.new('Part')
part.Anchored = true
part.CanCollide = false
part.CanQuery = false
part.CanTouch = false
part.Transparency = .5
part.Parent = workspace
parts[player] = part
if player.Character then
characterAdded(player.Character)
end
player.CharacterAdded:Connect(characterAdded)
end
for index,player in Players:GetPlayers() do
playerAdded(player)
end
Players.PlayerAdded:Connect(playerAdded)
function playerRemoving(player)
parts[player]:Destroy()
parts[player] = nil
end
Players.PlayerRemoving:Connect(playerRemoving)
function renderStepped(dt)
for player,part in parts do
if not player.Character then continue end
part.Position = player.Character.Head.Position + player:GetAttribute('LookVector') * 10
--part.Position = player.Character.Head.Position + Vector3.new(0,2,0) + player:GetAttribute('LookVector') * 20
end
end
RunService.RenderStepped:Connect(renderStepped)
I appreciate the comment and instruction from the man himself! Unfortunately my math is terrible and I don’t know how to do what you suggested…
If I go with the mirror option, is this what you mean?
function renderStepped(dt)
for player,part in parts do
if not player.Character then continue end
--part.Position = player.Character.Neck.Position + player:GetAttribute('LookVector') * 20
local angle = math.acos(
math.clamp(workspace.CurrentCamera.CFrame.LookVector:Dot(player.Character.HumanoidRootPart.CFrame.LookVector),-1, 1))
local backwards = false
if angle > math.pi/2 then
backwards = true
end
part.Position = player.Character.Neck.Position + Vector3.new(0,2,0) + player:GetAttribute('LookVector') * (backwards and -10 or 10)
end
end
RunService.RenderStepped:Connect(renderStepped)
I’d prefer your first option. I’m not going to ask you to write it for me but maybe you could point me in the right direction?
so in the video we cover using dot inside the Look localscript that’s inside StarterPlayerScripts
so we do the same thing and by using dot we can work out the angle by doing camera.CFrame.LookVector:Dot(humanoidRootPart.CFrame.LookVector)
this will give us a value between 1 and -1
1 meaning 0 degrees
0 meaning 90 degrees
-1 meaning 180 degrees
so if we set the ik.Weight = 1 + dot
this will set the Weight to
2 at 0 degrees
1 at 90 degrees
0 at 180 degrees
and because ik.Weight has a maximum value of 1 it will clamp the value down to 1 so the ik will end up having
1 at 0 degrees
1 at 90 degrees
0 at 180 degrees
here is the final code
local runService = game:GetService("RunService")
local parts = {}
local iks = {} -- add a table so we can access each characters IK easily
local function CharacterAdded(character)
task.wait()
local ik = Instance.new("IKControl")
ik.Type = Enum.IKControlType.LookAt
ik.ChainRoot = character.UpperTorso
ik.EndEffector = character.Head
ik.Target = parts[game.Players:GetPlayerFromCharacter(character)]
ik.Parent = character.Humanoid
iks[character] = ik -- when we create the IK add it to the table
character.Humanoid.Died:Wait() ik:Destroy() -- TEMP FIX
end
local function CharacterRemoving(character)
iks[character] = nil -- when the character is removed remove the IK from the table
end
local function PlayerAdded(player)
local part = Instance.new("Part")
part.Anchored = true
part.CanCollide = false
part.CanQuery = false
part.CanTouch = false
part.Transparency = 1
part.Parent = workspace
parts[player] = part
if player.Character ~= nil then CharacterAdded(player.Character) end
player.CharacterAdded:Connect(CharacterAdded)
player.CharacterRemoving:Connect(CharacterRemoving) -- we must now keep track of when a character is removed
end
local function PlayerRemoving(player)
parts[player]:Destroy()
parts[player] = nil
end
for i, player in game.Players:GetPlayers() do PlayerAdded(player) end
game.Players.PlayerAdded:Connect(PlayerAdded)
game.Players.PlayerRemoving:Connect(PlayerRemoving)
runService.RenderStepped:Connect(function(deltaTime)
for player, part in parts do
if player.Character == nil then continue end
local ik = iks[player.Character] -- get the characters IK from the table
if ik ~= nil then ik.Weight = 1 + workspace.CurrentCamera.CFrame.LookVector:Dot(player.Character.HumanoidRootPart.CFrame.LookVector) end -- use dot to workout the angle from the Camera and HumanoidRootPart and use that to set the Weight
part.Position = player.Character.Head.Position + player:GetAttribute("LookVector") * 10
end
end)