Trouble with CFrame rotation

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    I want to be able to rotate the player at a 90 degree angle to wherever I’m pointing my mouse to.

  2. What is the issue? Include screenshots / videos if possible!
    I rotate at a 90 degree angle to where the player is facing instead at where I’m pointing.

local move = meshes:WaitForChild("FireVortex")
local ra1 = move:WaitForChild("Red Aura 1")
local ra2 = move:WaitForChild("Red Aura 2")
local vortex = move:WaitForChild("Vortex")
local ya1 = move:WaitForChild("Yellow Aura 1")
local ya2 = move:WaitForChild("Yellow Aura 2")
debounce = false
canTouch = false

game.ReplicatedStorage.FireVortex.OnServerEvent:Connect(function(player, direction)
	local character = player.Character
	local getchar = character:GetChildren()
	local humanoid = character:WaitForChild("Humanoid")
	local humrp = character:WaitForChild("HumanoidRootPart")
	local newRa1 = ra1:Clone()
	local newRa2 = ra2:Clone()
	local newVortex = vortex:Clone()
	local newYa1 = ya1:Clone()
	local newYa2 = ya2:Clone()
	local weld1 = Instance.new("Weld", newRa1)
	local weld2 = Instance.new("Weld", newRa2)
	local weld3 = Instance.new("Weld", newVortex)
	local weld4 = Instance.new("Weld", newYa1)
	local weld5 = Instance.new("Weld", newYa2)
	local bodyVelocity = Instance.new("BodyVelocity", humrp)
	bodyVelocity.MaxForce = Vector3.new(math.huge,math.huge,math.huge)
	bodyVelocity.Velocity = direction.lookVector * 50 --(character.HumanoidRootPart.CFrame.lookVector*50)
	humrp.CFrame = humrp.CFrame * CFrame.Angles(math.rad(90),0,0) 
	for i, v in pairs(getchar) do
		if v:IsA("Part") then
			--character.HumanoidRootPart.Transparency = 1
			v.Transparency = 1
		end
		if v:IsA("Accessory") then
			v.Handle.Transparency = 1
		end
	end
	newRa1.Parent = workspace
	newRa2.Parent = workspace
	newVortex.Parent = workspace
	newYa1.Parent = workspace
	newYa2.Parent = workspace
	newRa1.Anchored = false
	newRa2.Anchored = false
	newVortex.Anchored = false
	newYa1.Anchored = false
	newYa2.Anchored = false
	newRa1.CanCollide = false
	newRa2.CanCollide = false
	newVortex.CanCollide = false
	newYa1.CanCollide = false
	newYa2.CanCollide = false
	newRa1.CFrame = humrp.CFrame
	newRa2.CFrame = humrp.CFrame
	newVortex.CFrame = humrp.CFrame
	newYa1.CFrame =  humrp.CFrame
	newYa2.CFrame = humrp.CFrame
	weld1.Part0 = newRa1
	weld1.Part1 = humrp
	weld2.Part0 = newRa2
	weld2.Part1 = humrp
	weld3.Part0 = newVortex
	weld3.Part1 = humrp
	weld4.Part0 = newYa1
	weld4.Part1 = humrp
	weld5.Part0 = newYa2
	weld5.Part1 = humrp
	--humrp.CFrame = CFrame.new((humrp.CFrame + CFrame.new(0,0,-3)).p,direction.p)
	while wait()do
		newRa1.CFrame = newRa1.CFrame * CFrame.Angles(0, 0.2, 0)
		newRa2.CFrame = newRa2.CFrame * CFrame.Angles(0, 0.2, 0)
		newVortex.CFrame = newVortex.CFrame * CFrame.Angles(0, 0.2, 0)
		newYa1.CFrame = newYa1.CFrame * CFrame.Angles(0, 0.2, 0)
		newYa2.CFrame = newYa2.CFrame * CFrame.Angles(0, 0.2, 0)
		local DamageAmount = 15
		newVortex.Touched:Connect(function(hit)
			local hum = hit.Parent:FindFirstChild("Humanoid")
			if hum and canTouch == false then
				print(hit.Parent)
				if hit.Parent.Name ~= player.Name then
					canTouch = true
					print(hit.Parent)
					hum.Health = hum.Health - DamageAmount
					wait(2)
					canTouch = false
				end
			end
			wait(2)
			newRa1:Destroy()
			newRa2:Destroy()
			newVortex:Destroy()
			newYa1:Destroy()
			newYa2:Destroy()
			bodyVelocity:Destroy()
			humrp.CFrame = humrp.CFrame * CFrame.Angles(0,0,0)
			for i, v in pairs(getchar) do
				if v:IsA("Part") then 
					v.Transparency = 0
					character:WaitForChild("HumanoidRootPart").Transparency = 1
				end
				if v:IsA("Accessory") then
					v.Handle.Transparency = 0
				end
			end
			
		end)
	end
end)
  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    Youtube videos, Roblox dev forum

