*IMPORTANT NOTE* When using the .magnitude property of a Vector3, Unity performs a costly square root calculation. A much quicker option would be to use .sqrMagnitude to get the magnitude squared, which is what you need in the formula anyway. Currently you're taking the square root of something and then squaring it, which is just wasted calculations.
@@creepercloud2617 You've probably forgotten taking away the squaring [At 3:40, Math.Pow(distance, 2) should be replaced by simply distance, because now it's already squared].
Super useful, I was about to purchase a $30 gravitations pack from the asset store! Thanks for saving me the money, I might donate it to you instead :)
I use Unity since a year and a half. I was a trainee in a company for software development and currently, I study Applied computer science. Still, I watch every single video of you and learning so much. Thank you for all your great videos. Awesome!
Super Gravity video -i learned so much from this video about Gravity simulation.... 1] normalized/direction now makes sense to me.. it quickly lets u set direction like lookat. 2] attractor is not a fancy Unity word, he just created function that can be called. 2.71828... ] rb.mass can be used to access the mass value of rb 4] Findobjects of type lets u scan for things to attract just amazing what i learned from this video - great job, dude! PS; did u know that indiana once proclaimed by law that PI was about 4.
If i had known in 10th grade you could do lots of cool stuff with mathematical equations I would've paid attention. No seriously, unity should be used as an educational ressource at school. I mean its the perfect tool to learn programming, apply physical knowledge and see mathematical equations and logic applied to a specific problem. This is awesome.
I love this channel. I am new to programming and find most tutorials boring but these videos are perfectly explained, timed, and even have some comedic effects to them. So in short thank you.
I have so much fun with this, i made an object that instantiates different planet sizes every few seconds in a given are and in a given amount and playing with this is just so much fun. Thank you very much for making my evening!
@@riverfilms4548 Probably not just one gravity parameter but once you scale them appropriately with mass according and get a whole bunch of experiments with it done you could definitely have an orbit simulation.
8:40 Never use == with float and double. Use Mathf.Approx (or whatever it's called). Also, since F=1/D^2, the force gets large fast as D approaches 0. So either clamp max force to something reasonable, or if D
You could have used direction.sqrMagnitude to avoid a square-root call and immediately get the distance squared. It would also be better to use a simple multiplication when you are just squaring, because Mathf.Pow() is slower. Finally, the problem is not directly that the distance is 0, but that normalizing a vector with 0 length causes a division by zero. However, this is a nice tutorial, and I especially liked how you avoided FindObjectsOfType().
Bit of a an old video now, but it got me thinking of some interesting ideas for a game project I'm working on in unity. I'm wanting to create a procedural voxel planet, also known as marching cubes. Where it obits a sun in a 3d space, a tutorial on how I could achieve this would be greatly appreciated. I have researched online for resources but either no one wants to share said knowledge, or has said knowledge but would rather charge me a fortune for it. I've watched your video's for a good while now, and seeing this particular one gave me some possible hope that you might be the outlet to figure this solution out.
Sorry for saying this 4 years later but if you want orbit, you could just make a public vector3 and call it initialVelocity, and then set it to something in the inspector. Then in the start method, just set your rb velocity to initialVelocity. Experiment with the initialVelocity, and you should have proper orbit :>
This could be optimized even further. Once you calculated a force from an object, exact same force will aply to other object you put in to equation. So you can half the calculations. This can be done from a single script with these codes. list bodies; foreach(Rigidbody r in bodies {(foreach(Rigidbody b in bodies) { force=calculation(r,b); a.addforce(a); b.addforce(b); } }
I went and wrote that code. First, change your fixed update. void FixedUpdate() { int thisIndex = Attractors.IndexOf(this); int listSize = Attractors.Count; for (int i = thisIndex + 1; i < listSize; i++) { Attract(Attractors[i]); } } And throw this at the end of your attract method rb.AddForce(-force)
Using Random.InsideUnitSphere you can create some awesome effects, spawning random amounts of objects around a "sun" at variable distances, and adding a random amount of torque. You can also tell the object to look at the central spawn object (just for the start, before the torque is applied), and apply velocity left or right, to help create an orbit effect.
I'm 11 years old, looking to be an unprofessional indie game dev, the math part can sometimes get confusing for me since I'm only starting 6th grade, so that's where RUclipsrs like Brackeys kick in :P
sagacious if you want to learn it you can take a look at the khan academy website where you can learn algebra from the firs .i think you can understand it easily. "link"= www.khanacademy.org/
Just a suggestion. I thought a more efficient way would be, for each planet, to sum the forces from each of the others then apply the sum to itself. See the code snippet below: void FixedUpdate() { Vector3 forceVector = Vector3.zero; foreach (GravitatingObject otherPlanet in _planets) { if (otherPlanet == this) continue; // don't include ourselves! Vector3 direction = otherPlanet.transform.position - transform.position; float distance = direction.magnitude; float forceMagnitude = (G * ourRigidBody.mass * otherPlanet.GetComponent().mass) / (distance * distance); direction.Normalize(); // sum the forces from the individual planets forceVector += direction * forceMagnitude; } // apply the resulting force to us ourRigidBody.AddForce(forceVector); }
I am just now rediscovering your videos, and so far having a blast, really like the way they are made and structured, already subscribed. Not sure if it was mentioned already, but will throw my two cents here, when working with floating point, I find it best not to check against an exact value (i.e. distance == 0f) but to work with thresholds or a minimum epsilon value that will work. Meaning instead of checking if the distance is exactly equal to zero (which could bring trouble with floating point) the condition could be for the distance to be less than or equal than a certain tolerance constant (as small as you want it to be). Keep up the amazing work :)
You can refer to storing all objects in a static collection which register themselves when they enable/disable as the "Observer Pattern". - Entities store themselves in a specific global collection. - Everything else "observes" this collection to manipulate and/or interact with the entities inside of it. - You don't need a list, a static self expanding array may be cheaper. This is a pattern I use for pretty much everything, as GameObject.Find and GameObject.FindObjectsOfType should be avoided to prevent bad practices outside of Start and Awake.
Hey, Brackeys, I really have enjoyed your channel and I would like to thank you for the effort you put in each video. I just wanted to suggest a few topics that possibly you could go over in future videos. First, I would like to know if there could be a way for several people that watch this channel to use Unity collaborate and make a big project. Secondly, I would really like it if, after this RPG series, you do another survival series but using blender and going a bit more in depth with more concepts. Thanks!
I used Mathf.Pow(DistanceBetweenObjects, 2) to calculate square magnitude between two objects, but I found out, that they are very handy thing "Vector3.sqrMagnitude", that saves one line of code each time you calculate square distance - you need just put it into the formula!
Very similar approach like my one. To improve performance, there's no reason to get the square root of `sqrMagnitude` (which `magnitude` in fact does) and calculate the power by 2 (square) again. Further more I instanciate another `MonoBehaviour` derived class at runtime which triggers in `FixedUpdate` my static method for calculation of all object pairs at once. On adding objects to list, I generate a new list of pairs, so the same calculation works for both paired objects with just switching to the negative normalized vector.
Does anybody know an equally-amazing channel, but for Unreal Engine? btw. I watch your every video, even though I use UE and not Unity. I just love this channel :)
Does anyone know how I can calculate a trajectory with this? I was thinking of an invisible game object with a trail that goes ahead but I am not sure how I could make it go ahead almost instantly without getting shot out of orbit at an escape velocity or just shot into the main body
this probably won't be interesting anymore after 2 years but you can take the momentum of the rigid body (after the forces have been applied) and normalize that. that's the direction your rigidbody is heading
I think I need help. I have done everything exactly as you said so far (at least if im not missing something) but Im getting complier errors and cannot enter playmode.
i keep getting an error message telling me "the type or namespace 'Attractor' could not be found (are you missing a using directive or an assembly reference?)" Does anyone know a fix for this? It seems as though unity doesn't recognize Attractor as a valid array? I'm not sure but any help would be great
@@connormarks5584 For my game I wasn't working with planets, so I set the masses of the objects pretty low like 2 kg (try not to make masses 1 or anything below 1). I then wrote the code, but I didn't include the gravitational constant (G) since I wasn't working with planets with big masses 6:10. I also stopped the video at 7 minutes and didn't do the stuff afterwards. If none of that works, then feel free to answer these questions in a reply and I could get a better idea of how to fix it! What are you trying to do in your project? How far apart are the objects? What is going wrong (Is the code not effecting them at all or are they teleporting everywhere)? What are the masses of the objects?
@@dolphano2951 Ok so I tried everything that you said but nothing seems to change the issue. I decided to download the project from the link and there was an issue with the script min drawer I assume it was a post processing thing but it worked after I added this line of code at the top using MinAttribute = UnityEngine.PostProcessing.MinAttribute; but then after I hit play instead of the objects all coming together they where separating its as if the gravity was backwards. The mass of the objects is 1000 even after I changed it they only moved apart slower I have no idea why it will not work
@@connormarks5584 oh man that's pretty weird. I'm not too knowledgeable on post processing as of now, but you mentioned the gravity was reversed like repelling. This may sound kind of rookie but did you accidentally place a negative sign somewhere in the code?
I have a question about this attractors script! I'm trying to use it for a large number of objects: 125 cubes. When I do that, the framerate just plummets. What kind of solutions should I look for so I can make a game about gravity with a lot of objects?
Add if statement after distance calculation. Lets say if(distance > 50)do what Brackeys code does, else do the same but AddForce(-force). Create separate G var for both conditions and have fun
Loving your tutorials!...and have 3 questions: 1. how would you get the attractor force to go to 0 after a certain distance has been reached? 2. how could I assign gravity to the face of a plane or make the inner faces of a tube have gravity? 3. how would I make a low gravity areas for a first person controller?
1) if(distance < myMaxDistance){ //do the attraction stuff }else{ //do nothing (obviously, you don't need the else here, just to explain) } 2) there's a lot of solution to that... But it's to complex to answer without illustration. I'd recommend you to check unity's forum, you can ask anything there and people will help you, even if you're a complete beginner. But really quickly I see 2 eassy way of doing that : a) handle gravity on your own, just like in this episode, but you'd have to set the direction of the force to be the opposite of the plane's normal. b) just change the unity gravity direction vector somewhere in preferences to, like above, to be the inverse of the plane's normal. You can edit that under Edit>Project Settings> Physic but if you want your plane to change orientation, you'll have to change update it via scripting. 3) Same location as above Edit>Project Settings> Physic, you can tweak gravity intensity & direction.
Ok thanks, one more thing and this may seem to be a stupid question...but is there a way to determine my plane's normal (even when it is a curved object) in unity?
Very nice video. A optimization that I would suggest is calculating the distance squared (using pythagoras) and plugging it directly into the force formula, because Vector3.magnitude uses square root and is a costly operation.
Just add a require component at the start of your script. - [RequireComponent(typeof(Rigidbody))] Then you won't need to worry about remembering to add one yourself. You can do the same with colliders
Something people sould remember is that realistic Earth gravity, when walking on Earth is: gravity + (objectMass * airResistance). Without air resistance, every object moves at the same speed downward. This was proving by the us in a chamber completely removed of air. They dropped a bowling ball and a feather at the same time and they fell at the exact same speed.
The Rigidbody in Attractor doesn't actually need to be public as when a field is set to "private" it is only accessible by that CLASS; not that object. So other objects of the class Attractor can access the Rigidbody even when it's private!
What exactly does "OnEnable()" and "Attractor.Add(this)" do? For my script I made the attractors pull in every rigidbody instead of just other attractor (so that the player and physics objects are also pulled in and not just other celestial bodies) and I noticed it only worked with the array method. If I attempted the List way of doing it it would put a red underline under "this" in "Rigidbody.Add(this)" and say "cannot convert Rigidbody to attractor".
I'm in a similar boat. My problem is getting the dimension scaling right so I can maintain realism. My brain gets the actual values used in orbital mechanics calculations confused with the scaled values I'm using for the simulation.
I managed to make 2d balls that attract each other creating a beautiful to look at system but after adding 5-8 rigid bodies the processing power starts to suffer a lot. To the point where it just stops working properly and lags. Does anyone know how I can manage to have more objects that need less calculating power?
I did this a few years ago on my own. I'm was proud when i made it work. Turns out it's no big deal. It's just that I am too dumb to understand physics lol. Also, good to know that static attribute prefix can make the attribute accessible globally to all instances with the same class name.
In fact, the static keyword is even more powerful. It doesn't allow all instances to access the attribute but creates an attribute which is attached to the class directly. That means that you can also, if marked as public, access to your attribute through Class.staticAttribute and that is just SUPER useful.
- should have made use of [RequireComponent] attribute. - should have used Vector3.sqrMagnitude, because obtaining the magnitude is way more costly (especially if you're not gonna need it) - same goes for Mathf.Pow(s, 2), its a float wrapper around Math.Pow and this is more costly than x * x - instead check floats for zero, use Mathf.Approximately() was going to write better be using a static list for all attractors, glad to see you solved it the exact way i would have done it.
I was just about to say pretty much that. ALSO, for some reason rb.position is expensive vs transform.position(at least for 5.6 and 2017.3), check the difference yourself with this setup, when object count is at the thousands(i have an i7) using rb.position leads to about 1 fps and using transform.position i stay at a cool 50-60(with it's limit ofc) have a look at the profiler and dont forget to change both rb.positions if you try this.
Also also, method calling is expensive so try to do pretty much that in FixedUpdate: for (int i = 0; i < activeAttractees.Count; i++) { Vector3 dir = transform.position - activeAttractees [i].transform.position; activeAttractees [i].rb.AddForce (dir.normalized * (G * (rb.mass * activeAttractees [i].rb.mass) / dir.sqrMagnitude)); }
I think it could also be optimized by making one master script in the scene which would control all the attractors, rather than have FixedUpdate be called every time on each of them
Put simply, every time you create an object, it will add his attractor component to the list. The list is static, that mean it is common to all the scripts. So every script access the same list and add there own Attractor component to it. OnEnable is triggered the first time the script is enabled.
If we do that, it will add overhead on your game.. why checking it each time when you can just add the living object in the list upon when its just spawned? it improves performance... Coz there are tons of stuff happening all the time and having something silly like this will produce lag in calculations vs response.
Because the Attractors property is **static**, it belongs to the Attractor class itself rather than each instance of an Attractor having its own copy. You usually see this most commonly with constants, like Integer.MAX_INT where you're asking the Integer class what its max value is rather than asking an individual Integer, but it still applies in cases where the static property is not a constant.
he made the list static, which means one list is shared by all the attractor objects... so if every object adds itself to a list that everybody can see, they are now all in the list.
Im trying to make a spaceflight simulator kinda like kerbel space program so i was wondering can i use this as a flat plane and if so how whould i go about adding thrust so that my object (rocket) can launch up i wanna do this in a way of adding one of those atmospheric balloons so my plan was to do a thing where i can apply weight and thrust changeable but i dont actually know how to or where to start
Can this be used for a character controller, thinking planet sized map with a texture generated with libnoise or something like that with a character controller walking on the service, vehicles etc.?
It can be. You just need to set the mass of the character to be small. It would also be wise to put in some logic to auto-rotate the character so their "feet" are always pointing towards the planet that is applying the strongest force on the character.
Hey Brackeys, How do I make a XR Rig walk on surfaces, I can't control myself to walk in the different axis, because my XR Rig is not set to local directions, I don't know how to do that. Please help.
This is tremendous. Thank you, as always. I'm a high school teacher thinking of using Unity to reinforce concepts of astronomy and physics, but I'm novice at best. Does anyone know if the Unity physics engine is up to the task of using the method described in the video to create stable orbits? If we were to create a large sun-like sphere and send a smaller planets zooming by, would Unity physics be able to capture them and keep them in anything like a stable orbit? I feel like that's probably a pretty big ask of the physics engine.
I reckon it would be up to the challenge. I'm also thinking of modelling projectiles (I teach Maths and think it would be cool to have a way for the kids to actually model the process and get approximate answers)
Unity would be up for it. It all depends on your skill of implementing it. I'd imagine that it'd be easier to find a pre-made solution already out in the wild. Surely what you're looking for has already been created and more than likely by a professional coder/designer. if your goal is to learn unity and the underlying tech, then by all means, work through it. The tech can handle it.
*IMPORTANT NOTE*
When using the .magnitude property of a Vector3, Unity performs a costly square root calculation.
A much quicker option would be to use .sqrMagnitude to get the magnitude squared, which is what you need in the formula anyway.
Currently you're taking the square root of something and then squaring it, which is just wasted calculations.
when i replaced magnitude with SqrtMagnitude the gravity started acting alot slower, so your wrong
@@creepercloud2617 You've probably forgotten taking away the squaring [At 3:40, Math.Pow(distance, 2) should be replaced by simply distance, because now it's already squared].
yay it works thank you
@@creepercloud2617 You're welcome!
@@creepercloud2617 Lol dont say that before you know
its sad to see him go but the videos will live on
Same
Legends never die..
@@krissloo143 But ur mom does lol
@@simonvutov7575 She says hi
Damn... It's already 7 months...
Super useful, I was about to purchase a $30 gravitations pack from the asset store! Thanks for saving me the money, I might donate it to you instead :)
Lol. Good idea!
@@misterr3083 😂
We put an Attractor in your Attractor so you can attract Attractors while attracting etc...
yo dawg
hahaha
Is it a Great Attractor?
I use Unity since a year and a half. I was a trainee in a company for software development and currently, I study Applied computer science. Still, I watch every single video of you and learning so much. Thank you for all your great videos. Awesome!
Super Gravity video -i learned so much from this video about Gravity simulation.... 1] normalized/direction now makes sense to me.. it quickly lets u set direction like lookat. 2] attractor is not a fancy Unity word, he just created function that can be called. 2.71828... ] rb.mass can be used to access the mass value of rb 4] Findobjects of type lets u scan for things to attract
just amazing what i learned from this video - great job, dude!
PS; did u know that indiana once proclaimed by law that PI was about 4.
Still relevant in 2019, awesome overview on how to approach it.
2020
I hear that isaac newton plans to change his famouss gravitational equation in early 2021- so thankful I saw this now for my game!
@@spacevolvox4020 He commented this a year ago
Thomas de Langen ya ik just pointing out how it is still relevant in 2020 although i could’ve been more descriptive
@@spacevolvox4020 ah k lol
If i had known in 10th grade you could do lots of cool stuff with mathematical equations I would've paid attention. No seriously, unity should be used as an educational ressource at school. I mean its the perfect tool to learn programming, apply physical knowledge and see mathematical equations and logic applied to a specific problem. This is awesome.
I love this channel. I am new to programming and find most tutorials boring but these videos are perfectly explained, timed, and even have some comedic effects to them. So in short thank you.
4:36 so many tractors...
NuclearFX ahahahah
@NuclearFX haha tractor go -brr- vroom
September of 2021. still best unity tutorials on youtube. Thank you.
I'm currently making a particle physics game and it worked for 2d too! I am soo happy with how it is currently turning out!
Thank you so much for posting this. I'm mucking around with gravitational attraction between objects. This is going to save me a lot of work.
I have so much fun with this, i made an object that instantiates different planet sizes every few seconds in a given are and in a given amount and playing with this is just so much fun.
Thank you very much for making my evening!
I love how to-the-point and well explained this is. 9 minutes of material that would normally take another person 45 minutes to trudge through.
And that's how Brackeys created the Universe. In the beginning was the Word. And the Word was 'internal class Creator'.
"How to create Universal Sandbox under 10 minutes"
vistaero well, real numbers and explosions. Good way to give objects orbit propably would be handy too.
@@vistaero herd of a joke in your life?
I ask myself if it would be possible to get planets in their orbits with just the gravity. :O
if he used point effector then it takes only 3 minutes
@@riverfilms4548 Probably not just one gravity parameter but once you scale them appropriately with mass according and get a whole bunch of experiments with it done you could definitely have an orbit simulation.
Please make an updated tutorial of this but using ecs and dots 🙏🙏 I would love to see how you tackle that!
8:40 Never use == with float and double. Use Mathf.Approx (or whatever it's called). Also, since F=1/D^2, the force gets large fast as D approaches 0. So either clamp max force to something reasonable, or if D
Relying on the collider to keep distance reasonable is living dangerously
So is storing objects in a naked static variable
Great video!
If I had 5 dollars for every time you said attractor, I wouldn't need to go to work anymore.
You could have used direction.sqrMagnitude to avoid a square-root call and immediately get the distance squared. It would also be better to use a simple multiplication when you are just squaring, because Mathf.Pow() is slower. Finally, the problem is not directly that the distance is 0, but that normalizing a vector with 0 length causes a division by zero.
However, this is a nice tutorial, and I especially liked how you avoided FindObjectsOfType().
Bit of a an old video now, but it got me thinking of some interesting ideas for a game project I'm working on in unity. I'm wanting to create a procedural voxel planet, also known as marching cubes. Where it obits a sun in a 3d space, a tutorial on how I could achieve this would be greatly appreciated. I have researched online for resources but either no one wants to share said knowledge, or has said knowledge but would rather charge me a fortune for it. I've watched your video's for a good while now, and seeing this particular one gave me some possible hope that you might be the outlet to figure this solution out.
Sorry for saying this 4 years later but if you want orbit, you could just make a public vector3 and call it initialVelocity, and then set it to something in the inspector. Then in the start method, just set your rb velocity to initialVelocity. Experiment with the initialVelocity, and you should have proper orbit :>
This could be optimized even further. Once you calculated a force from an object, exact same force will aply to other object you put in to equation. So you can half the calculations. This can be done from a single script with these codes.
list bodies;
foreach(Rigidbody r in bodies
{(foreach(Rigidbody b in bodies)
{
force=calculation(r,b);
a.addforce(a);
b.addforce(b);
}
}
I went and wrote that code.
First, change your fixed update.
void FixedUpdate()
{
int thisIndex = Attractors.IndexOf(this);
int listSize = Attractors.Count;
for (int i = thisIndex + 1; i < listSize; i++)
{
Attract(Attractors[i]);
}
}
And throw this at the end of your attract method
rb.AddForce(-force)
Using Random.InsideUnitSphere you can create some awesome effects, spawning random amounts of objects around a "sun" at variable distances, and adding a random amount of torque. You can also tell the object to look at the central spawn object (just for the start, before the torque is applied), and apply velocity left or right, to help create an orbit effect.
I'm 11 years old, looking to be an unprofessional indie game dev, the math part can sometimes get confusing for me since I'm only starting 6th grade, so that's where RUclipsrs like Brackeys kick in :P
Sagacious once you have an understanding of basic algebra it'll be a lot easier
sagacious if you want to learn it you can take a look at the khan academy website where you can learn algebra from the firs .i think you can understand it easily.
"link"= www.khanacademy.org/
What did you learn in this 2 years?
@@zeroiq4737 If he's thirteen now then he should have started algebra XD
@Joel Webber he’s probably acing it
This Tutorial was awesome! You just gave me a huge inspiriation, thanks!
drinking game every time he says “attractor” take a shot
Better version eat a ghost pepper everytime he says "attractor"
Just a suggestion. I thought a more efficient way would be, for each planet, to sum the forces from each of the others then apply the sum to itself.
See the code snippet below:
void FixedUpdate()
{
Vector3 forceVector = Vector3.zero;
foreach (GravitatingObject otherPlanet in _planets)
{
if (otherPlanet == this)
continue; // don't include ourselves!
Vector3 direction = otherPlanet.transform.position - transform.position;
float distance = direction.magnitude;
float forceMagnitude = (G * ourRigidBody.mass * otherPlanet.GetComponent().mass) / (distance * distance);
direction.Normalize();
// sum the forces from the individual planets
forceVector += direction * forceMagnitude;
}
// apply the resulting force to us
ourRigidBody.AddForce(forceVector);
}
I am just now rediscovering your videos, and so far having a blast, really like the way they are made and structured, already subscribed. Not sure if it was mentioned already, but will throw my two cents here, when working with floating point, I find it best not to check against an exact value (i.e. distance == 0f) but to work with thresholds or a minimum epsilon value that will work. Meaning instead of checking if the distance is exactly equal to zero (which could bring trouble with floating point) the condition could be for the distance to be less than or equal than a certain tolerance constant (as small as you want it to be). Keep up the amazing work :)
Great tutorial! Visual Studio 2017 has a handy unity shortcut Ctrl+Shift+Q to generate Monobehaviour callback functions by the way.
Again such a cool tutorial. Where would I be without Brackeys!
Brackets ur the best mange tak for alt den hjælp:) jeg har været fan i 2 år nu.
You can refer to storing all objects in a static collection which register themselves when they enable/disable as the "Observer Pattern".
- Entities store themselves in a specific global collection.
- Everything else "observes" this collection to manipulate and/or interact with the entities inside of it.
- You don't need a list, a static self expanding array may be cheaper.
This is a pattern I use for pretty much everything, as GameObject.Find and GameObject.FindObjectsOfType should be avoided to prevent bad practices outside of Start and Awake.
Hey, Brackeys, I really have enjoyed your channel and I would like to thank you for the effort you put in each video. I just wanted to suggest a few topics that possibly you could go over in future videos. First, I would like to know if there could be a way for several people that watch this channel to use Unity collaborate and make a big project. Secondly, I would really like it if, after this RPG series, you do another survival series but using blender and going a bit more in depth with more concepts. Thanks!
Your videos are the best, thank you so much for them. As soon as I'm able to make some money from my games I'll be sure to pass along your cut. ^^
Niceee video ;) best unity tech RUclipsr
the Attractor in the
"void Attract (Attractor objtoattract)"
shows as an error and won't let the game run, does anyone know a solution?
What is the error?
My favorite Chanel . Thanks for this tutorial
You should issue a challenge to all your viewers to make a small video game using only your tutorials
You make the best videos man!
Great video as always man, you're the best!
I love your videos so much because they help me a lot with my games :D
Thank You For The Best Understandable Tutorials!
I used Mathf.Pow(DistanceBetweenObjects, 2) to calculate square magnitude between two objects, but I found out, that they are very handy thing "Vector3.sqrMagnitude", that saves one line of code each time you calculate square distance - you need just put it into the formula!
Neat, love it, thanks again !! So many crazy weapon ideas now muuuaaaaahhhhhhhh.
Man , you are an awesome teacher , thanks so much !
Very similar approach like my one. To improve performance, there's no reason to get the square root of `sqrMagnitude` (which `magnitude` in fact does) and calculate the power by 2 (square) again. Further more I instanciate another `MonoBehaviour` derived class at runtime which triggers in `FixedUpdate` my static method for calculation of all object pairs at once. On adding objects to list, I generate a new list of pairs, so the same calculation works for both paired objects with just switching to the negative normalized vector.
Dang, I'm already feeling like I can make an entire universe simulator haha. Great tutorial!
Does anybody know an equally-amazing channel, but for Unreal Engine?
btw. I watch your every video, even though I use UE and not Unity. I just love this channel :)
Sykoo is the best Unity channel I can think of.
Dean Ashford, Dev Enabled
Thank you so much! I was looking for a tutorial like this one to help me with my game!
Thank you! That helps me a lot with a current project!
how did you get it to work!?!?!?!?
This was great. I'd love to see it expanded to create a solar system with orbital patterns etc..
imagine calling your triplets sara, sarah ans sahra. thats how this code is written
Does anyone know how I can calculate a trajectory with this? I was thinking of an invisible game object with a trail that goes ahead but I am not sure how I could make it go ahead almost instantly without getting shot out of orbit at an escape velocity or just shot into the main body
this probably won't be interesting anymore after 2 years but you can take the momentum of the rigid body (after the forces have been applied) and normalize that. that's the direction your rigidbody is heading
@@StrawberryXetr0n Lol yeah I'm well past whatever I was messing around with this for but still, thanks
One of your best Videos in my orion. Ehm opinion!
I think I need help. I have done everything exactly as you said so far (at least if im not missing something) but Im getting complier errors and cannot enter playmode.
i keep getting an error message telling me "the type or namespace 'Attractor' could not be found (are you missing a using directive or an assembly reference?)" Does anyone know a fix for this? It seems as though unity doesn't recognize Attractor as a valid array? I'm not sure but any help would be great
same here
i reckon they changed it
Cool. Can you make a tutorial about simulating magnets?
Lame nickname en.m.wikipedia.org/wiki/Force_between_magnets
There the force between magnets roughly changes by 1/X^4
Thank You!!! This literally saved me for a game jam (GMTK 2021)
how did you get it to work
@@connormarks5584 For my game I wasn't working with planets, so I set the masses of the objects pretty low like 2 kg (try not to make masses 1 or anything below 1). I then wrote the code, but I didn't include the gravitational constant (G) since I wasn't working with planets with big masses 6:10. I also stopped the video at 7 minutes and didn't do the stuff afterwards.
If none of that works, then feel free to answer these questions in a reply and I could get a better idea of how to fix it!
What are you trying to do in your project? How far apart are the objects?
What is going wrong (Is the code not effecting them at all or are they teleporting everywhere)?
What are the masses of the objects?
@@dolphano2951 Ok so I tried everything that you said but nothing seems to change the issue.
I decided to download the project from the link and there was an issue with the script min drawer I assume it was a post processing thing but it worked after I added this line of code at the top using MinAttribute = UnityEngine.PostProcessing.MinAttribute; but then after I hit play instead of the objects all coming together they where separating its as if the gravity was backwards. The mass of the objects is 1000 even after I changed it they only moved apart slower I have no idea why it will not work
@@connormarks5584 oh man that's pretty weird. I'm not too knowledgeable on post processing as of now, but you mentioned the gravity was reversed like repelling. This may sound kind of rookie but did you accidentally place a negative sign somewhere in the code?
@@dolphano2951 Well tbh I am a bit of a rookie but as I mentioned I downloaded the project so I didn't write the code
Is Attractor a type of component or some variable, and how do you know which objects are of type attractor in 4:36
I have a question about this attractors script!
I'm trying to use it for a large number of objects: 125 cubes. When I do that, the framerate just plummets. What kind of solutions should I look for so I can make a game about gravity with a lot of objects?
Add if statement after distance calculation. Lets say if(distance > 50)do what Brackeys code does, else do the same but AddForce(-force). Create separate G var for both conditions and have fun
Loving your tutorials!...and have 3 questions:
1. how would you get the attractor force to go to 0 after a certain distance has been reached?
2. how could I assign gravity to the face of a plane or make the inner faces of a tube have gravity?
3. how would I make a low gravity areas for a first person controller?
1) if(distance < myMaxDistance){
//do the attraction stuff
}else{
//do nothing (obviously, you don't need the else here, just to explain)
}
2) there's a lot of solution to that... But it's to complex to answer without illustration. I'd recommend you to check unity's forum, you can ask anything there and people will help you, even if you're a complete beginner.
But really quickly I see 2 eassy way of doing that :
a) handle gravity on your own, just like in this episode, but you'd have to set the direction of the force to be the opposite of the plane's normal.
b) just change the unity gravity direction vector somewhere in preferences to, like above, to be the inverse of the plane's normal. You can edit that under Edit>Project Settings> Physic but if you want your plane to change orientation, you'll have to change update it via scripting.
3) Same location as above Edit>Project Settings> Physic, you can tweak gravity intensity & direction.
what I mean is what maths equation would you use to gradually return a force to 0 over time?
Ok thanks, one more thing and this may seem to be a stupid question...but is there a way to determine my plane's normal (even when it is a curved object) in unity?
Great video! Very informative !!
This is so much more optimized than all my solutions :p
Very nice video. A optimization that I would suggest is calculating the distance squared (using pythagoras) and plugging it directly into the force formula, because Vector3.magnitude uses square root and is a costly operation.
So use direction.sqrMagnitude
Wait that's a thing? How could I never have noticed before. Thanks
Awesome, just what i was looking for. :)
The type or namespace name 'Attractor' could not be found (are you missing a using directive or an assembly reference?)
Wonderful video! I knew physics would become useful at some point :D
Just add a require component at the start of your script. - [RequireComponent(typeof(Rigidbody))]
Then you won't need to worry about remembering to add one yourself. You can do the same with colliders
Something people sould remember is that realistic Earth gravity, when walking on Earth is: gravity + (objectMass * airResistance). Without air resistance, every object moves at the same speed downward. This was proving by the us in a chamber completely removed of air. They dropped a bowling ball and a feather at the same time and they fell at the exact same speed.
Well... technically speaking we haven't really done _complete_ removal of air yet... That's way too hard due to the immense vacuum you create
You don't need a vaccum chamber to show that. Just 2 line of math using Newton's equations. So the US didn't prove shit. Newton did.
The Rigidbody in Attractor doesn't actually need to be public as when a field is set to "private" it is only accessible by that CLASS; not that object. So other objects of the class Attractor can access the Rigidbody even when it's private!
What exactly does "OnEnable()" and "Attractor.Add(this)" do?
For my script I made the attractors pull in every rigidbody instead of just other attractor (so that the player and physics objects are also pulled in and not just other celestial bodies) and I noticed it only worked with the array method. If I attempted the List way of doing it it would put a red underline under "this" in "Rigidbody.Add(this)" and say "cannot convert Rigidbody to attractor".
I'd like to see this reworked to keep a playerObject on the surface of a sphere while still allowing them to move around it.
8:35 why not try{}?
Damn it, after watching this i finally realized whats wrong with my own gravity script. I put it in update, instead of fixed update XD.
I'm in a similar boat. My problem is getting the dimension scaling right so I can maintain realism. My brain gets the actual values used in orbital mechanics calculations confused with the scaled values I'm using for the simulation.
Mega like from Mexico!!!
You taught me a lot thx :D
Not even notifications squad, Just Love your videos so much :D
Really amazing!
Thanks!!
Can you do something on Google Play Services?
thanks I was looking for this too
4:45 - Somebody count how many times he says attract
I managed to make 2d balls that attract each other creating a beautiful to look at system but after adding 5-8 rigid bodies the processing power starts to suffer a lot. To the point where it just stops working properly and lags. Does anyone know how I can manage to have more objects that need less calculating power?
Was actually wanting to make a video game from this
Hey Brackeys! How much time do you typically spend making one of these well done and fun tutorials!??
How could I use the gizmos to draw the range of gravity?
I didn’t understand anything you just did but it was a cool video
I did this a few years ago on my own. I'm was proud when i made it work. Turns out it's no big deal. It's just that I am too dumb to understand physics lol. Also, good to know that static attribute prefix can make the attribute accessible globally to all instances with the same class name.
In fact, the static keyword is even more powerful. It doesn't allow all instances to access the attribute but creates an attribute which is attached to the class directly. That means that you can also, if marked as public, access to your attribute through Class.staticAttribute and that is just SUPER useful.
- should have made use of [RequireComponent] attribute.
- should have used Vector3.sqrMagnitude, because obtaining the magnitude is way more costly (especially if you're not gonna need it)
- same goes for Mathf.Pow(s, 2), its a float wrapper around Math.Pow and this is more costly than x * x
- instead check floats for zero, use Mathf.Approximately()
was going to write better be using a static list for all attractors, glad to see you solved it the exact way i would have done it.
Thanks!
You can use Int if you do not care more about the precision.
I was just about to say pretty much that.
ALSO, for some reason rb.position is expensive vs transform.position(at least for 5.6 and 2017.3), check the difference yourself with this setup, when object count is at the thousands(i have an i7) using rb.position leads to about 1 fps and using transform.position i stay at a cool 50-60(with it's limit ofc)
have a look at the profiler and dont forget to change both rb.positions if you try this.
Also also, method calling is expensive so try to do pretty much that in FixedUpdate:
for (int i = 0; i < activeAttractees.Count; i++) {
Vector3 dir = transform.position - activeAttractees [i].transform.position;
activeAttractees [i].rb.AddForce (dir.normalized * (G * (rb.mass * activeAttractees [i].rb.mass) / dir.sqrMagnitude));
}
I think it could also be optimized by making one master script in the scene which would control all the attractors, rather than have FixedUpdate be called every time on each of them
*Please* explain the optimisation... Why does the list contain _every_ attractor if you only add "this" to it?
Put simply, every time you create an object, it will add his attractor component to the list. The list is static, that mean it is common to all the scripts. So every script access the same list and add there own Attractor component to it.
OnEnable is triggered the first time the script is enabled.
If we do that, it will add overhead on your game.. why checking it each time when you can just add the living object in the list upon when its just spawned? it improves performance... Coz there are tons of stuff happening all the time and having something silly like this will produce lag in calculations vs response.
Because the Attractors property is **static**, it belongs to the Attractor class itself rather than each instance of an Attractor having its own copy. You usually see this most commonly with constants, like Integer.MAX_INT where you're asking the Integer class what its max value is rather than asking an individual Integer, but it still applies in cases where the static property is not a constant.
he made the list static, which means one list is shared by all the attractor objects... so if every object adds itself to a list that everybody can see, they are now all in the list.
Im trying to make a spaceflight simulator kinda like kerbel space program so i was wondering can i use this as a flat plane and if so how whould i go about adding thrust so that my object (rocket) can launch up i wanna do this in a way of adding one of those atmospheric balloons so my plan was to do a thing where i can apply weight and thrust changeable but i dont actually know how to or where to start
are you having plans to stream
Love your vids keep it up
why direction.normalized is used there i want to know normalized function
Can this be used for a character controller, thinking planet sized map with a texture generated with libnoise or something like that with a character controller walking on the service, vehicles etc.?
It can be. You just need to set the mass of the character to be small. It would also be wise to put in some logic to auto-rotate the character so their "feet" are always pointing towards the planet that is applying the strongest force on the character.
Please help, I have error with this line "FindObjectOfType();", it says " cannot implicitly convert type 'Attractors' to 'Attractors[ ]' "
Its probably "FindObjectsOfType" instead of "FindObjectOfType". one letter can ruin everything :/
wats is the short key to complete the basic foreach statement?
Make a follow up video on "Surface Gravity" for cube shaped planets please. :D
Thats relatively easy to the point where you should figure it out on your own.
Hey Brackeys, How do I make a XR Rig walk on surfaces, I can't control myself to walk in the different axis, because my XR Rig is not set to local directions, I don't know how to do that. Please help.
This is tremendous. Thank you, as always. I'm a high school teacher thinking of using Unity to reinforce concepts of astronomy and physics, but I'm novice at best. Does anyone know if the Unity physics engine is up to the task of using the method described in the video to create stable orbits? If we were to create a large sun-like sphere and send a smaller planets zooming by, would Unity physics be able to capture them and keep them in anything like a stable orbit? I feel like that's probably a pretty big ask of the physics engine.
I reckon it would be up to the challenge. I'm also thinking of modelling projectiles (I teach Maths and think it would be cool to have a way for the kids to actually model the process and get approximate answers)
Unity would be up for it. It all depends on your skill of implementing it. I'd imagine that it'd be easier to find a pre-made solution already out in the wild. Surely what you're looking for has already been created and more than likely by a professional coder/designer. if your goal is to learn unity and the underlying tech, then by all means, work through it. The tech can handle it.