Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using UnityEngine;
- public class SimplePhysicsManager : MonoBehaviour
- {
- public static List<SimplePhysBody> bodyList = new List<SimplePhysBody>();
- public static float сellSize = 256;
- public static float width = 8;
- public int maxCells = 64;//width*width
- public static List<PhysHashCell> cells = new List<PhysHashCell>();
- private bool IsInsideCircle(Vector2 CirclePos, float CircleRad, Vector2 checkVector2)
- {
- if (Math.Sqrt(Math.Pow((CirclePos.x - checkVector2.x), 2) +
- Math.Pow((CirclePos.y - checkVector2.y), 2)) < CircleRad)
- { return true; }
- else return false;
- }
- static public bool lineTouchCircle(Vector2 p1, Vector2 p2, Vector2 circleCenter, float radius)
- {
- Vector2 d = p2 - p1;
- Vector2 f = p1 - circleCenter;
- float a = Vector2.Dot(d, d);
- float b = 2 * Vector2.Dot(f, d);
- float c = Vector2.Dot(f, f) - radius * radius;
- float discriminant = b * b - 4 * a * c;
- if (discriminant < 0)
- {
- // no intersection
- }
- else
- {
- // ray didn't totally miss sphere,
- // so there is a solution to
- // the equation.
- discriminant = Mathf.Sqrt(discriminant);
- // either solution may be on or off the ray so need to test both
- // t1 is always the smaller value, because BOTH discriminant and
- // a are nonnegative.
- float t1 = (-b - discriminant) / (2 * a);
- float t2 = (-b + discriminant) / (2 * a);
- // 3x HIT cases:
- // -o-> --|--> | | --|->
- // Impale(t1 hit,t2 hit), Poke(t1 hit,t2>1), ExitWound(t1<0, t2 hit),
- // 3x MISS cases:
- // -> o o -> | -> |
- // FallShort (t1>1,t2>1), Past (t1<0,t2<0), CompletelyInside(t1<0, t2>1)
- if (t1 >= 0 && t1 <= 1)
- {
- // t1 is an intersection, and if it hits,
- // it's closer than t2 would be
- // Impale, Poke
- return true;
- }
- // here t1 didn't intersect so we are either started
- // inside the sphere or completely past it
- if (t2 >= 0 && t2 <= 1)
- {
- // ExitWound
- return true;
- }
- // no intn: FallShort, Past, CompletelyInside
- return false;
- }
- return false;
- }
- public SimplePhysicsManager()
- {
- if (cells.Count == 0)
- {
- for (int i = 0; i < maxCells; i++)
- {
- var cell = new PhysHashCell(i);
- cells.Add(cell);
- }
- }
- }
- public static void AddBody(SimplePhysBody body)
- {
- bodyList.Add(body);
- Vector3 pos = body.transform.position;
- var hashID = (int)((Mathf.Floor(pos.x / сellSize)) + (Mathf.Floor(pos.y / сellSize)) * width);
- body.hashID = hashID;
- cells[hashID].AddBodyWithLayer(body, body.gameObject.layer);
- }
- public static void RemoveBody(SimplePhysBody body)
- {
- bodyList.Remove(body);
- Vector3 pos = body.transform.position;
- var hashID = (int)((Mathf.Floor(pos.x / сellSize)) + (Mathf.Floor(pos.y / сellSize)) * width);
- if (hashID >= 0 && hashID <= cells.Count)
- {
- cells[hashID].RemoveBodyWithLayer(body, body.gameObject.layer);
- }
- }
- public static bool laserActive = false;
- public static Vector2 laserStart = new Vector2();
- public static Vector2 laserEnd = new Vector2();
- private void FixedUpdate()
- {
- //update all hashIDs
- for (int i = 0; i < bodyList.Count; i++)
- {
- SimplePhysBody body = bodyList[i];
- Vector3 pos = body.transform.position;
- var hashID = (int)((Mathf.Floor(pos.x / сellSize)) + (Mathf.Floor(pos.y / сellSize)) * width);
- if (laserActive)
- {
- //Check against lazer ray
- Debug.DrawLine(laserStart, laserEnd, new Color(1, 0, 0));
- bool coll = lineTouchCircle(laserStart, laserEnd, (Vector2)body.transform.position, body.radius);
- if (coll)
- {
- body.OnCollideRay();
- }
- }
- if (hashID != body.hashID)
- {
- //we need up update this guys hash!
- cells[body.hashID].RemoveBodyWithLayer(body, body.gameObject.layer);
- body.hashID = hashID;
- cells[hashID].AddBodyWithLayer(body, body.gameObject.layer);
- }
- }
- for (int i = 0; i < cells.Count; i++)
- {
- if (cells[i] != null)
- {
- //check collisions in cells
- cells[i].CheckListCollisions(LayerMask.NameToLayer("Player"), LayerMask.NameToLayer("Loot")); //heaviest!
- cells[i].CheckListCollisions(LayerMask.NameToLayer("Player"), LayerMask.NameToLayer("Enemy")); //heaviest!
- cells[i].CheckListCollisions(LayerMask.NameToLayer("PlayerBullet"), LayerMask.NameToLayer("Enemy")); //heaviest!
- }
- }
- }
- }
- public class PhysHashCell
- {
- private int hashID;
- public Dictionary<int, List<SimplePhysBody>> BodyDictionary = new Dictionary<int, List<SimplePhysBody>>();
- private float dist;
- private List<SimplePhysBody> list1;
- private int list1Count;
- private List<SimplePhysBody> list2;
- private int list2Count;
- private SimplePhysBody physGameObject1;
- private SimplePhysBody physGameObject2;
- public PhysHashCell(int id)
- {
- hashID = id;
- }
- public void AddBodyWithLayer(SimplePhysBody body, int layer)
- {
- if (BodyDictionary.ContainsKey(layer))
- {
- BodyDictionary[layer].Add(body);
- }
- else
- {
- var PhysBodyList = new List<SimplePhysBody>();
- PhysBodyList.Add(body);
- BodyDictionary.Add(layer, PhysBodyList);
- }
- }
- public void RemoveBodyWithLayer(SimplePhysBody body, int layer)
- {
- if (BodyDictionary.ContainsKey(layer))
- {
- BodyDictionary[layer].Remove(body);
- }
- }
- public void CheckListCollisions(int listName1, int listName2)
- {
- if (BodyDictionary.ContainsKey(listName1) && BodyDictionary.ContainsKey(listName2))
- {
- list1 = BodyDictionary[listName1];
- list2 = BodyDictionary[listName2];
- }
- else
- {
- return; //missing dictionary!
- }
- list1Count = list1.Count;
- list2Count = list2.Count;
- if (list1Count == 0 || list2Count == 0)
- {
- return; //dictionary empty!
- }
- for (int i = 0; i < list1Count; i++)
- {
- physGameObject1 = list1[i];
- for (int j = 0; j < list2Count; j++)
- {
- physGameObject2 = list2[j];
- if (physGameObject1 != physGameObject2)
- {
- //SpriteRenderer sr;
- //sr = physGameObject1.GetComponent<SpriteRenderer>();
- //sr.color = new Color(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f));
- //sr = physGameObject2.GetComponent<SpriteRenderer>();
- //sr.color = new Color(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f));
- Vector3 p1 = physGameObject1.transform.position;
- Vector3 p2 = physGameObject2.transform.position;
- dist = (p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y);
- if (dist < physGameObject1.radius * physGameObject1.radius + physGameObject2.radius * physGameObject2.radius)
- {
- physGameObject1.OnCollideRadial(physGameObject2);
- physGameObject2.OnCollideRadial(physGameObject1);
- }
- }
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement