Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Need some help with my Wind mechanic

Discussion in 'Scripting' started by Omni_Owl, Oct 4, 2016.

  1. Omni_Owl

    Omni_Owl

    Joined:
    Nov 26, 2013
    Posts:
    176
    I got this mechanic in my game where wind pushes a ball in the direction that I want as long as the ball is within an invisible trigger volume.

    The problem is though that I get some fairly unpredictable behaviour some times that I'd like help changing so that the resulting motion is somewhat predictable. Below you see a picture of a scenario I had today:



    1. The ball receives Force from an explosion.
    2. The ball rolls to the left as expected.
    3. The ball hits one of the aforementioned triggers and it's pushing it towards the Right as supposed to (but very weakly which is odd too)
    4. The ball hits another trigger volume that should push it right but notice how the ball is already curving to the left even though it shouldn't be.
    5. The ball jumps off to the left even though this should be near impossible given the cloud pushes it right.

    I have had another thing happen too where the ball stops where you see the number 5 and then it just rolls back and forth forever in the wind that should be pushing it only Right. Similar weird behaviour happens when I push the ball Left.

    Here is my code:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class ContinuousPush : MonoBehaviour
    5. {
    6.     public enum WindDirection
    7.     {
    8.         EAST = 0,
    9.         WEST = 1,
    10.         NORTH = 2,
    11.         SOUTH = 3
    12.     }
    13.  
    14.     public float Force = 3;
    15.     public WindDirection Direction = WindDirection.EAST;
    16.  
    17.     public void OnTriggerStay2D(Collider2D other)
    18.     {
    19.         if (other.tag == "Player")
    20.         {
    21.             Rigidbody2D rBody = other.attachedRigidbody;
    22.             switch (Direction)
    23.             {
    24.                 case WindDirection.EAST:
    25.                     rBody.AddForce(Force * rBody.transform.right);
    26.                     break;
    27.                 case WindDirection.WEST:
    28.                     rBody.AddForce(-Force * rBody.transform.right);
    29.                     break;
    30.                 case WindDirection.NORTH:
    31.                     rBody.AddForce(Force * rBody.transform.up);
    32.                     break;
    33.                 case WindDirection.SOUTH:
    34.                     rBody.AddForce(-Force * rBody.transform.up);
    35.                     break;
    36.                 default:
    37.                     Debug.Log("No valid Direction");
    38.                     break;
    39.             }
    40.         }
    41.     }
    42. }
    Any help would be appreciated. I'm sure it's just because my math is too simplified or something.
     
  2. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    So, from your diagram, I assume that the cloud pushes your ball left, not right and you have little force because this happens every frame, not every physics update.

    What you to do is to collect the objects that are in the trigger and apply them in the fixed update.

    Use OnTriggerEnter2D to capture the collider when entering, and OnTriggerExit2D to remove it from the list of objects in the collider. (using System.Collections.Generic;) Look for List.

    Now with a list, use the FixedUpdate to apply the force based off of the direction you want.
     
  3. Omni_Owl

    Omni_Owl

    Joined:
    Nov 26, 2013
    Posts:
    176
    So you are saying that I should add objects to a list that FixedUpdate() goes over all the time and then remove those objects from the list when they exit the trigger?
     
  4. Omni_Owl

    Omni_Owl

    Joined:
    Nov 26, 2013
    Posts:
    176
    I tried to change the code, to this:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class ContinuousPush : MonoBehaviour
    6. {
    7.     public enum WindDirection
    8.     {
    9.         EAST = 0,
    10.         WEST = 1,
    11.         NORTH = 2,
    12.         SOUTH = 3
    13.     }
    14.  
    15.     public float Force = 3;
    16.     public WindDirection Direction = WindDirection.EAST;
    17.  
    18.     private List<Rigidbody2D> RigidBodiesInCloud;
    19.  
    20.     public ContinuousPush()
    21.     {
    22.         RigidBodiesInCloud = new List<Rigidbody2D>();
    23.     }
    24.  
    25.     public void OnTriggerStay2D(Collider2D other)
    26.     {
    27.         if (other.GetComponent<Rigidbody2D>() != null)
    28.         {
    29.             Rigidbody2D rBody = other.GetComponent<Rigidbody2D>();
    30.             RigidBodiesInCloud.Add(rBody);
    31.         }
    32.     }
    33.  
    34.     public void OnTriggerExit2D(Collider2D other)
    35.     {
    36.         if (other.GetComponent<Rigidbody2D>() != null)
    37.         {
    38.             Rigidbody2D rBody = other.GetComponent<Rigidbody2D>();
    39.             RigidBodiesInCloud.Remove(rBody);
    40.         }
    41.     }
    42.  
    43.  
    44.     public void FixedUpdate()
    45.     {
    46.         if (RigidBodiesInCloud.Count > 0)
    47.         {
    48.             foreach (Rigidbody2D rBody in RigidBodiesInCloud)
    49.             {
    50.                 switch (Direction)
    51.                 {
    52.                     case WindDirection.EAST:
    53.                         rBody.AddForce(-Force * rBody.transform.right);
    54.                         break;
    55.                     case WindDirection.WEST:
    56.                         rBody.AddForce(Force * rBody.transform.right);
    57.                         break;
    58.                     case WindDirection.NORTH:
    59.                         rBody.AddForce(Force * rBody.transform.up);
    60.                         break;
    61.                     case WindDirection.SOUTH:
    62.                         rBody.AddForce(-Force * rBody.transform.up);
    63.                         break;
    64.                     default:
    65.                         Debug.Log("No valid Direction");
    66.                         break;
    67.                 }
    68.             }
    69.         }
    70.     }
    71. }
    Which produced this hillarity. So I guess I didn't get what you meant with your solution:
     
  5. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    lol... dont use transform.right.... who knows where it is facing, use Vector2.right instead.

    Code (csharp):
    1. foreach (Rigidbody2D rBody in RigidBodiesInCloud)
    2. {
    3.     switch (Direction)
    4.     {
    5.         case WindDirection.EAST:
    6.             rBody.AddForce(-Force * Vector2.right);
    7.             break;
    8.         case WindDirection.WEST:
    9.             rBody.AddForce(Force * Vector2.right);
    10.             break;
    11.         case WindDirection.NORTH:
    12.             rBody.AddForce(Force * Vector2.up);
    13.             break;
    14.         case WindDirection.SOUTH:
    15.             rBody.AddForce(-Force * Vector2.up);
    16.             break;
    17.         default:
    18.             Debug.Log("No valid Direction");
    19.             break;
    20.     }
    21. }
     
    Omni_Owl likes this.
  6. Omni_Owl

    Omni_Owl

    Joined:
    Nov 26, 2013
    Posts:
    176
    Yeah that seemed to help. Still learning haha

    Thanks! The power of the cloud is now a nice 0 to 1 float scale instead of 1 to whatever arbitrary number haha