Help with getting gun to point at player + math

Trying to get this turret to point at the player at all times. The nozzle of the turret is connected via HingeConstraints. I’ve managed to get the entire model to point in the direction of the player, but I need the gun to now rotate and point towards the player. This is what I currently have.

-- base refers to the top square, and tHumPart to the humanoidrootpart of the player
base.CFrame = CFrame.new(base.Position, Vector3.new(tHumPart.Position.X, base.Position.Y, tHumPart.Position.Z))

The problem is that the gun is still pointing toward the ground and is not following the player. I’m trying to figure out how to change the angle of the hinge constraints so that is can point towards the player. This is what I’ve tried, but it doesn’t appear to get the right angle.

-- nozzle is the little gun thing
local ground = workspace:Raycast(nozzle.Position, Vector3.new(0, -100, 0), params).Distance
local plrDist = RaycastToHrp(tHumPart, params).Distance

local tPos = tHumPart.Position
local nPos = nozzle.Position

local angle = math.deg(math.acos(ground / plrDist)) -- i think this is wrong
if tostring(angle) ~= "nan" then
	RotateGun(math.clamp(angle, 0, 90))
end

diagram203

PS: If you're wondering why I just don't get the nozzle to follow the root parts position

The base needs to stay as it is

nozzle.CFrame = CFrame.new(nozzle.Position, tHumPart.Position)

3 Likes

Is it ok if we get a rbxl file with just the turret and the code? It’s kinda hard to debug without knowing if there’s something wrong with the setup of the turret or RotateGun.

1 Like

Would prefer not, it’s simply just a matter of incorrect math on my part I think. All RotateGun does it set the two HingeConstraints to the given angle. That function definitely works fine, just the calculation of the angle that I’ve done is wrong.

Hello, I think I found the issue here. From what I can see, you’re trying to get the angle of a triangle consisting of the points of the ground, the player’s root, and the origin. The issue here is that the ground is not necessarily in line with the player’s root, meaning that no right triangle is formed, and the angle can’t be calculated this way.

image

(Assuming the angle is always based on y) The correct way to go about this would first be to get the vector between the origin and root. (rootP - originP) You can then use this vector’s negative (since we’re going down, have to invert it) Y component to get the adjacent’s length of the triangle. The hypotenuse would be the magnitude of this vector. Now that you have these two values, you can easily use inverse cosine to determine your angle!

local vector = tHumPart.Position - nozzle.Position
local y = -vector.Y

local angle = math.deg(math.acos(y/vector.Magnitude))

Edit: after rethinking, y can in fact be below 0 and will still be fine

2 Likes

Thanks for your response. This is the behaviour now, seems to be opposite of what it’s meant to be?

The angle measures seem accurate, so it could be the way that you are rotating the hinge. You may have to add/subtract 90 degrees to adjust to the angle’s standard position. Also, by the looks of it, it seems that the rotation may be based on radians (which could explain that weird jittering), so you can try removing the math.deg part.

1 Like

I did a lot of testing and this is the best formula I could come up with, it’s not pretty and will require you to adjust the math.rad value a bit to get it to work exactly as you wish, but it is locking the turret from rotating up and down while pointing the front face at the player like you wanted

cube.CFrame = CFrame.lookAt(cube.Position, tHumPart.Position) * CFrame.Angles(cube.Position:Angle(tHumPart.Position) + -math.rad(80), 0, 0)

The turret will still very slightly rotate up and down though unfortunately

1 Like

Actually with some more heavy testing the formula:

base.CFrame = CFrame.lookAt(base.Position, Vector3.new(tHumPart.Position.X, base.Position.Y, tHumPart.Position.Z))

is working correctly for me so I suspect the reason why you’re having so much trouble to rotate the turret as you wish is because the base itself isn’t orientated correctly. I recommend you follow the advice I previously gave you here:

because sometimes a problem is much easier to solve by building something a bit differently than it’s currently build rather than use complex trigonometry to try to solve it :slightly_smiling_face::+1:

1 Like

This only points the base in the players direction though, right? I need the turret gun hinge constraints to also change depending on the player’s position

This will solve the problem you have with the base rotating incorrectly. As for how to calculate the angle for the turret gun’s HingeConstraint, I wish I could help you but my math knowledge isn’t advanced enough to do so unfortunately

1 Like

I did some research and I found some useful information: If the base is rotating correctly, then the gun only needs to rotate up and down to point at the player. Due to this, we can use 2D math instead of 3D math since we’re dealing with only 1 axis so we only need triangle calculations

This website has an angle of a triangle calculator, and also shows the formulas you need to calculate them

1 Like

The HingeConstraints.TargetAngle is measured in degrees I believe.

The calculation shows the angle is 16, and the further away I get the angle increases. Shouldn’t it decrease the further away you get? It also appears the current angle isn’t equal the target angle, which may be part of the problem

Yea that seems useful. However, we are only dealing with two known sides, distance between the player and the turret (hypotenuse), and the distance from the ground. I believe the formula for that is -1cos(adjacent side / hypotenuse)?

Perhaps I need to find a better way of making a turret like this? I’ve observed that for some reason the parts that are connected by the HingeConstraints are delayed when the base is moved, so as a work around I was just welding those parts to the base, and then unwelding them. I don’t think this would work though when rotating the gun and base at the same time.

Maybe I need to change the way I’ve set up the turret, and use an alternative way without hinge constraints? I’ve found this video on youtube: https://www.youtube.com/watch?v=VUegcu8HSfM

I think maybe I should just get the nozzle to always point at the player, and somehow disconnect it from the rest of the base so the base doesn’t rotate, only the nozzle

Is the distance from the ground the orange arrow or the white arrow

White (silly char lmit blahblahblah)

If I’m not mistaken (I haven’t read all the posts yet) you can just use the CFrame.new(Position, LookPosition) to make an object/cframe point towards something. Then just use CFrame.angles and mutliply that with the CFrame you get for a rotational offset.

PS: If you’re wondering why I just don’t get the nozzle to follow the root parts position

I don’t think that should be an issue if you set the nozzle cframe manually.

1 Like

Yes, but the turret has two main parts. The base and the nozzle, the base does exactly what you said, but the nozzle needs to point towards the player using hinge constraints. Kinda hard to explain, but watch this video

image

What if instead of hinge constraints, you use a model and use the PivotTo() method of the model to set the primary CFrame of it?

1 Like