Can you send a video of what it’s supposed to look like, because I’m not entirely sure what you’re trying to get across. Do you want the player to only rotate at 90 degree increments?

https://gyazo.com/990a517afcfb7bdff023cf8245793a7b

https://gyazo.com/990a517afcfb7bdff023cf8245793a7b

So in the first spin it makes me spin all over the place when I come into contact with things. The second spin is what I want
but I want it like that for every direction I point at.

So essentially you just want to rotate with the mouse cursor?

Also the gifs are the same gif

No so in the code, I already rotate. I just want to rotate forward to wherever I point at instead of rotating wherever Roblox says forward is if that makes sense. And sorry about that here is the other Gyazo.

https://gyazo.com/9c379f4c73105904d671ddf641d401cf

You can use CFrame.lookAt to get the CFrame with the rotation you want.

 CFrame.lookAt( RootPart.Position , Target.Position  )
1 Like

Alright so I played with some things for a while, but here’s what I have and it’s pretty smooth:

local UIS = game:GetService("UserInputService") --Not necessary, just what I used for testing
local RS = game:GetService("RunService")

local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:wait()
local humanoid = character:WaitForChild("Humanoid")
local RootPart = character:WaitForChild("HumanoidRootPart")
local mouse = player:GetMouse()

UIS.InputBegan:connect(function(input,processed)
	
	if processed then return end
	
	if input.KeyCode == Enum.KeyCode.F then
		
		local BG = Instance.new("BodyGyro")
		BG.D = 500 --Play with this number
		BG.MaxTorque = Vector3.new(0,1e5,0) --Makes it so that the movement is strictly left to right
		BG.CFrame = RootPart.CFrame
		BG.Parent = RootPart
		
		local RSconn
		RSconn = RS.Heartbeat:Connect(function()
			BG.CFrame = CFrame.new(RootPart.Position,mouse.Hit.p) --Update the orientation to which the RootPart is moving to
		end)
		
		UIS.InputEnded:connect(function(input)
			if input.KeyCode == Enum.KeyCode.F then --Just a placeholder input
				RSconn:Disconnect()
				BG:Destroy()
				return
			end
		end)
	end
end)

Of course, you don’t at all need the entire code, just mainly the Body Gyro and RunService bits. Another thing you could do, though, is make this a separate local script and have the script disabled until you need the rotation

How would I define the target? I just want them to go forward for a specific time not a position.

So I put it into the local script where I have the key down function so now it looks like this

local Players = game:GetService("Players")
local userinput = game:GetService("UserInputService")
local Player = game.Players.LocalPlayer
local debounce = false
local Mouse = Player:GetMouse()
local character = Player.Character 
local Torso = character:WaitForChild("HumanoidRootPart")
local RS  = game:GetService("RunService")

userinput.InputBegan:Connect(function(input, gameproccessed)
	if gameproccessed then return end
	if input.UserInputType == Enum.UserInputType.Keyboard then
		if input.KeyCode == Enum.KeyCode.J and debounce == false then
			debounce = true
			print("Vortex")
			game.ReplicatedStorage.FireVortex:FireServer(Mouse.hit)
			local BG = Instance.new("BodyGyro", Torso)
			BG.D = 500 --Play with this number
			BG.MaxTorque = Vector3.new(0,1e5,0) --Makes it so that the movement is strictly left to right
			BG.CFrame = Torso.CFrame
			local RSconn
		RSconn = RS.Heartbeat:Connect(function()
			BG.CFrame = CFrame.new(Torso.Position,Mouse.Hit.p) --Update the orientation to which the RootPart is moving to
				wait(2)
				RSconn:Disconnect()
				BG:Destroy()
		end)
			wait(7)
			debounce = false
		end
	end
end)

But I also have this in the server script

local meshes = game.ServerStorage.Elements:WaitForChild("Fire Element")
local move = meshes:WaitForChild("FireVortex")
local ra1 = move:WaitForChild("Red Aura 1")
local ra2 = move:WaitForChild("Red Aura 2")
local vortex = move:WaitForChild("Vortex")
local ya1 = move:WaitForChild("Yellow Aura 1")
local ya2 = move:WaitForChild("Yellow Aura 2")
debounce = false
canTouch = false

game.ReplicatedStorage.FireVortex.OnServerEvent:Connect(function(player, direction)
	local character = player.Character
	local getchar = character:GetChildren()
	local humanoid = character:WaitForChild("Humanoid")
	local humrp = character:WaitForChild("HumanoidRootPart")
	local newRa1 = ra1:Clone()
	local newRa2 = ra2:Clone()
	local newVortex = vortex:Clone()
	local newYa1 = ya1:Clone()
	local newYa2 = ya2:Clone()
	local weld1 = Instance.new("Weld", newRa1)
	local weld2 = Instance.new("Weld", newRa2)
	local weld3 = Instance.new("Weld", newVortex)
	local weld4 = Instance.new("Weld", newYa1)
	local weld5 = Instance.new("Weld", newYa2)
	local bodyVelocity = Instance.new("BodyVelocity", humrp)
	bodyVelocity.MaxForce = Vector3.new(math.huge,math.huge,math.huge)
	bodyVelocity.Velocity = direction.lookVector * 50 --(character.HumanoidRootPart.CFrame.lookVector*50)
	humrp.CFrame = humrp.CFrame * CFrame.Angles(math.rad(90),0,0) 
	
	--CFrame.lookAt(humrp.Position, )
	for i, v in pairs(getchar) do
		if v:IsA("Part") then
			--character.HumanoidRootPart.Transparency = 1
			v.Transparency = 1
		end
		if v:IsA("Accessory") then
			v.Handle.Transparency = 1
		end
	end
	newRa1.Parent = workspace
	newRa2.Parent = workspace
	newVortex.Parent = workspace
	newYa1.Parent = workspace
	newYa2.Parent = workspace
	newRa1.Anchored = false
	newRa2.Anchored = false
	newVortex.Anchored = false
	newYa1.Anchored = false
	newYa2.Anchored = false
	newRa1.CanCollide = false
	newRa2.CanCollide = false
	newVortex.CanCollide = false
	newYa1.CanCollide = false
	newYa2.CanCollide = false
	newRa1.CFrame = humrp.CFrame
	newRa2.CFrame = humrp.CFrame
	newVortex.CFrame = humrp.CFrame
	newYa1.CFrame =  humrp.CFrame
	newYa2.CFrame = humrp.CFrame
	weld1.Part0 = newRa1
	weld1.Part1 = humrp
	weld2.Part0 = newRa2
	weld2.Part1 = humrp
	weld3.Part0 = newVortex
	weld3.Part1 = humrp
	weld4.Part0 = newYa1
	weld4.Part1 = humrp
	weld5.Part0 = newYa2
	weld5.Part1 = humrp
	--humrp.CFrame = CFrame.new((humrp.CFrame + CFrame.new(0,0,-3)).p,direction.p)
	while wait()do
		newRa1.CFrame = newRa1.CFrame * CFrame.Angles(0, 0.2, 0)
		newRa2.CFrame = newRa2.CFrame * CFrame.Angles(0, 0.2, 0)
		newVortex.CFrame = newVortex.CFrame * CFrame.Angles(0, 0.2, 0)
		newYa1.CFrame = newYa1.CFrame * CFrame.Angles(0, 0.2, 0)
		newYa2.CFrame = newYa2.CFrame * CFrame.Angles(0, 0.2, 0)
		local DamageAmount = 15
		newVortex.Touched:Connect(function(hit)
			local hum = hit.Parent:FindFirstChild("Humanoid")
			if hum and canTouch == false then
				print(hit.Parent)
				if hit.Parent.Name ~= player.Name then
					canTouch = true
					print(hit.Parent)
					hum.Health = hum.Health - DamageAmount
					wait(2)
					canTouch = false
				end
			end
			wait(2)
			newRa1:Destroy()
			newRa2:Destroy()
			newVortex:Destroy()
			newYa1:Destroy()
			newYa2:Destroy()
			bodyVelocity:Destroy()
			humrp.CFrame = humrp.CFrame * CFrame.Angles(0,0,0)
			for i, v in pairs(getchar) do
				if v:IsA("Part") then 
					v.Transparency = 0
					character:WaitForChild("HumanoidRootPart").Transparency = 1
				end
				if v:IsA("Accessory") then
					v.Handle.Transparency = 0
				end
			end
			
		end)
	end
end)

