TurretController - CFrame based Joint Instance mover

You Know This is a Great little Feature. I should keep this in my notes to add for my game when Martian Mode comes out as a heat ray guide.

1 Like

Heyo, good news the bug is fixed :confetti_ball:

Bug quote

Videos:

Before:

After:

Yeah, it was really annoying to solve I spent hours guessing and checking solutions until I had the nerve to write down the issue and visualize what was actually happening but it’s solved now.

Whitebackground messy image+explanation

dios mios

Yeah, I had to detect the quadrant of the CFrame.lookAt starting from the jointPosition instead of the attachment position because at the attachment position the Z axis which determines the quadrants is very finicky during the scenario.

		--Detect quadrant of lookAt position
		local jointPosition = currentJointMotor6D.Part0.CFrame*originalC0Position
		local quadrantLookAtFromJointPosition = CFrame.lookAt(jointPosition,lookAtPosition,baseCFrame.UpVector)	
		local baseRelative = baseCFrame:ToObjectSpace(quadrantLookAtFromJointPosition)
		local _,y, _ = baseRelative:ToOrientation()
		constrainedY = math.abs(constrainedY)*math.sign(y)--use the quadrants of the lookAtFromJoint

Anyway, I’m currently hoping to give this controller more physics like oomph through the use of PID. Send help if possible in this scripting support post. But yeah hope to see your creations soon if you used this resource!

2 Likes

New update PID Controller thanks to @ThanksRoBama Thanks RoBama. Allows your turrets to behave physics like without using the physics engine for maximum reliability.

It even works for cases where the yaw or pitch constraint is zero:

1 Like

Hello!
It’s me again.
While using the module, how would one make it target the closest target if there are multiple ones?
I was thinking- creating a table in the workspace and putting all the targets there.
Then I would make the loop through the table and use magnitude to find the distance of each target compared to the origin. Then target each one based on proximity.

Do you think this is a good idea?

image
Here is something I cooked up,
It doesn’t seem to be working obviously.

The original intent was to loop through the workspace and target anything named Target within range.

I probably did something stupid or my method shouldn’t be used at all.

any advice?

Yeah the first issue is that you are not changing the goalPosition, even if it does detect the closest enemy correctly it’ll still point towards the Target part in the workspace and not v: part or kill : part.

But yeah your idea is on point though I believe you meant origin is the position of the turret and not the world origin at (0,0,0).

For a question like this, I suggest researching further on the topic, after some research I found that @Quasiduck has already written a function to find the closest part within a table of parts so it should work though you can organise it differently, perhaps using collection services instead to get table of all the parts labeled as the enemy.

Once you found the closest enemy/object/part you can then start using this turret controller to look at that part. I recommend doing this if you are using the turret controller with lerping or with a PID controller.

local closestEnemyPosition
local arbritraryDirection 
RunService.Heartbeat:Connect(function(step)
--Find the closest enemy.
closestEnemyPosition = findClosestEnemy() or Vector3.new(0,0,-1)-- You decide what to do if there are no enemy positions to look at and what position the turret will look at.
	GunHead:LookAt(closestEnemyPosition,step)
end)
1 Like

Is there a way to decipher how much elasticity is applied to the turrets? I’m trying to achieve a more smooth-tween transition from one orientation to another, without having it sway back and forth for a few seconds. Fantastic module though!

1 Like

I believe you are using the PID controller and for that unfortunately not really. People get paid to tune PID systems and guess those three numbers to make it go exactly the way you want. The best I think we can do for now is to search online for a PID tuner simulator and just guess those values.

Otherwise perhaps a future update will be to use a spring module like in this I made post and apply it to the turret system to do something cool, that way it’s easier to control the dampening as it’s just a value from 0-1.

Edit: also there is a rotation issue currently if you set yaw left and yaw right to more than 90 degrees where it’ll just swoosh past the supposed constraint deadzone region because of how CFrame lerping works taking the shortest path. I’ll see if I can fix it when I get the time to do.

1 Like

Yup, I’ll mess with these values until I find a smoother transition.

Also yeah, I think I ran into that rotation issue a few times; luckily it wasn’t too big of an issue. I also noticed another bug where the turrets randomly started to randomly wiggle and rotate around. I wonder if this is just a flaw in the way I set up the turrets though.

1 Like

Nah not really, I intentionally left this bug here in order to see if anyone would notice it :wink:. The issue was the constraint quadrant checking which caused it to teleport around. You can get the latest version from the tool box or the GitHub repository above.

For the PID Tuning a simple website should be this one with a car example written in javascript. Play around with the values and see if they fit what you want them to, pretty fun.

2 Likes

Thanks so much, this site helped a lot! Found a good setting to use for the PID. :slight_smile:

For clarification, is that “bug” solved in the latest versions or do we have to fix it ourselves? Thanks again for all the help, I really appreciate it!

Yeah to further clarify the teleporting turret should be fixed in the latest version, you can view what changed in the GitHub.

The only remaining bug is this one which I don’t know the fix to currently which kinda sucks because you can’t get a constraint range of > 180°

1 Like

For some reason my turret is only using the LerpAlpha value for the speed and ignores AngularSpeed. Am I doing something wrong with my turret or is it meant to act how it is?

Turret: CANNON.rbxm (107.1 KB)

2 Likes

Wow, I have spent hours looking at this.

The issue is that the orientation of the base is (90,0,0) which messed up the EulerAngle clamping math somehow and forced the current look vector and current goal vector to be the same always.

image

This subsequently, messed up a lot of things mainly the CFrame lerping alpha value which made it equal to 1 so it always instantly looks at the target.

No idea what the fix is, but thanks for bringing it up.

1 Like

I re rigged it to only use 3 pieces like the example dummy and it works fine now. I’m guessing I rigged it wrong and it broke it or something

Hello, I am having some trouble making this work on a tool:

Code I am using:

local waistConstraints = {
	["YawLeft"] = 360;
	["YawRight"] = 360;
	["ElevationAngle"] = 360;
	["DepressionAngle"] = 360;
}

local TurretController = require(script.TurretController, true)

local waistController = TurretController.new(waist, waistConstraints)
waistController:LookAt(mouse.Hit.Position)

I believe the issue is due to the CFrame.lookAt which is being used internally:

CFrame.lookAt(turretPosition,lookAtPosition,baseCFrame.UpVector)--goal

For your case try removing the third parameter within the module script since for your usage case you don’t need to worry if the base of your CFrame will tilt (Most likely the humanoid will stay upright unlike other turret types).

Edit: Another method is to move the turret attachment a bit further back instead of putting it right at the gun barrel, put it behind the gun body.

1 Like

One question, since I cannot parent the turret attachment to the tool handle, I am looping it’s world position to another attachment in the tool barrel. Could this be causing the issue? None of the solutions that you proposed are working for me.

Edit: Moving the attachment behind the gun fixes only the part where it rotates like crazy, but it still doesn’t point the gun where it should.

Yeah this could possibly cause the issue depending on the sequence the WorldPosition gets updated, never tested it with this tool scenario hard to reproduce.

Might want to just modify the turret info property manually:

TurretController.TurretInfo = your attachment

Also in the video you are pointing right below, the waist where there’s a deadzone which could break the CFrame.lookat as mentioned before, that might also further contribute as well.

1 Like

Did his module break because I tried the RBXLX file from github and nothing moves at all. Am I doing it wrong?