BodyGyro Orientation?

Hi, I’m currently working with BodyGyros for my SpaceShips. They way these are being utilised is that when a Player selects a Planet to ‘warp’ to, the BodyGyro rotates into the direction.

I’ve ran into issues however where the warp sequence is beginning before the rotation is complete. Is there any way to detect when the Ship is facing its targeted destination befote beginning movement?

Would a simple tweening be capable of doing this?

Or would it be easier to RayCast directly infront of the starship until the desired destination is noted, following this, begin movement?

1 Like

Tweening would make more mess in your code. You would need 3 teens back to back for one full rotation. I would stick with bodygyro and maybe just use a wait() with the max amount of seconds the ship has to turn. You could also maybe play with the power .P of the bodygyro.

Using Tweens could I not just Tween the CFrame as: CFrame.new(Base.CFrame, Destination.Position)?

Yes, but keep in mind that the tween will go the fastest route to its destination, which may be a desirable effect for you. If you want to spin full rotations however this works against you.

If I remember my legacyBodyMovers correctly, a BodyGyro has a CFrame you can change.
While I would recommend using new constraints, you can make the ship face to a planet then wait until the bodygyro has turned to it with this code:

BodyGyro.CFrame = CFrame.new(BodyGyro.CFrame.Position, Planet.Position)
repeat 
    wait()
until Ship.CFrame == BodyGyro.CFrame

There are ways you can improve this, such as a check that makes it within a range so that it doesn’t need to be exact.
Here is a simple function for checking if a number is within a range:

function IsWithinRange(N0,N1,Range)
    return N0 > N1 - Range and N0 < N1 + Range
end

You can then use CFrame:components() and check each one if it’s within 0.0872665 (5 degrees), and once all of them are within it you can send the ship on it’s way. Please excuse any errors as I am writing this pretty late at night without much testing.

2 Likes

Hi! I’ve started working with your method and it’s proven helpful!
I was wondering if you can elaborate on this method? I’m new to working with Maths per say and would like to try to implement this.

Thanks!

From the devhub:
CFrame documentation
Components returns the values: x, y, z, R00, R01, R02, R10, R11, R12, R20, R21, R22, where R00-R22 represent the 3x3 rotation matrix of the CFrame, and xyz represent the position of the CFrame.
The check within the range was to make it not need to be exact (As that could take a while to actually complete, even if its 0.0000001 off, BodyGryo.CFrame == Ship.CFrame will return false.)
Example check code:

function CheckWithRange(Range)
    local CF1 = {BodyGyro.CFrame:components()}
    local CF2 = {Ship.CFrame:components()}
    local WithinRange = 0
    for i,v in pairs(CF1) do
        if IsWithinRange(v, CF2[i], Range) then
            WithinRange = WithinRange + 1
        end
    end
    return WithinRange == #CF1 --All numbers are close enough
end

The 0.0872 is ~5 degrees in radians, which is what CFrames use. For conversion to degrees and from, use math.rad / math.deg. If you want to get 5 degrees in radians, use math.rad(5), and for converting back into degrees use math.deg(0.0872).
CFrames are complex, but once you get how they work you can do a lot with them.

2 Likes

Can I bump this as I’m having issues.

I’ve tried using the method shown above however it won’t work?