Search Unity

Help-Use gravity only within a certain area

Discussion in 'Scripting' started by Haru Ilpalazzo, Jul 7, 2015.

  1. Haru Ilpalazzo

    Haru Ilpalazzo

    Joined:
    Jul 7, 2015
    Posts:
    7
    How could use gravity alone in an area of land , as if embers in a dome ?
     
  2. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    987
    Create a sphere gameobject and set its collider to isTrigger. This sphere is the area gravity exists.
    On all your rigidbodies, set their "Use Gravity" to false.

    Put this script on the sphere we made, and now you can walk into the sphere and get gravity.
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class ColliderGravity : MonoBehaviour
    4. {
    5.     public Vector3 gravity = Physics.gravity;
    6.  
    7.     void OnTriggerStay(Collider colliderInfo)
    8.     {
    9.         if(colliderInfo.attachedRigidbody != null)
    10.         {
    11.             colliderInfo.attachedRigidbody.AddForce(gravity);
    12.         }
    13.     }
    14. }
     
  3. Haru Ilpalazzo

    Haru Ilpalazzo

    Joined:
    Jul 7, 2015
    Posts:
    7


    thank testing tomorrow : D
     
  4. Pavlon

    Pavlon

    Joined:
    Apr 15, 2015
    Posts:
    191
    Just out of curiosity wouldn't it be Mutch faster to place a game object in the middle and do a range check i
     
  5. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    987
    Im not sure, because then we would need to either put on every rigidbody that we want to be affected by said gravity a script that has a reference to the gameobject to be able to check the range, or we would need to reference all the rigidbodies on the gameobject and it would need to loop through them all every frame to check the range.

    Where as with OnTriggerEnter, it isnt only more user friendly, but unity might be doing extra optimizing for us, and they may already have had the info being used for other calculations, and doing OnTriggerEnter is just us saying "pass that info to us too please". I'm not sure if that is how it works though =)

    Profile it I guess ^^
     
  6. Pavlon

    Pavlon

    Joined:
    Apr 15, 2015
    Posts:
    191
    So here is what i got first the code i used with Colliders

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Cube : MonoBehaviour
    5. {
    6.     void OnCollisionEnter()
    7.     {
    8.         this.GetComponent<BoxCollider> ().enabled = false;
    9.         this.GetComponent<Rigidbody> ().useGravity = false;
    10.         this.GetComponent<Rigidbody> ().velocity = Vector3.zero;
    11.         Main.count ++;
    12.     }
    13. }
    14.  

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Spawn : MonoBehaviour
    5. {
    6.     private int size = 25; // 15625 rigid bodys
    7.     void Start ()
    8.     {
    9.         for (int x = 0; x < size; x++)
    10.         {
    11.             for (int y = 0; y < size; y++)
    12.             {
    13.                 for (int z = 0; z < size; z++)
    14.                 {
    15.                         GameObject.Instantiate(Resources.Load("Cube"),new Vector3(x * 1.5f,y * 1.5f,z * 1.5f),Quaternion.AngleAxis(180,Vector3.zero));
    16.                  
    17.                 }
    18.             }
    19.         }
    20.         Main.start = true;
    21.     }
    22. }

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Main : MonoBehaviour
    5. {
    6.     public static int  count = 0;
    7.     public static bool start = false;
    8.     private float time = 0;
    9.  
    10.     void Update ()
    11.     {
    12.         if (start == true)
    13.         {
    14.             time = Time.time;
    15.             start = false;
    16.         }
    17.         if (count == 15625)//15625 from Spawn.cs
    18.             Debug.Log (Time.time - time);
    19.     }
    20. }
    21.  

    the results are

    3.88901
    3.79381
    3.79797
    3.84071

    now with using range

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Cube : MonoBehaviour
    5. {
    6.     public bool collision = true;
    7.  
    8.     public void Collision()
    9.     {
    10.         collision = false;
    11.         this.GetComponent<Rigidbody> ().useGravity = false;
    12.         this.GetComponent<Rigidbody> ().velocity = Vector3.zero;
    13.         Main.count ++;
    14.     }
    15. }
    16.  

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Spawn : MonoBehaviour
    5. {
    6.     private int size = 25; // 15625 rigid bodys
    7.     void Start ()
    8.     {
    9.         for (int x = 0; x < size; x++)
    10.         {
    11.             for (int y = 0; y < size; y++)
    12.             {
    13.                 for (int z = 0; z < size; z++)
    14.                 {
    15.                         NoGravityArea.cube_list.Add(Instantiate(Resources.Load("Cube"),new Vector3(x * 1.5f,y * 1.5f,z * 1.5f),Quaternion.AngleAxis(180,Vector3.zero)) as GameObject);
    16.                 }
    17.             }
    18.         }
    19.         Main.start = true;
    20.     }
    21. }
    22.  

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class NoGravityArea : MonoBehaviour {
    6.  
    7.     public static List<GameObject> cube_list = new List<GameObject>();
    8.  
    9.     void FixedUpdate ()
    10.     {
    11.         for (int i = 0; i < cube_list.Count; i ++)
    12.         {
    13.             if(cube_list[i].GetComponent<Cube>().collision == true &&
    14.                Mathf.Sqrt
    15.                (
    16.                        ((cube_list[i].transform.position.x - this.transform.position.x) * (cube_list[i].transform.position.x - this.transform.position.x))
    17.                     +
    18.                     ((cube_list[i].transform.position.y - this.transform.position.y) * (cube_list[i].transform.position.y - this.transform.position.y))
    19.                     +
    20.                     ((cube_list[i].transform.position.z - this.transform.position.z) * (cube_list[i].transform.position.z - this.transform.position.z))
    21.                 ) < 30)
    22.             {
    23.                 cube_list[i].GetComponent<Cube>().Collision();
    24.             }
    25.         }
    26.     }
    27. }
    28.  


    the results are (with FixedUpdate)

    3.933629
    3.938395
    3.934564
    3.945481

    the results are (with Update) what is inacurate

    3.816878
    3.905328
    3.90814
    3.901522

    so there is no mutch difference for me but you can optimize more thinks if you do it with range and not a collider
     
  7. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    987
    Might just be unneeded premature optimization though, as well as possibly more complex, harder to understand code compared to just OnTriggerStay.
     
  8. Haru Ilpalazzo

    Haru Ilpalazzo

    Joined:
    Jul 7, 2015
    Posts:
    7
    I have a doubt

    is possible that gravity fields (using the first code
    of HiddenMonk) have different forces of gravity?
    Field 1 gravity 0,9,0
    FIELD 2 0, -9.0
     
  9. Pirs01

    Pirs01

    Joined:
    Sep 30, 2012
    Posts:
    389
    Code (csharp):
    1. public Vector3 gravity2 = new Vector3(0f, 9f, 0f);
     
  10. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    987
    Instead of doing gravity2 like pirs said. Just make a new sphere gameobject marked as isTrigger, put the ColliderGravity script on it, and in the inspector change the gravity from -9.81 to what ever u want.

    This is the beauty of components =)