Advertisement
Guest User

Untitled

a guest
Oct 25th, 2014
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.77 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4.  
  5. public class SimplePhysicsManager : MonoBehaviour
  6. {
  7.     public static List<SimplePhysBody> bodyList = new List<SimplePhysBody>();
  8.  
  9.     public static float сellSize = 256;
  10.     public static float width = 8;
  11.  
  12.     public int maxCells = 64;//width*width
  13.  
  14.     public static List<PhysHashCell> cells = new List<PhysHashCell>();
  15.  
  16.     private bool IsInsideCircle(Vector2 CirclePos, float CircleRad, Vector2 checkVector2)
  17.     {
  18.         if (Math.Sqrt(Math.Pow((CirclePos.x - checkVector2.x), 2) +
  19.                       Math.Pow((CirclePos.y - checkVector2.y), 2)) < CircleRad)
  20.         { return true; }
  21.         else return false;
  22.     }
  23.  
  24.     static public bool lineTouchCircle(Vector2 p1, Vector2 p2, Vector2 circleCenter, float radius)
  25.     {
  26.         Vector2 d = p2 - p1;
  27.         Vector2 f = p1 - circleCenter;
  28.  
  29.         float a = Vector2.Dot(d, d);
  30.         float b = 2 * Vector2.Dot(f, d);
  31.         float c = Vector2.Dot(f, f) - radius * radius;
  32.  
  33.         float discriminant = b * b - 4 * a * c;
  34.         if (discriminant < 0)
  35.         {
  36.             // no intersection
  37.         }
  38.         else
  39.         {
  40.             // ray didn't totally miss sphere,
  41.             // so there is a solution to
  42.             // the equation.
  43.  
  44.             discriminant = Mathf.Sqrt(discriminant);
  45.  
  46.             // either solution may be on or off the ray so need to test both
  47.             // t1 is always the smaller value, because BOTH discriminant and
  48.             // a are nonnegative.
  49.             float t1 = (-b - discriminant) / (2 * a);
  50.             float t2 = (-b + discriminant) / (2 * a);
  51.  
  52.             // 3x HIT cases:
  53.             //          -o->             --|-->  |            |  --|->
  54.             // Impale(t1 hit,t2 hit), Poke(t1 hit,t2>1), ExitWound(t1<0, t2 hit),
  55.  
  56.             // 3x MISS cases:
  57.             //       ->  o                     o ->              | -> |
  58.             // FallShort (t1>1,t2>1), Past (t1<0,t2<0), CompletelyInside(t1<0, t2>1)
  59.  
  60.             if (t1 >= 0 && t1 <= 1)
  61.             {
  62.                 // t1 is an intersection, and if it hits,
  63.                 // it's closer than t2 would be
  64.                 // Impale, Poke
  65.                 return true;
  66.             }
  67.  
  68.             // here t1 didn't intersect so we are either started
  69.             // inside the sphere or completely past it
  70.             if (t2 >= 0 && t2 <= 1)
  71.             {
  72.                 // ExitWound
  73.                 return true;
  74.             }
  75.  
  76.             // no intn: FallShort, Past, CompletelyInside
  77.             return false;
  78.         }
  79.  
  80.         return false;
  81.     }
  82.  
  83.     public SimplePhysicsManager()
  84.     {
  85.         if (cells.Count == 0)
  86.         {
  87.             for (int i = 0; i < maxCells; i++)
  88.             {
  89.                 var cell = new PhysHashCell(i);
  90.                 cells.Add(cell);
  91.             }
  92.         }
  93.     }
  94.  
  95.     public static void AddBody(SimplePhysBody body)
  96.     {
  97.         bodyList.Add(body);
  98.         Vector3 pos = body.transform.position;
  99.         var hashID = (int)((Mathf.Floor(pos.x / сellSize)) + (Mathf.Floor(pos.y / сellSize)) * width);
  100.  
  101.         body.hashID = hashID;
  102.  
  103.         cells[hashID].AddBodyWithLayer(body, body.gameObject.layer);
  104.     }
  105.  
  106.     public static void RemoveBody(SimplePhysBody body)
  107.     {
  108.         bodyList.Remove(body);
  109.         Vector3 pos = body.transform.position;
  110.         var hashID = (int)((Mathf.Floor(pos.x / сellSize)) + (Mathf.Floor(pos.y / сellSize)) * width);
  111.         if (hashID >= 0 && hashID <= cells.Count)
  112.         {
  113.             cells[hashID].RemoveBodyWithLayer(body, body.gameObject.layer);
  114.         }
  115.     }
  116.  
  117.     public static bool laserActive = false;
  118.     public static Vector2 laserStart = new Vector2();
  119.     public static Vector2 laserEnd = new Vector2();
  120.  
  121.     private void FixedUpdate()
  122.     {
  123.         //update all hashIDs
  124.         for (int i = 0; i < bodyList.Count; i++)
  125.         {
  126.             SimplePhysBody body = bodyList[i];
  127.  
  128.             Vector3 pos = body.transform.position;
  129.             var hashID = (int)((Mathf.Floor(pos.x / сellSize)) + (Mathf.Floor(pos.y / сellSize)) * width);
  130.  
  131.             if (laserActive)
  132.             {
  133.                 //Check against lazer ray
  134.                 Debug.DrawLine(laserStart, laserEnd, new Color(1, 0, 0));
  135.  
  136.                 bool coll = lineTouchCircle(laserStart, laserEnd, (Vector2)body.transform.position, body.radius);
  137.                 if (coll)
  138.                 {
  139.                     body.OnCollideRay();
  140.                 }
  141.             }
  142.  
  143.             if (hashID != body.hashID)
  144.             {
  145.                 //we need up update this guys hash!
  146.                 cells[body.hashID].RemoveBodyWithLayer(body, body.gameObject.layer);
  147.                 body.hashID = hashID;
  148.                 cells[hashID].AddBodyWithLayer(body, body.gameObject.layer);
  149.             }
  150.         }
  151.  
  152.         for (int i = 0; i < cells.Count; i++)
  153.         {
  154.             if (cells[i] != null)
  155.             {
  156.                 //check collisions in cells
  157.                 cells[i].CheckListCollisions(LayerMask.NameToLayer("Player"), LayerMask.NameToLayer("Loot")); //heaviest!
  158.                 cells[i].CheckListCollisions(LayerMask.NameToLayer("Player"), LayerMask.NameToLayer("Enemy")); //heaviest!
  159.                 cells[i].CheckListCollisions(LayerMask.NameToLayer("PlayerBullet"), LayerMask.NameToLayer("Enemy")); //heaviest!
  160.             }
  161.         }
  162.     }
  163. }
  164.  
  165. public class PhysHashCell
  166. {
  167.     private int hashID;
  168.  
  169.     public Dictionary<int, List<SimplePhysBody>> BodyDictionary = new Dictionary<int, List<SimplePhysBody>>();
  170.     private float dist;
  171.  
  172.     private List<SimplePhysBody> list1;
  173.     private int list1Count;
  174.  
  175.     private List<SimplePhysBody> list2;
  176.     private int list2Count;
  177.  
  178.     private SimplePhysBody physGameObject1;
  179.     private SimplePhysBody physGameObject2;
  180.  
  181.     public PhysHashCell(int id)
  182.     {
  183.         hashID = id;
  184.     }
  185.  
  186.     public void AddBodyWithLayer(SimplePhysBody body, int layer)
  187.     {
  188.         if (BodyDictionary.ContainsKey(layer))
  189.         {
  190.             BodyDictionary[layer].Add(body);
  191.         }
  192.         else
  193.         {
  194.             var PhysBodyList = new List<SimplePhysBody>();
  195.             PhysBodyList.Add(body);
  196.             BodyDictionary.Add(layer, PhysBodyList);
  197.         }
  198.     }
  199.  
  200.     public void RemoveBodyWithLayer(SimplePhysBody body, int layer)
  201.     {
  202.         if (BodyDictionary.ContainsKey(layer))
  203.         {
  204.             BodyDictionary[layer].Remove(body);
  205.         }
  206.     }
  207.  
  208.     public void CheckListCollisions(int listName1, int listName2)
  209.     {
  210.         if (BodyDictionary.ContainsKey(listName1) && BodyDictionary.ContainsKey(listName2))
  211.         {
  212.             list1 = BodyDictionary[listName1];
  213.             list2 = BodyDictionary[listName2];
  214.         }
  215.         else
  216.         {
  217.             return; //missing dictionary!
  218.         }
  219.         list1Count = list1.Count;
  220.         list2Count = list2.Count;
  221.  
  222.         if (list1Count == 0 || list2Count == 0)
  223.         {
  224.             return; //dictionary empty!
  225.         }
  226.  
  227.         for (int i = 0; i < list1Count; i++)
  228.         {
  229.             physGameObject1 = list1[i];
  230.  
  231.             for (int j = 0; j < list2Count; j++)
  232.             {
  233.                 physGameObject2 = list2[j];
  234.  
  235.                 if (physGameObject1 != physGameObject2)
  236.                 {
  237.                     //SpriteRenderer sr;
  238.  
  239.                     //sr = physGameObject1.GetComponent<SpriteRenderer>();
  240.                     //sr.color = new Color(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f));
  241.                     //sr = physGameObject2.GetComponent<SpriteRenderer>();
  242.                     //sr.color = new Color(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f));
  243.  
  244.                     Vector3 p1 = physGameObject1.transform.position;
  245.                     Vector3 p2 = physGameObject2.transform.position;
  246.                     dist = (p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y);
  247.                     if (dist < physGameObject1.radius * physGameObject1.radius + physGameObject2.radius * physGameObject2.radius)
  248.                     {
  249.                         physGameObject1.OnCollideRadial(physGameObject2);
  250.                         physGameObject2.OnCollideRadial(physGameObject1);
  251.                     }
  252.                 }
  253.             }
  254.         }
  255.     }
  256. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement