title: How to reverse a Force?
body: <p>(Hello, sorry if this is a really stupid question. I'm not good at coding and I probably don't understand what I'm doing)</p>
  <p>I'm doing boids on Unity 3D and I'm trying to block them in a square area. Therefore I added  Forces, one if they were going to far on the x and another one on the z axis.
  <strong>However I don't understand how to make a force so that they don't go too far on the -x and -z axis. How do I reverse the forces so those boids stay inside my area ?</strong></p>
  <p>Here's my x and z boundaries :</p>
  <pre><code>        //Force x
          float distX = Mathf.Max(0, transform.position.x);
          if (distX &gt; 20)
          {
              float forceReject = Mathf.Clamp(5, 1.0f - (distX / 2), 2) * forceRejectGround;
              sumForces += new Vector3(-forceReject, 0, 0);
          }
          
          //Force z
          float distZ = Mathf.Max(0, transform.position.z);
          if (distZ &gt; 20)
          {
              float forceReject = Mathf.Clamp(5, 1.0f - (distZ / 2), 2) * -forceRejectGround;
              sumForces += new Vector3(0, 0, forceReject);
          }
        
  </code></pre>
  <p>Here's the whole code because some asked it (however it's in french sorry)</p>
  <pre><code>public class Boid : MonoBehaviour
  {
      public float zoneRepulsion = 2;
      public float zoneAlignement = 9;
      public float zoneAttraction = 30;
      public float hauteurSol = 0;
  
      public float forceRepulsion = 15;
      public float forceAlignement = 3;
      public float forceAttraction = 20;
      public float forceRejetSol = 100;
  
      public Vector3 target = new Vector3();
      public float forceTarget = 15;
      public bool goToTarget = false;
      public bool stopToTarget = false;
      private bool atTarget = false;
  
      public Vector3 velocity = new Vector3();
      public float maxSpeed = 10;
      public float minSpeed = 5;
  
      public bool drawGizmos = true;
      public bool drawLines = true;
  
      // Update is called once per frame
      void Update()
      {
          Vector3 sumForces = new Vector3();
          Color colorDebugForce = Color.black;
          float nbForcesApplied = 0;
  
          foreach (Boid otherBoid in BoidManager.sharedInstance.roBoids)
          {
              Vector3 vecToOtherBoid = otherBoid.transform.position - transform.position;
              Vector3 forceToApply = new Vector3();
  
              //Si on doit prendre en compte cet autre boid (plus grande zone de perception)
              if (vecToOtherBoid.sqrMagnitude &lt; zoneAttraction * zoneAttraction)
              {
                  //Si on est entre attraction et alignement
                  if (vecToOtherBoid.sqrMagnitude &gt; zoneAlignement * zoneAlignement)
                  {
                      //On est dans la zone d'attraction uniquement
                      forceToApply = vecToOtherBoid.normalized * forceAttraction;
                      float distToOtherBoid = vecToOtherBoid.magnitude;
                      float normalizedDistanceToNextZone = ((distToOtherBoid - zoneAlignement) / (zoneAttraction - zoneAlignement));
                      float boostForce = (4 * normalizedDistanceToNextZone);
                      if (!goToTarget) //Encore plus de cohésion si pas de target
                          boostForce *= boostForce;
                      forceToApply = vecToOtherBoid.normalized * forceAttraction * boostForce;
                      colorDebugForce += Color.green;
                  }
                  else
                  {
                      //On est dans alignement, mais est on hors de répulsion ?
                      if (vecToOtherBoid.sqrMagnitude &gt; zoneRepulsion * zoneRepulsion)
                      {
                          //On est dans la zone d'alignement uniquement
                          forceToApply = otherBoid.velocity.normalized * forceAlignement;
                          colorDebugForce += Color.blue;
                      }
                      else
                      {
                          //On est dans la zone de repulsion
                          float distToOtherBoid = vecToOtherBoid.magnitude;
                          float normalizedDistanceToPreviousZone = 1 - (distToOtherBoid / zoneRepulsion);
                          float boostForce = (4 * normalizedDistanceToPreviousZone);
                          forceToApply = vecToOtherBoid.normalized * -1 * (forceRepulsion * boostForce);
                          colorDebugForce += Color.red;
  
                      }
                  }
  
  
                  sumForces += forceToApply;
                  nbForcesApplied++;
                  
              }
          }
  
          //On fait la moyenne des forces, ce qui nous rend indépendant du nombre de boids
          sumForces /= nbForcesApplied;
  
          //On ajoute le rejet du sol
          float distSol = Mathf.Max(0,transform.position.y - hauteurSol);
          if (distSol &lt; 2)
          {
              float forceRejet = Mathf.Pow(1.0f - (distSol / 2), 2) * forceRejetSol;
              sumForces += new Vector3(0, forceRejet, 0);
          }
  
          //Rejet du plafond
          float distPlaf = Mathf.Max(5, transform.position.y);
          if (distPlaf &gt; 10)
          {
              float forceRejet = Mathf.Clamp(5, 1.0f - (distPlaf / 2), 2) * -forceRejetSol;
              sumForces += new Vector3(0, forceRejet, 0);
          }
  
          //Rejet pour la limite d' x
          float distX = Mathf.Max(0, transform.position.x);
          if (distX &gt; 20)
          {
              float forceRejet = Mathf.Clamp(5, 1.0f - (distX / 2), 2) * forceRejetSol;
              sumForces += new Vector3(-forceRejet, 0, 0);
          }
          //Rejet pour la limite de -x
          if (distX &lt; -15)
          {
              float forceRejetXNeg = Mathf.Clamp(5, 1.0f - (distX / 2), 2) * forceRejetSol;
              sumForces += new Vector3(forceRejetXNeg, 0, 0);
          }
          //Rejet pour la limite d' z
          float distZ = Mathf.Max(0, transform.position.z);
          if (distZ &gt; 20)
          {
              float forceRejet = Mathf.Clamp(5, 1.0f - (distZ / 2), 2) * -forceRejetSol;
              sumForces += new Vector3(0, 0, forceRejet);
          }
          //Rejet pour la limite de -z
          if (distZ &lt; -15)
          {
              float forceRejetZNeg = Mathf.Clamp(5, 1.0f - (distZ / 2), 2) * -forceRejetSol;
              sumForces += new Vector3(0, 0, forceRejetZNeg);
          }
  
          //Si on a une target, on l'ajoute
          float distToTarget = 0;
          if (goToTarget)
          {
              Vector3 vecToTarget = target - transform.position;
              distToTarget = vecToTarget.magnitude;
              if (distToTarget &lt; 0.5f)
              {
                  goToTarget = false;
                  atTarget = true;
              }
              else
              {
                  atTarget = false;
                  Vector3 forceToTarget = vecToTarget.normalized * forceTarget;
                  if (distToTarget &lt; 5 &amp;&amp; stopToTarget)
                      forceToTarget *= 10;
                  sumForces += forceToTarget;
                  colorDebugForce += Color.magenta;
                  nbForcesApplied++;
                  if (drawLines)
                      Debug.DrawLine(transform.position, target, Color.magenta);
              }
          }
  
          //Debug
          if (drawLines)
              Debug.DrawLine(transform.position, transform.position + sumForces, colorDebugForce / nbForcesApplied);
  
          //On freine
          velocity += -velocity * 10 * Vector3.Angle(sumForces, velocity) / 180.0f * Time.deltaTime;
  
          //on applique les forces
          velocity += sumForces * Time.deltaTime;
  
          //On limite la vitesse
          if (velocity.sqrMagnitude &gt; maxSpeed * maxSpeed)
              velocity = velocity.normalized * maxSpeed;
          if (velocity.sqrMagnitude &lt; minSpeed * minSpeed)
              velocity = velocity.normalized * minSpeed;
  
          //Si on doit freiner sur la cible, on limite la vitesse
          if ((goToTarget || atTarget) &amp;&amp; stopToTarget)
              if (distToTarget &lt; 3)
                  velocity = velocity.normalized * distToTarget/10.0f;
  
  
          //On regarde dans la bonne direction        
          if (velocity.sqrMagnitude &gt; 0)
              transform.LookAt(transform.position + velocity);
  
          //Debug
          if (drawLines)
              Debug.DrawLine(transform.position, transform.position + velocity, Color.blue);
  
          //Deplacement du boid
          transform.position += velocity * Time.deltaTime;
      }
  
      void OnDrawGizmosSelected()
      {
          if (drawGizmos)
          {
              // Répulsion
              Gizmos.color = new Color(1, 0, 0, 1.0f);
              Gizmos.DrawWireSphere(transform.position, zoneRepulsion);
              // Alignement
              Gizmos.color = new Color(0, 1, 0, 1.0f);
              Gizmos.DrawWireSphere(transform.position, zoneAlignement);
              // Attraction
              Gizmos.color = new Color(0, 0, 1, 1.0f);
              Gizmos.DrawWireSphere(transform.position, zoneAttraction);
          }
      }
  }
  
  </code></pre>