• 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 Karsnen_2 · Jun 08, 2012 at 02:57 PM · physicsrigidbodysimulationconfigurablejoint

Create a leaf with it's natural motion acting upon gravity?

Hello Devs,

I am trying to create a leaf where you drop it and it falls acting upon gravity. It has to be a real leaf or should I say I am trying to create something very similar to a simulator. I was thinking about a configurable joint across the leaf. But I am not sure though. As for as the physics is concerned, I was going to add a rigidbody and bring down the mass, angular drag to minimum depending upon the play testing. Plus I was also about to bring the overall Gravity to -2 from -9.81.

For the future I was planning upon adding 1.Fire 2.Wind 3.Water to give more realism. If a part of the leaf gets a hit by a branch then it should detach itself from it's parent.

Hassle : My question is, as being a lone dev I would like to know how should I approach this problem. I do not have a good leaf model either. I would also prefer to buy some assets on the asset store (last option), if I have to.

Kindly help me as of how to approach.

regards,

Karsnen.

Comment
Add comment · Show 1
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 Fattie · Jun 09, 2012 at 09:00 AM 0
Share

PS if you also mean you literally don't have any good artwork for a leaf, just buy some for 10 or 15 dollars. How else could you get it other than buying it? The whole modern world - every aspect of everything from manufacturing to entertainment - works on the basis of buying and selling 3D models and 3D textures, there is an infinite variety available! Just turn on the internet

2 Replies

· Add your reply
  • Sort: 
avatar image
3
Best Answer

Answer by Fattie · Jun 09, 2012 at 08:58 AM

"or should I say I am trying to create something very similar to a simulator"

I love that sentence!

  1. do not, ever, change gravity. Never.

  2. make absolutely sure your leaf has real-world sizes and real-world masses. you'll need an accurate scale to go out and weigh some leaves

  3. it is all about air flow. you are going to have to model, in some way, airflow. likely you can simply add an upwards force - probably randomized every about 1.7 seconds I'd say - on a script on the object

  4. you mention hinges, are you implying you want the leaf to bend in the middle, ie the leaf has two parts? i would not do this, just leave it as one objet

  5. it is a pain in the arse to make rocking movements, like a boat on water. or like, err, a leaf in air. one very simple approach is make a little thingy that applies force at each of the two ends (ie, as in point 3) and also do "something" in the middle such as: add an invisible rod a couple inches long that hangs down, and stick a small weight on the end. It will sort of balance it and rock it.

Now you're simulating - you're a real game programmer! Enjoy!

Don't forget to WORK TIDILY. It is a hallmark of good simulation programming that you always for example carefully calculate your own mass (very likely some bastard has changed the mass of some component while tweaking it), for example attach this to everything antigravityFixer.js

 #pragma strict
 function Awake()
     {
     GetComponent(ConstantForce).force =
          Physics.gravity * giveTotalMass() * -1.0;
     }
 function giveTotalMass():float
     {
     // all rigidbodies here and below, sum the mass!!!
     var tm:float = 0.0;
     for (var rb : Rigidbody in
              transform.parent.GetComponentsInChildren(Rigidbody))
         tm += rb.mass;
     return tm;
     }

and then you might see code like this kicking around...

 function Awake()
     {
     if ( GetComponent(antigravityFixer) )
         massOfObject = GetComponent(antigravityFixer).giveTotalMass();
     getJoystickForceHere.localPosition = Vector3.zero; // just in case
     }
 function FixedUpdate()
     {
     pushMeBaby = getJoystickForceHere.localPosition * 1.5;
     rigidbody.AddForce( pushMeBaby * massOfObject );
     blah blah...
     }

Hope it helps in some way!

Really the best solution here is, someone probably has a really good "leaf rig" already that they don't mind giving away.

Personally if I was doing this... You see in point 5 it describes "two" places with random air-blasts upwards. I'd make a little sled that randomizes the position and number of those "air blast areas" and then have a little trivial evolutionary algorithm that runs for a day looking for some simple metrics, like, "does not flip over often" or "doesn't just boringly never move" or "slowly heads downwards overall".

