Im trying to rotate the player and keep this rotation, even if the player walks. I tried that, but the orientation resets after the player walks:
(ServerScript connected to event)
the server cannot edit the player model because the client has network ownership of it. so you have to rotate it on the client
its much better to do it on the client since it wont have a delay and will appear much smoother
you cannot just give the server network ownership, rotate, then give the client it back. since this will do nothing due to how roblox updates
you can either do this with PivotTo() of the entire model (you may get some weird positional errors) or like what you are doing before by just setting the root’s CFrame manually, both methods work since its the root part
@bluechristmas20181 SetPrimaryPartCFrame is deprecated, please do not use it. use PivotTo instead
But how would I make it visible to the server? FireAllClients would in your explanation not work, because other clients dont have ownership about that specifiq one
EDIT: I also tested it now with FireAllClients and even on the specifiq client it is not working.
May be but still doesnt fix the issue. Ill try now using a loop, maybe that works
EDIT: Yeah no that just makes me spin around, even if I try to do it with an if statement
task.spawn(function()
runService.Heartbeat:Connect(function(d)
if hrt.CFrame ~= hrt.CFrame * CFrame.fromEulerAnglesXYZ(math.rad(0), math.rad(90), 0) then
hrt.CFrame = hrt.CFrame * CFrame.fromEulerAnglesXYZ(math.rad(0), math.rad(90), 0)
end
end)
end)
It won’t work because you are using the root’s current CFrame, which means the if statement will always be true, also I would use :GetPivot(). Since you want to keep this initial rotation, try doing something like this:
local character = hrt.Parent
character:PivotTo(character:GetPivot() * CFrame.fromEulerAnglesXYZ(0, math.rad(90), 0)
local initialRot = character:GetPivot().Rotation -- this is the rotation we wanna keep
task.spawn(function()
runService.Heartbeat:Connect(function()
local currentCF = character:GetPivot()
if currentCF.Rotation ~= initialRot then -- check if the rotation is correct
character:PivotTo(initialRot + currentCF.Position) -- maintains rotation but keeps the position
end
end)
end)
One slight problem with the script I showed above: what if the player dies? The script would lose reference to the character and as such currentCF would become nil each time. If you want to keep the rotation even after the player dies, then you should replace character with this function:
-- get the player
local playerService = game:GetService("Players")
local player = playerService:GetPlayerFromCharacter(hrt.Parent)
-- function to get the character
local function getChar()
if player == nil then return end
return player.Character or player.Character:Wait() -- yields until player's character respawns
end
How silly of me, I forgot this was supposed to be running on the server, so my bad. Even tho the client has network ownership over the character, the server can still rotate it, the problem is the delay in communication (ping). It may look like extreme rubberbanding, but no, the character is not stuck and can be moved, really slowly nevertheless. The correct way to do this would be with a local script, and I put it in one function like this:
local runService = game:GetService("RunService")
local player = game.Players.LocalPlayer
local function lockRotation()
local character = player.Character or player.CharacterAdded:Wait()
character:PivotTo(character:GetPivot() * CFrame.fromEulerAnglesXYZ(0, math.rad(90), 0))
local initialRot = character:GetPivot().Rotation -- this is the rotation we wanna keep
runService.Heartbeat:Connect(function()
character = player.Character or player.CharacterAdded:Wait()
local currentCF = character:GetPivot()
if currentCF.Rotation ~= initialRot then -- check if the rotation is correct
character:PivotTo(initialRot + currentCF.Position) -- maintains rotation but keeps the position
end
end)
end
task.wait(5)
lockRotation() -- lock from this point on
I tested it in Studio this time, and if you ignore the occasional flicking of 1-2 parts of the character when it dies, the script works perfectly.
I’m curious, what is the looping animation you are using? How is it ‘way smoother’ than correcting the rotation every frame? And I’m really excited to look at a simpler method to lock a model’s orientation!
The Animation makes it smoother when equipping and you dont have that flicking. You can just make an Animation and at TimeStamp 0 and like second2 you insert the exact KeyFrames you want to achieve, loop it, and set the AnimationPriority to Action or sth higher. Then its just simple:
EDIT: Dont forget to dont add/change the leg KeyFrames or youll overwrite the Roblox`s one and you would need to make one for it which is not hard, but unnessesary
Local Script:
local ID = script.Parent.Animation
local anim = game.Players.LocalPlayer.Character.Humanoid:LoadAnimation(ID)
local tcooldown = false --Ignore that
script.Parent.Equipped:Connect(function(mouse)
event.Equip:FireServer(true)
anim:Play()
end)
script.Parent.Unequipped:Connect(function(mouse)
event.Equip:FireServer(false)
anim:Stop()
end)
It works like this:
With the High AnimationPriority, the Animation KeyFrames of the Default Roblox Character are being overwritten. But since I added no KeyFrames to the leg, the default walking animation will not be overwritten.
So it looks like this when standing:
And when walking:
The LocalScript is parented to a tool, but you should be able to do it everywhere, where LocalScripts can run (exp: StarterPlayerScripts or so)