Search Unity

Growing Bubble of Pushing Force

Discussion in 'Scripting' started by Nomad_Artisan, Oct 13, 2013.

  1. Nomad_Artisan

    Nomad_Artisan

    Joined:
    Jun 29, 2013
    Posts:
    20
    Hi, and thanks for taking a look!

    Here's what I'm trying to do thematically.
    I want a forcefield sphere to grow from the center of the player outward to a set radius before disappearing. While growing, if the forcefield touches another object, it should push that object away from the player.

    Currently I have it working just fine on inanimate objects. As you can see in the code below, it's creating an array of all colliders within a certain distance of the player, then for each collider it waits an amount of time based on the distance from the player before having a force applied to it. This makes it appear as if there's a growing bubble of force starting from the player.
    The issue is that if an enemy is outside the forcefield's radius when I activate it, and then moves into the radius before the forcefield thematically reaches its full size, the enemy obviously isn't affected at all.

    I've tried creating a collider whose radius grows over time and tried using OnCollisionEnter and OnCollisionStay functions, but these functions aren't acknowledging other objects in the scene. I think that the forcefield's growing collider is skipping over the other colliders as it grows past them (this is speculation on my part).

    I've been wracking my brain on how to make it work the way I've intended. I'm not sure what direction I need to research in order to solve this problem.

    Any ideas on how I can make this work as intended?
    Thanks in advance for any help!

    P.S. So there's no confusion, in the below code, i have it set up to only push objects in one direction. So I check the greater value between the push directions Vector3.x and Vector3.z, and zero out the lesser.

    Code (csharp):
    1. function FixedUpdate ()
    2.     {
    3.         if(Input.GetKeyDown(KeyCode.Space)  canShield == true)
    4.         {
    5.             Instantiate(shieldGrow, transform.position, transform.rotation);    // instantiate the growing shield
    6.             var blastPos    : Vector3 = transform.position;                                                             // sets blast effect to center on player
    7.             var colliders : Collider[] = Physics.OverlapSphere(blastPos, radius);                                       // creates an array of all colliders within radius of player
    8.             CanShieldDelay();                                                                                           // enables use of shield after 1 second
    9.            
    10.             for (var hit : Collider in colliders)                                                                       // loops for every collider in colliders array
    11.             {
    12.                 if((hit.tag == "block" || hit.tag == "enemy")  hit.rigidbody)                                                                   // happens if collider is a block and has a rigid body
    13.                 {
    14.                     //hit.rigidbody.isKinematic = false;
    15.                     var closestPoint    : Vector3   = hit.rigidbody.ClosestPointOnBounds(transform.position);           // establishes closest point of hit rigid body to center of player
    16.                     var distance        : float     = (Vector3.Distance(closestPoint, transform.position)) - 0.45;      // gets distance from player to rigid body. -0.45 reflects subtracting player's capsuleCollider radius
    17. //                  var pushDir         : Vector3   = (hit.transform.position - transform.position).normalized;         // pushDir equals Vector from player to hit rigidBody
    18.                     var pushDir         : Vector3   = (hit.transform.position - transform.position);
    19.                     if (Mathf.Abs(pushDir.x) > Mathf.Abs(pushDir.z))
    20.                     {
    21.                         pushDir = Vector3(pushDir.x / Mathf.Abs(pushDir.x), 0, 0);
    22.                     }
    23.                     else if (Mathf.Abs(pushDir.x) < Mathf.Abs(pushDir.z))
    24.                     {
    25.                         pushDir = Vector3(0, 0, pushDir.z / Mathf.Abs(pushDir.z));
    26.                     }
    27.                     else
    28.                     {
    29.                         pushDir = Vector3.zero;
    30.                     }
    31.                     print(distance);
    32.                
    33.                     PushEffect(hit, pushDir, distance);                                                                 // calls the Pusheffect onto the hit rigid body, normalizing the vector for direction of push, and getting the distance to the hit rigid body to delay force
    34.                    
    35.                 }                  
    36.             }
    37.         }
    38.        
    39.     }
    40.    
    41.  
    42.  
    43.     function PushEffect(hitObject, pushDir, distance)
    44.     {
    45.         if(hitObject.tag == "enemy")                                                // handle's enemies cauth in blast zone
    46.                     {
    47.                         hitObject.GetComponent(AIPath).enabled = false;
    48.                         hitObject.rigidbody.isKinematic = false;
    49.                         hitObject.rigidbody.velocity = Vector3.zero;
    50.                     }
    51.         if(distance < 1.0)
    52.             pushDir = pushDir/2;
    53.         yield WaitForSeconds(distance/(2*radius));                                  // waits for amount of time based on distance to object. object at very edge of radius would be effected after ~1 second
    54.        
    55.         //hitObject.rigidbody.isKinematic = false;
    56.         hitObject.rigidbody.AddForce(pushDir * 50000);                  // applies forces to hit object directly away from player
    57.     }
    58.