That being said, you can very likely get a great result just by guessing two good spots for "little air blasts"

Again - there's surely someone who already has a decent leaf-rig they don't mind giving away, making all this chat useless.

Also ... it's worth noting that an unbelievably simple way to do this is:

MAKE AN ANIMATION...

just make a long animation of a leaf with a nice natural jiggle on it (get the famous scene with the ticket from the movie polar express for reference). Just randomly play sections of the animations as it falls!

Total work time, 10 minutes.

Worth remembering there is very often "an incredibly simpler solution that is better anyway" :)

Comment
Add comment · Show 4 · 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 Karsnen_2 · Jun 11, 2012 at 03:53 PM 0
Share

Wow. Fattie - Thanks man. That was a comprehensive answer. I am right now working like the way you have told. But again, I have one doubt.

Why do you recommend not to change the value of gravity? Is there any specific optimization values?

Because with what I tried and what I saw on the internet, it says that only scaling on the object differs the gravitational force and not the mass of the object. $$anonymous$$oreover, I also see you script has altered the Gravity. Is it okay I change the drag through scripts, if needed (at certain instances).

Thank you.

avatar image Karsnen_2 · Jun 11, 2012 at 04:00 PM 0
Share

Add to add upon that, Unity also recommends not to change the masses of rigidbodies within 100 times.

http://unity3d.com/support/documentation/Components/class-Rigidbody.html At $$anonymous$$ass Explanation.

I hope that if I add in objects in the future I might have to add objects which might have 100 times difference.

avatar image Fattie · Jun 14, 2012 at 06:25 PM 0
Share

Note! never change gravity !!! nothing works once you change gravity. it always leads to trouble. EVERYTHING about physX is built from the ground up to use real masses, real size, and real gravity.

regarding that script, it does not change gravity: very simply, it adds a force in opposition to gravity!!!

thanks for the "tick" by the way!!!!!!!!!

Do not hesitate to ask ANYTHING else you may need. Anything big or small.

avatar image Karsnen_2 · Jun 15, 2012 at 05:33 PM 0
Share

@fattie I do not have plan of changing the gravity at Edit -> Project Settings ->Physics -> Gravity.

If thats what you meant by gravity. I A$$anonymous$$ NOT CHANGING THAT.

But the drag, mass on the rigidbody?

Thanks by the way.

avatar image
3

Answer by bjennings76 · Nov 20, 2016 at 10:35 AM

I realize this post is quite old, but I recently needed to create my own script for a non-particle falling sheet of paper and @fattie's answer helped me a lot. In addition to the 'puff' idea, I also added a slide force based on the slope of the paper that worked out quite well for my purposes.

Here's my script in case it helps anyone else.

