Best way to make parts rotate constantly without lag?

Currently in my game i have about ~20 objects that are rotating all the time for aesthetical purposes. I am doing this by adding functions with bindtorenderstep that rotate the cframe in a localscript. However when I do this for multiple parts the scripts start to lag. What is a good alternative?

4 Likes

Usually, using bodyforce objects result in less lag. For instance, you could use a bodygyro, and set the cframe of that with renderstep, allowing the bodygyro itself to rotate the object. There might be better methods, but that’s what came to mind for me :slight_smile:

Body position + Gyro… Setting the CFrame without rotation is the same as setting it with.

Alternately you could just rig a animation of it spinning at a constant rate. Ive had really good luck with that.

4 Likes

http://wiki.roblox.com/index.php?title=API:Class/BodyAngularVelocity

1 Like

If you’re using my tips from your previous thread then it should be pretty smooth, but if you’re still having problems you can try some alternatives.

Example

This contains an example of the anchored root part + Motor6D method. It’s set up just to test it out in Studio, but it can be adapted to run on a client.

EfficientRotation.rbxl (134.3 KB)

Meant to be run with regular run mode, not play solo:

image


Alternatives

Some goals:

  • No permanent drift. If you set “rotation 360 deg every 10 seconds”, then after 10 000 seconds (or any other large number) it should be very close to 360.
  • No temporary drift. The model should not temporarily slow down.
  • Set-and-forget. This requires your scripts to do the least amount of work by letting the engine handle everything
Solution No perm drift No temp drift Set-and-forget Easy
BodyGyro :white_check_mark: :no_entry_sign: :no_entry_sign: :white_check_mark:
BodyAngularVelocity :no_entry_sign: :no_entry_sign: :white_check_mark: :white_check_mark:
HingeConstraint with Motor ActuatorType :no_entry_sign: :no_entry_sign: :white_check_mark: Somewhat
HingeConstraint with Servo ActuatorType :white_check_mark: :no_entry_sign: :no_entry_sign: Somewhat
Set CFrame of root part with Motor6Ds and Welds :white_check_mark: :white_check_mark: :no_entry_sign: Somewhat
Animations :white_check_mark: :white_check_mark: :no_entry_sign: :no_entry_sign:
Looped Animations :question: :white_check_mark: :white_check_mark: :no_entry_sign:

Most likely it doesn’t matter to you if there is drift since these are just for aesthetic purposes.


BodyAngularVelocity

BodyAngularVelocity seems to be the easiest one to use here. You’ll still have to set up a weld/joint structure:

With a structure like that, you can stick a BodyAngularVelocity in the Root Part to rotate it. You’ll need a BodyPosition or AlignPosition to keep it in place, and a BodyGyro to keep it from turning on the axes you don’t want it to turn on.

  • A BodyPosition will require a script to set the Position property on start
  • An AlignPosition could allow you to rotate these parts without any scripts, but will require a separate, anchored root part and more setup.
Example using BodyPosition

RotationBodyAngularVelocityBodyPosition.rbxl (134.0 KB)

Notice how it slowed down in that last gfy? It has “drift”, and in this case, severe drift. Good thing, too, or the game would have been at a much lower FPS! That’s the physics engine not being able to keep up with all the part updates.


BodyGyro

The code for BodyGyro is a lot like the “EfficientRotation” example from the top – you still have to update it every step or frame, but the physics engine handles movement.

Since you’re setting what CFrame to go to, if the physics engine catches up, the models should rotate to the proper rotation. They will still slow down if the physics engine can’t keep up, though. You’ll still need to weld everything like you do in the BodyAngularVelocity example. It can have “temporary” drift.

Again, you can use either BodyPosition or AlignPosition here. There’s no real advantage to using AlignPosition this time unless you just feel like using the fancy new constraints.

Example (using BodyPosition)

RotationBodyGyroBodyPosition.rbxl (134.2 KB)

Again, there is some drift in the second Gfy. If it’s severe enough, BodyGyro-based rotations can actually move backwards for a moment while the BodyGyro’s CFrame property makes a rotation that the object itself did not. This only happens when physics is slowing down. You might be able to alleviate it by changing the P(ower) and D(ampening) properties of the BodyGyro.


HingeConstraints

You must have an anchored root part to attach the base of your model to using Attachments and Constraints.

  • Motor should act like BodyAngularVelocity in performance and drift.
  • Servo should act like BodyGyro in performance and drift.

I won’t be making examples of these as they require more set-up for the same performance and functionality.


Animations

You must have an anchored root connected to the base of your model with a Motor6D. You have to use the animation editor to animate a rotation for that Motor6D, then set up scripts to play that animation for all models.

I won’t be making an example of this because it requires too much work.

This could be really efficient. If you don’t care about “drift” or animations syncing from server → client, you could set the animation to looped and play it once and be done! The Roblox engine will handle the rest without worrying about physically simulating the movement, which is great!


Setting the CFrame directly

This is the first example in this post:


Still not smooth enough? Low FPS? Nothing worked?

In that case, you’re moving too much per frame. Remember, this is just aesthetics! It’s much better to have choppy aesthetics and smooth gameplay than choppy aesthetics and choppy gameplay!

You can…

  • Use the CFrame method and time how long updates take. After X milliseconds, stop updating models. This will result in only part of the models being updated, but it can keep your FPS smooth.
  • Only update the rotations of models that are close to the player.
    • If you’re using the CFrame method, you can just not update them
    • If you’re using any of the physics methods (Body*, HingeConstraints), you can anchor the models
    • If you’re using the animation method, you can stop or pause the animations
  • Optimize your models – decrease their part/triangle count and turn CanCollide off.

Could you tell us more about these objects? How big are they? How simple are they? What are they used for? How close together are they? Could you give us a more in-depth explanation of how you’re moving these right now?

With so many options, it’s hard to recommend any single one when there’s so much information left out.

53 Likes

Holy moly, thats a long answer. I somehow managed to not see your reply from my last thread. Imma look through this and see if i can find a solution that fits for me!

Great post, but I don’t agree with you saying that animations are not easy when in my opinion they’re the easiest of them all.

Not to mention that they’re even reusable between multiple different models as long as you have a consistent naming for your pivot point.

1 Like

I say it’s the hardest to do because it takes a lot of set up.

  • BodyAngularVelocity and BodyGyro take almost no set-up and can be done entirely by script.
  • Using constraints, there’s a little bit of set-up with the Studio tools, but you can do it entirely without programming.
  • With animations, there is a lot of set-up using…
    • Studio tools
    • And either…
      • multiple plugins
      • or some programming and a plugin
    • Must also be uploaded to the website and can’t be shared between multiple users or groups.

Programming-wise, animations take the same amount of work as BodyAngularVelocity.


I think, in theory, animations are the best solution. I think in practice the tools aren’t good enough. This is exactly the sort of thing animations are for, but animations require so much set-up that it’s not as easy as it should be.

  • Setting up animations in Studio requires dealing with a “legacy joint” with properties that you can only set by script. This means you need to either use multiple plugins or use the command bar to set it up.
  • Using animations requires uploading to the website, which should not be necessary for something this simple. This prevents sharing between users or groups, so this doesn’t allow easy re-use between group projects. Even worse, you might see it working in Studio since you have access to the asset while everyone else doesn’t.

Ideally we could use Attachments/Constraints, and animations could be kept entirely in-Studio if we didn’t want the copy-protection that uploading provides. For an animation this simple, it’s just an unnecessary speedbump.

Once animations are that easy to use then I’ll absolutely recommend them first thing, as this is exactly the sort of thing they’re for.

2 Likes

Sorry if this has already been suggested, but all the fans and stuff in Innovation Labs and Arctic Base use Motor6Ds created with plugins. They’re very efficient and look smooth, just remember they don’t have physics simulation, and aren’t synchronised between clients.

3 Likes

doesnt that mean that you need a looping script that changes the desiredAngle all the time? or did you set that to math.huge?

I just type in 99999999999999999 :sweat_smile:

4 Likes

I guess thats also a way :joy:

1 Like