Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

How do you make the npc's rootpart rotate a certain amount without breaking the npc?

So I'm making a game that it top-view and I've reset the movements to only be left & right to rotate the character.

I made a script that makes it so every time the player presses a key the checkTurn() function plays. In the checkTurn() function, it will check if the player pressed "A" or "LeftArrow" (if so, calls the turn("left") function) or if the player has pressed "D" or "RightArrow" (if so, call the turn("right") function)

The turn function accepts one param - direction. The direction is either "right" or "left". The turn function will then rotate the player in whichever direction was specified.

After the if statements of checkTurn() the while statements loop until the player releases the keys.

(I'm aware that if the player presses "A" and then while still holding "A" if they make another input it will stack the loops - I'll fix that next)

I'm currently editing the "left" direction of the turn() function. RIght was what left used to be and is more controllable, but I noticed it wasn't really turning fast enough. I decided to make it so "Left" moved faster by changing some things - and it definitely goes faster - it is just way less controllable.

I'm newish to CFrames so my CFrame math might be super wrong so there is also that.

Here is my current code: It is a local script inside the Game.StarterPlayer.StarterCharacterScripts folder.

local RunService = game:GetService("RunService") --Gets run service
local Players = game:GetService("Players") --Gets player service
local inputServ = game:GetService("UserInputService") --Gets inputservice! --Used for input
----------------
local localPlayer = Players.LocalPlayer --Gets the local player
local char = script.Parent --Gets the Player's Character
local rootP = char:WaitForChild("HumanoidRootPart") --Gets the npc's rootPart
local hum = char:WaitForChild("Humanoid") --gets npc's humanoid
------------------------------------------------------------
local turnAmt = 0.1 --The amount * the npc walkspeed that the npc will turn
--Will turn the character in the definied direction
function turn(direction)
	if direction == "left" then
		local turnAng = Vector3.new(0,hum.WalkSpeed*turnAmt,0) --Gets the ang the npc should turn.  
		--Rotate the humrootpart
		local rootPRot = rootP.Orientation --Gets rotation of root part
		local rot = rootPRot+turnAng --Adds the turnAng to the root part so we get the target ending rotation
		local cFAngleTurn = CFrame.Angles(0,math.rad(rot.y),0) --Turns the rot into a CFrame so it can be multiplied
		local endCFrame = rootP.CFrame * cFAngleTurn --Calculates the end CFrame of the rootPart
		local beforeCFrame = rootP.CFrame --Stores the current CFrame of the rootPart
		print("\nturnAmt:",turnAng,"rootPRot:",rootPRot,"\nrot:",rot,"\ncFAngleTurn:",cFAngleTurn,"\nbeforeCFrame",beforeCFrame,"\nendCFrame:",endCFrame) --For debugging
		rootP.CFrame = endCFrame --Sets the CFrame
	elseif direction == "right" then
		local turnAng = CFrame.Angles(0,math.rad(hum.WalkSpeed*turnAmt),0) --Gets the turnAng (as a CFrame.Angle)
		--Rotate the humrootpart
		local rootPRot = Vector3.new(rootP.CFrame:ToAxisAngle()) --Turns the rootPart current rotation into a CFrame.Angle so they can be added together
		local turnAmtAA = Vector3.new(turnAng:ToAxisAngle()) --Turns the turnAngle back into a Vector3
		local rot = rootPRot+turnAmtAA --Adds the currentRotation and the turnAmt rotation together to get the ending target rotation
		local cFAngleTurn = CFrame.Angles(math.rad(rot.x),-math.rad(rot.y),math.rad(rot.z)) --Turns the target ending rotation into a CFrame.Angle
		local endCFrame = rootP.CFrame * cFAngleTurn --Multiples CFrames to set the CFrame rotation
		rootP.CFrame = endCFrame --Sets the new rotation
	end
end
--Checks if the right keys are being pressed and if so turns it
--Also loops while the user continues to press key
function checkTurn(input)
	if input.KeyCode == Enum.KeyCode.A or input.KeyCode == Enum.KeyCode.Left then --A or LeftArrow was pressed
		--Rotate the humrootpart left
		turn("left")
	elseif input.KeyCode == Enum.KeyCode.D or input.KeyCode == Enum.KeyCode.Right then --D or RightArrow was pressed
		--Rotate the humrootpart right
		turn("right")
	end
	while inputServ:IsKeyDown(Enum.KeyCode.A) or inputServ:IsKeyDown(Enum.KeyCode.Left) or inputServ:IsKeyDown(Enum.KeyCode.D) or inputServ:IsKeyDown(Enum.KeyCode.Right) do
		wait(1)
		if inputServ:IsKeyDown(Enum.KeyCode.A) or inputServ:IsKeyDown(Enum.KeyCode.Left) then
			turn("left")
		else
			turn("right")
		end
	end
end 
inputServ.InputBegan:Connect(checkTurn)

I know it is probably bad, but if anyone could offer some help that would be great! Thanks.

1 answer

I found the issue - I was adding the rotation it should end at to the current rotation. In other words, I was doing current rotation + current rotation + turn. I just needed to do current rotation + turn.

ROT is not needed - it should just be the turn angle

This discussion is preserved as it was. New answers, comments, and votes are closed.