Rotating a turret that's welded to a bigger object/NPC with weld.C0

I’ve been working on a mother ship boss battle for one of my games and I’ve been trying to cframe a turret that is welded to the mothership so that it will face where the player is at the current time when it fires a blast at the player. I wrote this little script below as a demo of what I’ve been trying but I’m not quite sure how I would go about rotating the turret that’s welded with C0. I’ve noticed that the line below “partA.Weld.C0 = CFrame.Angles(math.rad(0), math.rad(0),math.rad(0))” will let me rotate the turret even though it’s still welded to the mothership, like for example if I changed it to “partA.Weld.C0 = CFrame.Angles(math.rad(0), math.rad(50),math.rad(0))” then It would move the welded turret right and negative 50 would turn it left. The issue I have now is, say my variable “detect” is the player, I’d want to make the turret face the direction of that part.but I’m not sure how or what I’d need to do to get the 3 numbers to plug into the angle Cframe. If anyone has any tips or help on how I’d be able to do this that would be great!

local detect = game.Workspace.DetectMe
local partA = script.Parent.Turret1.TurretBase

partA.Weld.C0 = CFrame.Angles(math.rad(0), math.rad(0),math.rad(0))
1 Like

I recommend switching to this method mentioned in this post: https://devforum.roblox.com/t/whats-the-most-efficient-way-to-attach-model-to-players-hand-anything-else/334624/7

I looked into that forum post and the one thing that makes me turn away from it is that it seems to just attach the accessory in a certain direction depending on the player it’s attached to. It looks like it would be great for an RPG game attaching weapons to the player and what not but the thing is I want to rotate the turret on the mother ship to face the player that’s flying around in space ship and the turret is going to be shooting like every second. I’m also not exactly sure how I could make the turret face the player by going through that method.

You can get a CFrame that points towards another position with just two vectors:

local newCFrame = CFrame.new(OriginPosition, TargetPosition)

I’ve tried this and it works, that is if you want the entire npc to look at that certain direction. I tried this with the turret welded to the mother ship and it just won’t work. Idk if I’m doing something wrong or what

As mentioned above, a CFrame pointing from position A to position B can be found with CFrame.lookAt(origin, target, upVector)

But this does not give you a useful result, either! This would be good if the turret were free-standing in the air and not mounted on a spaceship, or if the turret’s CFrame were `CFrame.new(). This is because it does not account for the orientation of the spaceship it’s mounted on.

The way to fix this is to work in the coordinate space of the turret, to make the turret the center of the world, not the origin point (0,0,0)

Relative to the turret, the player is located at turret.CFrame:PointToObjectSpace(targetVector3)
This will return a Vector3 that’s in the turret’s space, as if the turret were the center of the world.
If the player is exactly 20 studs in front of the turret, then this will be something like (0, 0, 20) regardless of where in the world the turret or player are.
You may then use CFrame.lookAt(Vector3.new(), target.Position) to get a CFrame that’s ready to be put into C0 or C1 (not sure which).

Edit: The code above works just as well as the code below does, because (0, 1, 0) is already “up” in turret space

(None of this has been tested, please tell me when something isn’t as I expected when writing this)

You might notice that the turret faces the right way, but it’s twisted in some random direction.
This is because CFrame.lookAt is missing some information it would like to have when constructing the orientation; namely, which way is up.
To fix this, you will need the direction that’s considered “up” for the turret’s base. If the turret is mounted flat on the ground, then (0, 1, 0) will do and is already the default. But for a spaceship that can turn and tumble, you will probably need the upVector of the spaceship’s body. Or you may add an Attachment that faces some direction that’s considered up, and use its lookVector or upVector.

When you have the up vector, you use CFrame.lookAt(origin, target, upVector) to get the CFrame that points from the turret to the player.
But wait, that’s what you had earlier! It points in some weird, but correlated direction!
That’s because it’s in world space. To get the real CFrame, you put it into the space of the turret:

turret.CFrame:ToObjectSpace(CFrame.lookAt(origin, target, upVector))

(or should turret.CFrame and the other CFrame be switched?)

2 Likes

Thanks for responding! This was exactly what I was looking for!
I’ve been up all night working on this boss battle and I’ve been stumped on this for hours! It’s 9am for me now and I really need to get some sleep, but I’m going to go over this again first thing when I wake up and give it another shot! I’ll let you know how it goes! Thanks again for responding I really appreciate it!