Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

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

Asked by 4 years ago

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

Log in to vote
0
Answered by 4 years ago
Edited 4 years ago

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

Ad

Answer this question