Now should I take out the body velocity in the server script and leave the bodygyro in the local script. It still doesn’t rotate at a 90 degree angle in the direction that I point at and maybe I was clear. I was trying to say I wanted to make the player parallel to the ground and turn him 90 degrees that way the vortex spins horizontally instead of vertically. And I want it to be this way for wherever I point at.

1 Like

I played around with it for quite a bit, but I can’t really seem to get the orientation I think you’re looking for:


What I personally would do instead is make it so that you:

  1. Make the vortex part, make the root part the parent and then add a body position to it to align it with the character in the orientation you want (possibly using a body gyro as well) through script in #2.

  2. Make a script that sets/creates the body position and gyro object to match that of the character, and then make a while loop so that the part is constantly orienting in a specific direction and then make a local script for moving the player.

Once the move is over, simply destroy the part, body velocities/gyros, and any left over objects. Through this method you don’t have to orient the character in a weird way but rather just make them invisible.

Again, that’s just what I’d personally do, but I believe it’d be an easier way of doing it.

Alright thanks will try it and let you know

You’re welcome, hopefully it works

So I think I got what you were saying. Should I take off the welding to my root part and just weld the parts together, then I would use body position to align myself with the vortex right?

Essentially, yeah. The body position will keep it in the same place as the root part and the gyro will maintain the orientation so its facing the right way.

I recommend these properties:

-->> Body Position
BP.D = 250 --Again, play with this, but don't bring it too low or too high
BP.MaxForce = Vector3.new(1e5,0,1e5) --The Y is 0 because you don't want any up and down movement (unless you do, then you can change it)
BP.P = 1e4 --You can play with this a little bit as well, but somewhere between 1000-5000 is good, do some experimenting
BP.Position = RootPart.Position --It's important you update the BP.Position when the RootPart's orientation is changed (in the RunService function)

-->> Body Gyro
BG.CFrame = RootPart.CFrame --Important this is updated along with BP.Position
BG.D = 250 --Not too low or high
BG.MaxTorque = Vector3.new(1e5,0,1e5) --Y is 0 for same reason
BG.P = 1e4 --Once again, not too low or high, but toy around with it

With these values it’s important to keep in mind that the lower the MaxTorque/Force, the less likely you are to encounter some weird physics glitches. Though you can afford to increase them a bit, try to keep them as low as possible. Of course, however, none of these are required and if you find some values that work better then go ahead and use those (just be cautious). Good luck :happy1:

Just incase you want to read up on them:

Char:SetPrimaryPartCFrame(CFrame.new(Position,Direction)*CFrame.new(0,0,spin))

1 Like

This really helped thanks man.

No problem, glad I could help. Good luck on future projects :happy1: