How do I go about with tank controls?

Hi, everyone.

So I’ve just been working on something to create a tank control system and so far I’ve got very basic movement working, but I’m stumped when I need to figure out how to make the player rotate when left and right keys are being pressed and make the forward movement be in relation to your rotation (as in, your character points to the edge of a wall, you hit the forward key, you go to the edge of the wall.)

I’ve attempted a basic way to rotate the HumanoidRootPart but that yielded unfavorable results, with the character floating in the air and becoming generally hard to control, no matter what axis is modified.

Here’s my code for the controlling localscript (adapted from some of GnomeCode’s controls for 2D but in 3D):

local player = game.Players.LocalPlayer
local RunService = game:GetService("RunService")
local ContextActionService = game:GetService("ContextActionService")

local leftValue, rightValue, forwardValue, backwardValue = 0, 0, 0, 0

local function OnLeft (actionName, inputState)
	if inputState == Enum.UserInputState.Begin then
		leftValue = 1
	elseif inputState == Enum.UserInputState.End then
		leftValue = 0
	end
end

local function OnRight (actionName, inputState)
	if inputState == Enum.UserInputState.Begin then
		rightValue = 1
	elseif inputState == Enum.UserInputState.End then
		rightValue = 0
	end
end

local function OnForward (actionName, inputState)
	if inputState == Enum.UserInputState.Begin then
		forwardValue = 1
	elseif inputState == Enum.UserInputState.End then
		forwardValue = 0
	end
end

local function OnBackward (actionName, inputState)
	if inputState == Enum.UserInputState.Begin then
		backwardValue = 1
	elseif inputState == Enum.UserInputState.End then
		backwardValue = 0
	end
end

local function OnUpdate()
	if player.Character and player.Character:FindFirstChild("Humanoid") then
		local moveDirectionZAxis = 0 -- just need to figure out what to do here
		local moveDirectionXAxis = forwardValue - backwardValue
		player.Character.Humanoid:Move( Vector3.new(moveDirectionXAxis, 0, moveDirectionZAxis), false )
	end
end

RunService:BindToRenderStep("Control", Enum.RenderPriority.Input.Value, OnUpdate)

ContextActionService:BindAction("Left", OnLeft, true, Enum.KeyCode.A, Enum.KeyCode.Left, Enum.KeyCode.DPadLeft)
ContextActionService:BindAction("Right", OnRight, true, Enum.KeyCode.D, Enum.KeyCode.Right, Enum.KeyCode.DPadRight)
ContextActionService:BindAction("Forward", OnForward, true, Enum.KeyCode.W, Enum.KeyCode.Up, Enum.KeyCode.DPadUp)
ContextActionService:BindAction("Backward", OnBackward, true, Enum.KeyCode.S, Enum.KeyCode.Down, Enum.KeyCode.DPadDown)

Any help would be appreciated, as I’ve attempted to see if anyone else has done it but information about it is few and far between in terms of public knowledge.

3 Likes

Figured it out with some help, and a mix of other questions on the dev forum so, yeah, here it is:

local player = game.Players.LocalPlayer
local RunService = game:GetService("RunService")
local ContextActionService = game:GetService("ContextActionService")


local leftValue, rightValue, forwardValue, backwardValue = 0, 0, 0, 0

local Xdirection, Zdirection, rotation = 0, 0, 0

local function OnLeft (actionName, inputState)
	if inputState == Enum.UserInputState.Begin then
		leftValue = 1
	elseif inputState == Enum.UserInputState.End then
		leftValue = 0
	end
end

local function OnRight (actionName, inputState)
	if inputState == Enum.UserInputState.Begin then
		rightValue = 1
	elseif inputState == Enum.UserInputState.End then
		rightValue = 0
	end
end

local moving = false
local movingback = false

local function OnForward (actionName, inputState)
	if inputState == Enum.UserInputState.Begin then
		moving = true
		movingback = false
		while moving do
		rotation = player.Character.HumanoidRootPart.Orientation.Y
		Xdirection = math.sin(0.0174532925*rotation)*-1
		Zdirection = math.cos(0.0174532925*rotation)*-1
		wait()
		end
		--forwardValue = 1
	elseif inputState == Enum.UserInputState.End then
		moving = false
		Xdirection = 0
		Zdirection = 0
		--forwardValue = 0
	end
end

local function OnBackward (actionName, inputState)
	if inputState == Enum.UserInputState.Begin then
		movingback = true
		moving = false
		while movingback do
		rotation = player.Character.HumanoidRootPart.Orientation.Y
		Xdirection = math.sin(0.0174532925*rotation)*-1*-1
		Zdirection = math.cos(0.0174532925*rotation)*-1*-1
		wait()
		end
	elseif inputState == Enum.UserInputState.End then
		movingback = false
		Xdirection = 0
		Zdirection = 0
	end
end

local function OnQuickTurn (actionName, inputState)
	if inputState == Enum.UserInputState.Begin then
		player.Character.HumanoidRootPart.CFrame *= CFrame.Angles(0, math.rad( 180 ), 0)
	elseif inputState == Enum.UserInputState.End then
		Xdirection = 0
		Zdirection = 0
	end
end

local function OnUpdate()
	if player.Character and player.Character:FindFirstChild("Humanoid") then
		player.Character.HumanoidRootPart.CFrame *= CFrame.Angles(0, math.rad( (leftValue - rightValue) * 2 ), 0)
		player.Character.Humanoid:Move( Vector3.new(Xdirection, 0, Zdirection), false )
	end
end

RunService:BindToRenderStep("Control", Enum.RenderPriority.Input.Value, OnUpdate)

ContextActionService:BindAction("Left", OnLeft, true, Enum.KeyCode.A, Enum.KeyCode.Left, Enum.KeyCode.DPadLeft)
ContextActionService:BindAction("Right", OnRight, true, Enum.KeyCode.D, Enum.KeyCode.Right, Enum.KeyCode.DPadRight)
ContextActionService:BindAction("Forward", OnForward, true, Enum.KeyCode.W, Enum.KeyCode.Up, Enum.KeyCode.DPadUp)
ContextActionService:BindAction("Backward", OnBackward, true, Enum.KeyCode.S, Enum.KeyCode.Down, Enum.KeyCode.DPadDown)

ContextActionService:BindAction("QuickTurn", OnQuickTurn, true, Enum.KeyCode.LeftControl, Enum.KeyCode.RightControl, Enum.KeyCode.ButtonR1)
2 Likes

also, almost forgot to put the script that stops your character from auto turning, have this.

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(char)
		local hum = char:WaitForChild("Humanoid")
		hum.AutoRotate = false
	end)
end)

(Put this in a separate non local script inside of ServerScriptService)

3 Likes

I hate to bump this, but I appreciate that you put this out here, but I ran into a bit of a problem. Whenever you try and move backwards, this happens:


I don’t wanna get in trouble for this but this would help a lot if anybody know’s what the problem is!

Did you put this code in a separate server side script inside ServerScriptService?

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(char)
		local hum = char:WaitForChild("Humanoid")
		hum.AutoRotate = false
	end)
end)

That’s what I forgot. Thanks lol.

1 Like