Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
2
Question by fitzo · Jan 12, 2012 at 11:39 AM · physicsrigidbodysphereorbit

Constrain rigid body movement to a sphere

I want to have a number of rigid objects moving around a sphere at a fixed distance like this:

alt text

The objects should be able to move freely around the sphere, and interact, collide, etc, but with the distance to the sphere restricted.

How would you do this? Using gravity in some way seems to be the most natural way, but I don't know how. The objects needs to float in the air at orbit distance, or at least look like they do. The objects have different size and mass.

Edit: I edited the question since I used the word "orbit" which is not what I want. I want free movement restricted to a sphere, but using physics to handle collisions, rotations, etc.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by aldonaletto · Jan 12, 2012 at 12:27 PM

Make the sphere a rigidbody, turn Use Gravity off and freeze everything in Constraints. Add HingeJoints (menu Components/Physics/Hinge Joint) to each orbiting object, and set their Connected Rigidbody field to the central sphere. Set the Hinge Joint Axis to 0,0,0 if you don't want any particular axis, or set it to the axis you want (0,1,0 for Y axis, for instance). Apply forces or set the velocities of the orbiting objects and they will orbit forever.

EDITED: I found a better alternative: the configurable joint. Add a configurable joint and the script below to all "orbiting" objects and child them to a center object (the sphere or an empty object). You can also define an initial 2D velocity startvel that's "mapped" over the sphere.

var startVel: Vector2;

function Start(){ var joint = GetComponent(ConfigurableJoint); joint.xMotion = ConfigurableJointMotion.Locked; joint.yMotion = ConfigurableJointMotion.Locked; joint.zMotion = ConfigurableJointMotion.Locked; var toCenter = -transform.localPosition; // center position relative to object joint.anchor = transform.InverseTransformDirection(toCenter);
// map velocity to sphere surface rigidbody.velocity = Quaternion.LookRotation(toCenter) * startVel; } Each object keeps its original distance to the center, but is free to move to any direction. It can also rotate around itself when colliding with other objects - but only around the axis object-center (that's the only restriction).

Comment
Add comment · Show 8 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image fitzo · Jan 12, 2012 at 03:09 PM 0
Share

Thanks for the answer. Using that setup with the anchor positioned in the center of the sphere I can get an orbit. However that's not really what I want. I realize I probably shouldn't have used the word orbit as I want the objects to move freely around the surface of the fictual sphere. I will edit the question to reflect that.

avatar image aldonaletto · Jan 12, 2012 at 05:21 PM 0
Share

Setting the hinge axis to 0,0,0 made my rigidbody move freely in a spherical surface without any restrictions - that's what you want, no?

avatar image Bunny83 · Jan 12, 2012 at 06:20 PM 0
Share

Yep, that's what i understand. "fixed distance" and "move freely" should be explained a bit more in detail since both is not possible.

avatar image fitzo · Jan 12, 2012 at 06:28 PM 0
Share

aldonaletto: that is indeed whast I want, but I couldn't get that behavior using your description. I will try again. With "fixed distance" I mean that the distance to the center of the sphere (and the surface) should be constant. With "move freely" I mean that the objects should travel freely around the full surface of the sphere, not just orbit in a circular path.

avatar image aldonaletto · Jan 13, 2012 at 01:46 AM 1
Share

@fitzo, I tested configurable joints with much better results - the objects really moved freely over the sphere, and reacted to collisions as one could expect. I edited my answer to show this alternative.

Show more comments
avatar image
0

Answer by MrSkiz · Jan 12, 2012 at 03:52 PM

Here's my pick on the subject (I'm onto something quite similar :) )

var orbitRef : Transform; var push : float = 10; var attractForce : float = 5; var distanceMini : float = 2;

 function FixedUpdate () {
 // Planetary gravity
 var direction = orbitRef.position - transform.position;
 direction.Normalize();
 rigidbody.AddForce (direction * attractForce);

 // Floating above the surface
 var dir = transform.TransformDirection (-Vector3.up);
 var finRaycast = transform.localPosition;
 finRaycast.y = transform.localPosition.y-distanceMini;
 Debug.DrawLine (transform.position, finRaycast, Color.red);
     if (Physics.Raycast (transform.position, dir, distanceMini)) {
         rigidbody.AddForce (0, push, 0);
     }
 } 

With this attached to your objects, and the orbitRef variable pointing towards the center of you planet you have a simple but working planetary gravity. And the 2nd part of the script "counter-attack" the attraction with a opposite force (var push) if your object is under the minimal distance (var distanceMini) to make your object float upon the surface.

Now, it's yours to make your object move with few addForce more. I'm scratching my head with surface alignment.

Better/smarter solutions must exist, but that's what I've done wih few days of Unity practicing and barely any programmation background. :)

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image fitzo · Jan 12, 2012 at 10:05 PM 0
Share

Thanks. Your approach kind of worked, but I got strange behavior after letting it run for awhile, e.g. the object bouncing and rolling on the planet surface. It's probably caused by the fixed force added by:

rigidbody.AddForce (0, push, 0);

I came up with the following similar code:

 public Transform orbitRef;

 private float suspensionForce = 300f;
 private float correctionForce = 100f;
 private float startDistance;
     
 // Use this for initialization
 void Start () {
     startDistance =  Vector3.$$anonymous$$agnitude(transform.position - orbitRef.position);
 }
 
 void FixedUpdate () {        
     // Suspend object by using opposing forces. Using VelocityChange to elli$$anonymous$$ate
     // dependency on mass
     Vector3 direction = orbitRef.position - transform.position;
     float currentDistance = Vector3.$$anonymous$$agnitude(direction);
     direction.Normalize();
     rigidbody.AddForce (direction * suspensionForce, Force$$anonymous$$ode.VelocityChange);
     rigidbody.AddForce (-direction * suspensionForce, Force$$anonymous$$ode.VelocityChange);
     
     // Compensate for deviation, note that diff can be negative
     float diff = currentDistance - startDistance;
     rigidbody.AddForce(diff * correctionForce * direction, Force$$anonymous$$ode.VelocityChange);
 } 

First I suspend the object with opposing forces and then I compensate for any deviations from the original distance. This kind of works... It gives a nice rotation and manages to keep objects in orbit well, but the force compensation makes the objects oscillate in some situations, typically when moving very slowly. I haven't found a way around that yet, which makes it unusable for me.

avatar image
0

Answer by Bunny83 · Jan 12, 2012 at 06:55 PM

Well, it's a bit tricky. In the real world when you orbit a planet you have to move at an exact speed around the planet or you will loose your orbit. if you want a true spherical "orbit" with no variations you have to force the distance manually, but the speed might not be kept around the orbit that way.

 public Transform center;
 public float orbitRadius = 20.0f;
 
 void FixedUpdate()
 {
     Vector3 dist = transform.position - center.position;
     transform.position = center.position + dist.normalized * orbitRadius;
 }

You might be able to correct the velocity after that movement. The velocity vector needs to be rotated so it's tangent of the spherical orbit.

Best way:

  • Save the velocity value (magnitude)

  • project the velocity vector onto the current tangent plane (the plane normal is the "dist"-variable)

  • normalize it and multiply with the saved velocity value.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image fitzo · Jan 12, 2012 at 10:14 PM 0
Share

Thanks. I have other objects moving without physics that I manage to move around the sphere without any problems, but for these objects I need realistic collisions, friction, etc. The problem is that any manual adjustments of the position I have tried interferes with the physics, making it all look very unnatural.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

8 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to Click to Move Sphere (With physics)?* 0 Answers

Activate physics when animation ends 0 Answers

Rigidbody sphere slows down quickly 2 Answers

Sphere never sleeps 1 Answer

Tornado throwing back force after pulling 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges