The lookVectors are printing properly, however despite the lookVector changing, the head of the second player stays in the same position, which hopefully helps narrow down the location of issue?
I also noticed a strange animation jitter with the functioning head, which I think is something I can handle later and very likely related to (but not caused by) this other issue.
Information dump since I have yet to get a response. I had a very long conversation on Discord with another scripter and they ultimately couldn’t help me. This is very important to me. I’ve been trying to figure this out for days and the lack of progress is causing extreme anxiety and ruining my motivation for the project as a whole.
Part transparency for head-turning has been turned to 0 to display the difference between Player 1 and Player 2. Once again had to post the clip on YouTube because of size limitations: https://www.youtube.com/watch?v=2tfcBaeeL64
Some screenshots of output errors that likely aren’t the cause (I think the issue is in the CharacterIKs script)
local event = game.ReplicatedStorage.Look
local lookVector = Vector3.zero
local eventTime = -math.huge
local scheduleEvent = false
workspace.CurrentCamera:GetPropertyChangedSignal("CFrame"):Connect(function()
game.Players.LocalPlayer:SetAttribute("LookVector", workspace.CurrentCamera.CFrame.LookVector)
if scheduleEvent == true then return end
if workspace.CurrentCamera.CFrame.LookVector:Dot(lookVector) > 0.99 then return end
local deltaTime = time() - eventTime
if deltaTime > 0.1 then
eventTime = time()
lookVector = workspace.CurrentCamera.CFrame.LookVector
event:FireServer(lookVector)
else
scheduleEvent = true
task.wait(0.1 - deltaTime)
scheduleEvent = false
eventTime = time()
lookVector = workspace.CurrentCamera.CFrame.LookVector
event:FireServer(lookVector)
end
end)
StarterPlayerScripts - CharacterIKs
local runService = game:GetService("RunService")
local parts = {}
local iks = {}
local function CharacterAdded(character)
repeat wait() until "Head"
local ik = Instance.new("IKControl")
ik.Type = Enum.IKControlType.LookAt
ik.ChainRoot = character:WaitForChild("Neck2")
ik.EndEffector = character:WaitForChild("Head")
ik.Target = parts[game.Players:GetPlayerFromCharacter(character)]
ik.Parent = character.Humanoid
iks[character] = ik
character.Humanoid.Died:Wait() ik:Destroy()
end
local function CharacterRemoving(character)
iks[character] = nil
end
local function PlayerAdded(player)
local part = Instance.new("Part")
part.Anchored = true
part.CanCollide = false
part.CanQuery = false
part.CanTouch = false
part.Transparency = 0
part.Parent = workspace
parts[player] = part
if player.Character ~= nil then CharacterAdded(player.Character) end
player.CharacterAdded:Connect(CharacterAdded)
player.CharacterRemoving:Connect(CharacterRemoving)
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]
if ik ~= nil then ik.Weight = 1 + player:GetAttribute("LookVector"):Dot(player.Character.HumanoidRootPart.CFrame.LookVector) end
part.Position = player.Character.Head.Position - player:GetAttribute("LookVector") * 10
end
end)
I will definitely try to fix the errors ASAP for sure. I also went and sent a message to the person who originally made the tutorial and adjusted script (5uphi) and they said they’d take a look at it. Hopefully I can fix it soon haha
I don’t know how to adjust the script to make way for such a change.
While talking to 5uphi I adjusted some scripts, this post has details on how so.
This is what it looks like right now:
The script adjusted for these changes was the CharacterIKs script, however it is still having issues on the second client as seen on the video linked.
local runService = game:GetService("RunService")
local parts = {}
local iks = {}
local function CharacterAdded(character)
local ik = Instance.new("IKControl")
ik.Type = Enum.IKControlType.LookAt
ik.ChainRoot = character:WaitForChild("Neck2")
ik.EndEffector = character:WaitForChild("Head")
ik.Target = parts[game.Players:GetPlayerFromCharacter(character)]
ik.Parent = character.Humanoid
iks[character] = ik
character.Humanoid.Died:Wait() ik:Destroy()
end
local function CharacterRemoving(character)
iks[character] = nil
end
local function PlayerAdded(player)
local part = Instance.new("Part")
part.Anchored = true
part.CanCollide = false
part.CanQuery = false
part.CanTouch = false
part.Transparency = 0.5
part.Parent = workspace
parts[player] = part
if player.Character ~= nil then CharacterAdded(player.Character) end
player.CharacterAdded:Connect(CharacterAdded)
player.CharacterRemoving:Connect(CharacterRemoving)
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]
if ik ~= nil then ik.Weight = 1 + player:GetAttribute("LookVector"):Dot(player.Character.HumanoidRootPart.CFrame.LookVector) end
part.Position = player.Character:WaitForChild("Head").Position - player:GetAttribute("LookVector") * 10
end
end)
Hey there! After some testing, I think I’ve figured out the problem. I downloaded the file “Inverse_Kinematics_Dynamic_Weight.rbxl,” and it seems that when it’s in use, the other player’s character consistently looks down. The weird part is that it also shows on their screen that other players are looking down too.
I tried removing line 16 from the localscript “CharacterIKs,” and everything worked fine after that. I’ll share the Roblox place link below this message. Hope this helps with your urgent issue.
The reason for this issue is quite straightforward. By removing line 16, we address a problem with the “Character Added” function. This function essentially gets stuck, waiting for the character to die before moving on to the next set of codes. Consequently, the “RenderStepped” function doesn’t run as intended because it’s essentially halted on the “Character Added” function from line 16.
If you were to insert a print statement within the “RenderStepped” function, you’d notice that it consistently prints for one player, while for another player, it doesn’t. In essence, removing line 16 resolves this bottleneck and ensures the smooth execution of subsequent code, mitigating the issue you encountered.
To make sure that the “ik” variable is destroyed when the character dies, it’s better to use a humanoid.died function instead of waiting for it to happen.
Feel free to reach out if you have any more questions or need further clarification.
OH MY GOD IT WORKS
I seriously couldn’t figure out the issue by myself but you really saved me and my workflow. I made a few changes to your script (such as the onDied like you suggested) and tested it on a proper server with two different accounts and the head-turning is perfect. You’re my hero for this, thank you so much!!!
Of course!
and to any poor soul searching the internet for this oddly specific solution, this is the final script I ended up with. It probably isn’t the best, but it does the trick!
local runService = game:GetService("RunService")
local parts = {}
local iks = {}
local function CharacterAdded(character)
local ik = Instance.new("IKControl")
ik.Type = Enum.IKControlType.LookAt
ik.ChainRoot = character:WaitForChild("Neck2")
ik.EndEffector = character:WaitForChild("Head")
ik.Target = parts[game.Players:GetPlayerFromCharacter(character)]
ik.Parent = character.Humanoid
iks[character] = ik
local function onDied()
ik:Destroy()
end
end
local function CharacterRemoving(character)
iks[character] = nil
end
local function PlayerAdded(player)
local part = Instance.new("Part")
part.Anchored = true
part.CanCollide = false
part.CanQuery = false
part.CanTouch = false
part.Transparency = 0
part.Parent = workspace
parts[player] = part
if player.Character ~= nil then CharacterAdded(player.Character) end
player.CharacterAdded:Connect(CharacterAdded)
player.CharacterRemoving:Connect(CharacterRemoving)
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]
if ik ~= nil then ik.Weight = 1 + player:GetAttribute("LookVector"):Dot(player.Character.HumanoidRootPart.CFrame.LookVector) end
part.Position = player.Character:WaitForChild("Head").Position - player:GetAttribute("LookVector") * 10
end
end)
QUICK UPDATE TO ANYONE FOLLOWING THIS:
The head-turning will temporarily break if other players do not morph into the proper model. So I highly suggest forcing the player to automatically morph when they join the game, or figuring out how to fix that. (If you do figure it out, share those deets with me lol)