Im trying to make a game where you drive a submarine using a key pad infront of the player, im using body angular velocity to rotate the submarine, but the problem is that the submarine rotates globally.
Yeah you can kind of do that.
Something like
local object_ang_vel = Vector3.new(pitch_dir, 0, -roll_dir).Unit
if object_ang_vel.X ~= object_ang_vel.X then object_ang_vel = Vector3.new() end
local world_ang_vel = sub.PrimaryPart.CFrame:VectorToWorldSpace(object_ang_vel)
ang_vel.AngularVelocity = world_ang_vel * ROTATE_MULT
The angular velocity is a vector that gets converted from the subs object space to world space using CFrame.VectorToWorldSpace
.
It’s got a few issues though. If you don’t update it perfectly in sync with the physics engine, it’s going to apply almost the right torque but not quite. This is especially problematic if you’ve got high angular velocities or very high torques. It causes it to not really control right and sometimes go out of control. At low values it totally works tho.
Fortunately you can use the new Constraint types instead of the old, deprecated BodyMovers to do exactly what you want. Just insert an AngularVelocity object
… and set RelativeTo to Attachment0.
My brain is too small to understand the script you put in, is there a more simplified version of this script?
A bit. Let me try to explain it. Here’s a simplified version:
local object_ang_vel = Vector3.new(pitch, yaw, roll)
local world_ang_vel = sub.PrimaryPart.CFrame:VectorToWorldSpace(object_ang_vel)
ang_vel.AngularVelocity = world_ang_vel
object_ang_vel
is the angular velocity you want the ship to have relative to itself, i.e. in its own object-space coordinates. You must convert that to world-space coordinates because that’s how BodyAngularVelocity works. This is done by calling VectorToWorldSpace
, which is a method that converts the vector that’s passed in as a parameter - from the object-space of CFrame that the method is called on - to world space. The CFrame that VectorToWorldSpace
is called on is the CFrame of the submarine.
Hope this helps a bit.
But really, you shouldn’t be using a BodyAngularVelocity for this. If you instead use an AngularVelocity like I described, you don’t have to convert anything. You just do
local object_ang_vel = Vector3.new(pitch, yaw, roll)
ang_vel.AngularVelocity = object_ang_vel
I tired using just Angular Velocity but another problem arose, after a little bit my submarine would just randomly stop rotating
Sounds like a different issue, AngularVelocity definitely works.