Rotating Player not working

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)

hrt.CFrame = hrt.CFrame * CFrame.fromEulerAnglesXYZ(math.rad(0), math.rad(90), 0)

Try

PlayerCharacter:SetPrimaryPartCFrame(PlayerCharacter:GetPrimaryPartCFrame()*CFrame.fromEulerAnglesXYZ(math.rad(0), math.rad(90), 0)

Where PlayerCharacter is the character’s model.

P.S. I currently don’t have access to studio, so it isn’t fully checked.

1 Like

Same result als my method with using the HumanoidRootPart. After starting to walk, the char is rotating back to normal

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.

event.Equip.OnClientEvent:Connect(function(hrt)
	hrt.CFrame = hrt.CFrame * CFrame.fromEulerAnglesXYZ(math.rad(0), math.rad(90), 0)
end)

Roblox just overrides the rotation when walking, but there has to be a way without the use of animations

if you edit the player character on the client it will automatically replicate to the server. roblox already does that

1 Like

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)

its spinning you because you are constantly changing the cframe. that if statement is doing nothing because the cframe got updated

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

Hope this helps! :smile:

Does not work, it makes the char stuck at one place and makes it spinning weirdly.

char:PivotTo(char:GetPivot() * CFrame.fromEulerAnglesXYZ(math.rad(0), math.rad(90), 0))
		local root = char:GetPivot().Rotation
		task.spawn(function()
			runService.Heartbeat:Connect(function(d)
				local currCF = char:GetPivot()
				if currCF.Rotation ~= root then
					char:PivotTo(root + currCF.Position)
				end
			end)
		end)

How silly of me, I forgot this was supposed to be running on the server, so my bad. :skull: 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.

Yeap that works. However, I decided jsut to stick to a looping animation, that is way smoover and not that complicated.

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)

Does it interfere with the character’s walking animation? (also where did you put this script?)

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:
image
And when walking:
image

The LocalScript is parented to a tool, but you should be able to do it everywhere, where LocalScripts can run (exp: StarterPlayerScripts or so)

1 Like

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