Note: This script assumes the paper is thinnest on the Y axis (as if the default orientation is laying flat on a table).

 using System.Collections.Generic;
 using System.Linq;
 using UnityEngine;
 
 [RequireComponent(typeof(BoxCollider), typeof(Rigidbody), typeof(ConstantForce))]
 public class FeatherFall : MonoBehaviour {
     [SerializeField, Range(0.01f, 1f)] private float m_FloatForce = 0.8f;
     [SerializeField, Range(0.01f, 1f)] private float m_SlidePower = 0.2f;
     [SerializeField, Range(0.01f, 1f)] private float m_PuffPower = 0.05f;
     [SerializeField, Range(0.01f, 1f)] private float m_PuffDelayMin = 0.2f;
     [SerializeField, Range(0.01f, 1f)] private float m_PuffDelayMax = 0.3f;
 
     private Rigidbody m_Rigidbody;
     private BoxCollider m_Collider;
     private Vector3 m_AntigravityForce;
     private float m_LastTime;
     private float m_Delay;
     private Vector3[] m_EdgePoints;
     private Vector3 m_SlideVector;
     private Vector3 m_LastPuffPosition;
     private Vector3 m_LastPuffPower;
 
     private void Start() {
         m_Rigidbody = GetComponent<Rigidbody>();
         m_Collider = GetComponent<BoxCollider>();
         m_AntigravityForce = GetAntigravityForce();
         GetComponent<ConstantForce>().force = m_AntigravityForce*m_FloatForce;
 
         Vector3 center = m_Collider.center;
         Vector3 size = m_Collider.size/2;
 
         m_EdgePoints = new[] {
             new Vector3(      0, 0, -size.z) + center,  //bottom
             new Vector3(      0, 0,  size.z) + center,  //top
             new Vector3(-size.x, 0,       0) + center,  //left
             new Vector3( size.x, 0,       0) + center,  //right
             new Vector3(-size.x, 0, -size.z) + center,  //bottom left
             new Vector3( size.x, 0, -size.z) + center,  //bottom right
             new Vector3(-size.x, 0,  size.z) + center,  //top left
             new Vector3( size.x, 0,  size.z) + center   //top right
         };
     }
 
     private void Update() {
         UpdateSlide();
         UpdatePuffs();
     }
 
     private void UpdateSlide() {
         Vector3 normal = transform.up;
         m_SlideVector.x = normal.x*normal.y;
         m_SlideVector.z = normal.z*normal.y;
         m_SlideVector.y = -(normal.x*normal.x) - normal.z*normal.z;
         m_Rigidbody.AddForce(m_SlideVector.normalized*m_SlidePower);
     }
 
     private void UpdatePuffs() {
         if (m_LastTime + m_Delay < Time.time) {
             Puff();
         }
     }
 
     private void Puff() {
         float downwardVelocity = -m_Rigidbody.velocity.y;
         if (downwardVelocity > 0.001f) {
             m_LastTime = Time.time;
             m_Delay = Random.Range(m_PuffDelayMin, m_PuffDelayMax);
             Vector3 puffPosition = GetPuffPosition();
             m_LastPuffPower = m_AntigravityForce*m_PuffPower*downwardVelocity;
             m_LastPuffPosition = transform.InverseTransformPoint(puffPosition);
             m_Rigidbody.AddForceAtPosition(m_LastPuffPower, puffPosition, ForceMode.Impulse);
         }
     }
 
     private Vector3 GetPuffPosition() {
         Vector3 worldOffset = m_Collider.bounds.center;
         List<Vector3> worldEdges = m_EdgePoints.Select<Vector3, Vector3>(transform.TransformPoint).ToList();
         List<Vector3> validEdges = worldEdges.Where(v => v.y <= worldOffset.y).ToList();
 
         if (validEdges.Count == 0) {
             validEdges = worldEdges;
         }
 
         int edgeIndex = Random.Range(0, validEdges.Count - 1);
         return validEdges[edgeIndex];
     }
 
     private Vector3 GetAntigravityForce() {
         float totalMass = transform.GetComponentsInChildren<Rigidbody>().Sum(rb => rb.mass);
         return Physics.gravity*totalMass*-1f;
     }
 
     private void OnDrawGizmos() {
         if (m_EdgePoints == null) {
             return;
         }

         // Slide Vector
         Debug.DrawRay(transform.position, m_SlideVector, Color.blue);
 
         // Last Puff Vector
         Vector3 puffPosition = transform.TransformPoint(m_LastPuffPosition);
         Color puffColor = Color.white;
         float timeSinceLast = Time.time - m_LastTime;
         puffColor.a = 1 - timeSinceLast/m_Delay;
         Debug.DrawRay(puffPosition, m_LastPuffPower*10, puffColor);
 
         foreach (Vector3 edgePoint in m_EdgePoints) {
             Vector3 edgePosition = transform.TransformPoint(edgePoint);
             Gizmos.color = Color.white;
             Gizmos.DrawSphere(edgePosition, 0.01f);
         }
     }
 }
Comment
Add comment · 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

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.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

ConfigurableJoint Anchors and nested RigidBodies 2 Answers

Why is my object tilting when moving? 2 Answers

Can you define linear limits per axis on a Configurable Joint? 0 Answers

ConfigurableJoint Target Position/Rotation Issues? 1 Answer

How to test for a collision with a Terrain 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