TurretController - CFrame based Joint Instance mover

Could you explain in more detail I am rather confused sorry, also heres a video to give a better representation of my issue, Thanks for the help :smiley:

The lower torso bit rotates disallowing for the Cabin to face anywhere but while moving it works.

I also use the head motor6D for the controller and use Humanoid:Move to move the mech.

image

image

robloxapp-20210814-0055549.wmv (1.9 MB)

I believe if I deactivate the Motor maybe it’ll work? But then i’d have to use a weld which doesnt. I might put an animation on so it doesnt use the Motor. I’v done the same thing with a normal character and it works so im not sure why its not working.

Also I realise this sounds like a very basic question but how do I make the TurretController faster lol. Sorry for the simple question.

Hey, there is a bug when trying to limit the rotation. I was making my own turret rotation system when I noticed the turret would rotate through a prohibited angle when the limit is higher than 90, so I came here to see how you handeled that but I’ve noticed it happens here too.

In the vid you can see how the turret rotates around a prohibited area.

I am using :LookAt() in this case. :PIDLookAt() has weirder bugs.

The issue is the lerping method as CFrame lerp takes the shortest path hence crosses the prohibited zone. This is fixed in my private version of the module.

I found out that converting the CFrame to orientation then lerping the three numbers individually worked as the numbers respect the range.


local function lerp(start, goal, alpha)
	--we can use our super simple equation at the start, using the 3 values
	return start + (goal - start) * alpha
end
		local x1, y1, z1 = (currentRotation):ToOrientation()
		local x2, y2, z2 = (goalRotationCFrame):ToOrientation()
		local x3 = lerp(x1, x2, l1 or self.LerpAlpha)
		local y3 = lerp(y1, y2, l2 or self.LerpAlpha)
		local z3 = lerp(z1, z2, l3 or self.LerpAlpha)

This respects rotation as it takes the longest path from -180 to 180 instead of skipping it as the numbers.

However I also encountered an issue if the C0 or C1 is rotated as C0 needs to have no rotation at CFrame.new() hence I did not update the module with it yet. I believe this will be fixed with my better C0 formula but I will see what happens later.

I have also developed a newer method using Springs which is like the CFrame :LookAt() but bounces a bit for visual effect. I will include it in the newer version once I fix the orientation bug.

1 Like

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