TurretController - CFrame based Joint Instance mover

Hi, awesome module! very useful

However, i ran into some problems

First, for some reason, the torso seems to go a little bit “off” of the centre of the mouse position, you can see that in the gun’s laser. I dont know if its because of the player animations or is other thing.

Second is not a problem at all but is there a way to fix the torso’s horizontal movement when the player walks? That causes my gun to move to the sides and this module fixes vertical one (gun moves down) so im wondering if its possible with horizontal one

I used the resource you provided here

Im not very familiarized with this motor6d math, so a little explanation would really appreciated!

I hope you can help me, thank you!

1 Like

What do you mean by this? Got a video to share?

For the gun alignment it seems like @gpm231 was able to do it in the rbxl file there maybe try looking at it. The only issue was animations interfering.

1 Like

Sure, here it is

Notice how gun (torso actually) moves side to side

I tried the rbxl file, and seems like it has the same problem. Any way to fix it?

For a bit more context abount what i want to achieve, take a look at Jailbreak’s follow mouse

1 Like

It’s a lot more complicated to fix(Other bugs as well when looking straight at the middle), the shake is also caused by animations.
But I believe It’s fixed below:

Animation cancel + other fixes + orientation lerping @gpm231 :
GunLookAtDthe.rbxl (61.4 KB)

Honestly, I recommend everyone to make their own module, this one is getting pretty messy codewise TBH.

2 Likes

Thank you! Really helped out

Also i managed to fix the moving torso by changing a liiiitle bit the lower torso’s position in my weapon aiming animation

1 Like

So I am trying to do that and I think I got it, but there is one problem, having the thing aim correctly when the player changes orientation (it works well until the player starts walking):

I am using mouse.Hit.Position. The code I’m using is basically the one in the rbx file you attached here.

That formula only applies if you change a parts world CF instead of a C0 and C1.

The C0 and C1 maths is different.

1 Like

Oh my god. You will NOT believe how much time you saved me…

I can’t express how much I’m thankful for this
Thank you thank you thank you :pray:

1 Like

Is there any tutorial I can watch on how to use this. I am trying to create a turret using this module but I am having a hard time understanding what to do. This seems perfect for what I need it for

Hello again! I’m wanting to implement a lot of turrets handled individually by different players, and was wondering the best way to do this. I’ve came up with these options, and was looking for some guidance as to which I should go with:

  1. Server does calculations and tells client the data needed to rotate the turrets. (How would I get just the calculations on the server?)
  2. Server handles everything from calculations to rotating in a RunService loop.
  3. Client handles everything (may be exploitable).

Why does this keep happening? It always seems to happen with my pylon joints…

https://gyazo.com/143944ba5c98d9cb5b683b3569879d64
Always happens when im not using 180,-180 Yaw and limited Pitch

I just dont get it…

Seems to be a recursive CFrame loop just like doing:

part.CFrame *= part.CFrame

Usually caused by the Motor6D setup, try to make sure the Part0 is the base and Part1 belongs to the turret.

1 Like

As far as I can tell its correct, I even tried to Frankenstein it by putting the dummies head into the rig and reconnecting the rigs and motors still didnt work particularly well. Are the parts too big or something? or is there an issue with meshparts being used?

Or could this be an issue?

local PylonEvent = game.ReplicatedStorage.TSFWeapons.ServerEvents:WaitForChild("Pylon")
local WeaponTransfer = game.ReplicatedStorage.TSFWeapons.ServerEvents:WaitForChild("WeaponTransfer")
local TC = require(game.ReplicatedStorage.TurretController)

local timeStep

function initialiseMotor(pylon)
	local motor = pylon:FindFirstChild("Motor6DJoints").Pivot.Value
	local Constraints = {
		["YawLeft"] = 180,
		["YawRight"] = 180,
		["ElevationAngle"] = 90,
		["DepressionAngle"] = 90
	}
	
	local MotorControl = TC.new(motor,Constraints)
	return MotorControl
end

function turretAim(motor,target,pylon)
	local gimbalMotor = pylon:FindFirstChild("Pivot",true).Value
	local gimbalMotorOffset = gimbalMotor.C0
	task.spawn(function()
		--print(player,pylon,motor,target)

		repeat
			motor:PIDLookAt(target,timeStep)
			task.wait()
		until pylon:GetAttribute("Auto") == false
		gimbalMotor.C0 = gimbalMotorOffset
	end)
	
end

RS.Heartbeat:Connect(function(step)
	timeStep = step
end)

PylonEvent.OnServerEvent:Connect(function(player,hardpoint,Type)
	Player[player.Name] = {LTracks,RTracks,Motors}
	print("Recieved Message")
	print(hardpoint)
	print(Type)
	if Type == "Gun" then
		if hardpoint == "LP" then
			local pylon = player.Character:FindFirstChild("GunPylonL")
			local animator = pylon.AnimationController
			print(pylon:GetAttribute("Deployed"))
			if pylon:GetAttribute("Deployed") == false then
				print("Deployed")
				Player[player.Name][1]["Deploy"] = animator:LoadAnimation(animator.DeployLeft)
				Player[player.Name][1]["Deploy"]:Play()
				task.wait(Player[player.Name][1]["Deploy"].Length - 0.05)
				Player[player.Name][1]["Deploy"]:AdjustSpeed(0)
				pylon:SetAttribute("Deployed",true)
			elseif pylon:GetAttribute("Deployed") == true and pylon:GetAttribute("Auto") == false then
				print("Deployed Rear")
				Player[player.Name][1]["Deploy"]:Stop()
				Player[player.Name][3]["PivotL"] = initialiseMotor(pylon)
				Player[player.Name][1]["Rear"] = animator:LoadAnimation(animator.DeployRear)
				Player[player.Name][1]["Rear"]:Play()
				
				--task.wait(track.Length)
				--track:Stop()
				--pylon:SetAttribute("Deployed",false)
				pylon:SetAttribute("Auto",true)
				--aimAtTarget(player,pylon,nil,workspace.Target.Position)
				turretAim(Player[player.Name][3]["PivotL"],workspace.Target.Position,pylon)
			else
				print("Retracted")
				Player[player.Name][1]["Rear"] = animator:LoadAnimation(animator.DeployRear)
				Player[player.Name][1]["Rear"]:Play(0.100000001, 1, -1)
				task.wait(Player[player.Name][1]["Rear"].Length)
				Player[player.Name][1]["Rear"]:Stop()
				pylon:SetAttribute("Deployed",false)
				pylon:SetAttribute("Auto",false)
			end
--- other parts cut as unnecessary
end

im using this for my tank turret and sometimes the turret is slightly off and when on a ramp is off by a lot
do you have any idea how to fix this?

video:

code:

local gunbaseConstraints = {
	["YawLeft"] = 180,
	["YawRight"] = 180,
	["ElevationAngle"] = 0,
	["DepressionAngle"] = 0
}

gunConstraints = {
    ["YawLeft"] = 25,
    ["YawRight"] = 25,
    ["ElevationAngle"] = 0,
    ["DepressionAngle"] = 0
},

motor6d positions
image
attachment on the right is the BaseAttachment for the GunBase (connected to the GunBase Part)
attachment on the left is the TurretAttachment fro the GunBase (connected to the part below (the turretBase)
the motor line (using rig edit lite) is directly above each other


attachment on the right is the TurretAttachment for the Gun (connected to the Gun part)
attachment on the left is the BaseAttachment for the Gun (connected to the Gunbase)
the motor is on the BaseAttachment (the orange circle)

im using PIDLookAt(mouse.Hit.Position, dt) in the HeartBeat function on the server

i switched to the normal LookAt function and it fixed it but i was using PIDLookAt so i could control the speed of the movement so im still wondering how to control that without using PID

edit: after reading through the setup again and messing around with settings i figured it out

How can i reset players rotation with this, im making a gun system like this game Isle, 9 - Roblox
but i cant reset players rotation after he uneqiups the gun.
Can someone help me?

im trying to make the barrel of my tank not move to the mouse instantly and it works for 3 of the tanks but this one for some reason doesnt work

i printed what the angularDistance is and it saids zero even though when i printed the currentRotation.LookVector and goalRotationCFrame.LookVector they were different and no way VectorUtil would return 0 for the distance

image

the code has been unchanged from the original module, again this works with all my other tanks except this one. exact same attachment orientations. exact same barrel orientation and front face

any way to fix this?

edit: found the solution, there is a bug where if the par tthat is moving has a different orientation that isnt 0,0,0 it wont rotate right

save the motor c0 when you equip and before you use the LookAt function then use the saved motor c0 and reset it when you unequip

example:

local originalRightArmC0
local originalLeftArmC0

tool.Equipped:Connect(function()
    local plr = game.Players.LocalPlayer
    local char = plr.Character or plr.CharacterAdded:wait()
    originalRightArmC0 = char.Torso["Right Shoulder"].C0
    originalLeftArmC0 = char.Torso["Left Shoulder"].C0
end)

tool.Unequipped:Connect(function()
    local plr = game.Players.LocalPlayer
    local char = plr.Character or plr.CharacterAdded:wait()
    char.Torso["Left Shoulder"].C0 = originalLeftArmC0
    char.Torso["Right Shoulder"].C0 = originalRightArmC0
end)

Hey, so im a little confused, first of all i’ve got no idea what PID is, but from what i can tell its something with more options than the default module, but is there no way to change how quickly it turns without PID? And is there no way to only have it enabled for certain controllers?

Is there some kind of :Destroy() feature on the module?

1 Like