Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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
0
Question by S_Byrnes · May 15, 2016 at 11:47 PM · c#2dgravityplanetmagnet

How can I make a gravity field similar to a planetary body?

Hey guys, I'm trying to make a moving spherical 2D object that can pull objects in if they get caught in it's gravity field but in a way that if they're not already moving directly to it, and they come in on an angle, they will kind of veer off while being pulled in slightly and gain some speed.

I have tried the following script on my objects (the ones that will be getting manipulated by this gravity field), but I'd rather have a script on the gravity object itself to pull in the other objects if their Tag or Layer is what it's looking for:

         if (insideGravity)
         {
             Vector3 gravityField = planet.transform.position - transform.position;
             float index = (radius - gravityField.magnitude) / radius;
             rb.AddForce(gravityAmount * gravityField * index);
         }

That bool is set by OnTriggerEnter2D, but I'm open to any way to get it to detect when it's entered the radius.

And the issue I'm getting with the code above is that it will enter the trigger, and then go straight towards the planet and lock there, I need it to pick up that momentum and then kind of do a large orbit unless it exits the radius and then it should keep it's momentum until my drag value slows it back down to it's normal speed.

Also it should be noted that this is how I'm moving the objects that will be acted upon by this gravity field:

 Vector2 movement = new Vector2(xDirection, yDirection).normalized;
 
         rb.velocity = movement * moveSpeed;

I appreciate any and all help you are able to give me! Thank you!

Comment
Add comment · Show 19
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 OrbitGames · May 16, 2016 at 01:39 PM 0
Share

If I understand what you want correctly, you should get a list of all objects that you want the gravity of the object to affect (with tags or a list that you create yourself), cycle through it and add a force to each rigidbody, if the distance between the "planet" or something and the object is smaller than the gravity field

avatar image S_Byrnes OrbitGames · May 16, 2016 at 11:57 PM 0
Share

Thanks for the response!

How can I get the distance exactly? I think I get the rest of it, but the distance factor is what's stumping me.

Also would I use OnTriggerEnter2D and get the tag from that? Or is there another way to do it without colliders/triggers?

avatar image Eno-Khaon S_Byrnes · May 17, 2016 at 03:49 AM 0
Share

The length of any Vector is calculated using the Pythagorean Theorem (same as the hypotenuse of a triangle). This applies to any number of dimensions, so the principle is identical for 2, 3, 4, and more dimensions.

 // Vector between two points is B-A or A-B.
 // i.e. (sourceVector - destinationVector) or vice versa

 // Vector2 example
 Vector2 AB = B - A; (or A - B, for a vector pointing in the opposite direction)
 Vector2 length = $$anonymous$$athf.Sqrt((AB.x * AB.x) + (AB.y * AB.y));

 // Vector3 example
 Vector3 AB = B - A; (or A - B, for a vector pointing in the opposite direction)
 Vector3 length = $$anonymous$$athf.Sqrt((AB.x * AB.x) + (AB.y * AB.y) + (AB.z * AB.z));

 // Vector4 example
 Vector4 AB = B - A; (or A - B, for a vector pointing in the opposite direction)
 Vector4 length = $$anonymous$$athf.Sqrt((AB.x * AB.x) + (AB.y * AB.y) + (AB.z * AB.z) + (AB.w * AB.w));

That said, I hid links to each Vector format's "Distance" function up above... They do the same thing as I described above.

http://docs.unity3d.com/ScriptReference/Vector2.Distance.html

Show more comments

2 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by Amanna · May 18, 2016 at 10:32 AM

// http://wiki.unity3d.com/index.php/Gravity using UnityEngine; using System.Collections.Generic;

public class Gravity : MonoBehaviour {
public static float range = 1000;

 void FixedUpdate () 
 {
     Collider[] cols  = Physics.OverlapSphere(transform.position, range); 
     List<Rigidbody> rbs = new List<Rigidbody>();
 
     foreach(Collider c in cols)
     {
         Rigidbody rb = c.attachedRigidbody;
         if(rb != null && rb != rigidbody && !rbs.Contains(rb))
         {
             rbs.Add(rb);
             Vector3 offset = transform.position - c.transform.position;
             rb.AddForce( offset / offset.sqrMagnitude * rigidbody.mass);
         }
     }
 }

}

Comment
Add comment · Show 2 · 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 S_Byrnes · May 19, 2016 at 12:25 AM 0
Share

Thanks a lot for the answer!

I just tried it out but it's still giving me that 'locking' issue, where it will go straight towards the object and just stay at the objects position, I need it to gain some speed and be pulled in that direction and keep moving past the object if it gained too much speed.

avatar image S_Byrnes · May 23, 2016 at 12:46 AM 0
Share

Actually I take that back, it doesn't cause the locking issue, that was due to my other script still being activated.

This is currently doing nothing for me, where and how am I supposed to use it?

avatar image
0

Answer by jdean300 · May 19, 2016 at 09:21 AM

I'll give you some code that I wrote outside of Unity for a project a few years ago - it should give you some insight on how to accomplish this:

 /// <summary>
         /// Updates the velocity of all planets based on the force of gravity exerted between planets
         /// </summary>
         private void UpdatePlanetVelocities()
         {
             //foreach loop is not efficient in this case, we need to maintain knowledge about the index of a planet
             for (var i = 0; i < m_planets.Count; i++)
             {
                 for (var j = 0; j < m_planets.Count; j++)
                 {
                     //don't want to recalculate a reaction we have already visited
                     if (j <= i)
                         continue;
 
                     var force = ForceBetweenPlanets(m_planets[i], m_planets[j]);
                     m_planets[i].ForceThisFrame += force; //Equal and opposite forces
                     m_planets[j].ForceThisFrame -= force; //Equal and opposite forces
                 }
 
                 m_planets[i].Velocity += (m_planets[i].ForceThisFrame / (float)m_planets[i].Mass);
             }
         }
 
         /// <summary>
         /// Updates the position of all planets with their current velocity
         /// </summary>
         private void UpdatePlanetPositions()
         {
             foreach (var i in m_planets)
             {
                 i.Position += i.Velocity;
             }
         }
 
         /// <summary>
         /// Returns the gravitional force between A & B, in the direction of A to B
         /// </summary>
         /// <param name="a"></param>
         /// <param name="b"></param>
         /// <returns></returns>
         private static Vector2f ForceBetweenPlanets(Planet a, Planet b)
         {
             var d = Utils.Distance(a.Position, b.Position);
             //m_GravConst is just a scaling factor that affects how strong the gravity is
             var forceMag = m_GravConst * (a.Mass * b.Mass) / d; //Newton's Law of Universal Gravitation
 
             var forceVector = b.Position - a.Position;
             forceVector /= (float)d; //reduce to unit vector
             forceVector *= (float)forceMag; //scale to proper magnitude
 
             return forceVector;
         }

You should be able to copy most of this - just use your own list of planets that you determine based on triggers/tags, and let Unity's physics update the position of objects

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 S_Byrnes · May 21, 2016 at 09:59 AM 0
Share

Thanks a lot, I'll have a go at this tomorrow. I really appreciate the help!

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

161 People are following this question.

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

Related Questions

How do I programm a Planet Gravitation? 0 Answers

2D Top Down Character being Pulled down and movement script not working? 2 Answers

Can anyone tell me what I'm doing wrong here? 1 Answer

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers


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