using UnityEngine; using System.Collections; using System.Collections.Generic; namespace CharacterEngine.Primitives { public class CECollider { public static int[,] edges = new int[,] { {0, 2}, {0, 3}, {1, 2},{1, 3} }; private BoxCollider2D collider; public BoxCollider2D Coll { get { return collider; } } public virtual Vector2 position { get { return collider.bounds.center; } } public float Height { get { return (GetPoint(0) - GetPoint(3)).magnitude; } } public float Width { get { return (GetPoint(0) - GetPoint(2)).magnitude; } } public Vector2 Max { get { return GetPoint(0); } } public Vector2 Min { get { return GetPoint(1); } } public Vector2 AABBMax { get { return GetAABBPoint(0); } } public Vector2 AABBMin { get { return GetAABBPoint(1); } } public readonly Vector2[] localPoints; public CECollider (BoxCollider2D coll) { collider = coll; ///COLLIDER CONSTANT RELATIVE POINTS localPoints = new Vector2[] { coll.size * 0.5f, //max -coll.size * 0.5f, //min new Vector2(-coll.size.x * 0.5f, coll.size.y * 0.5f), new Vector2(coll.size.x * 0.5f, -coll.size.y * 0.5f) }; } /// /// GET REAL WORLD POINT OF COLLIDER /// /// /// public virtual Vector2 GetPoint (int index) { return position + (Vector2)(collider.transform.rotation * Vector2.Scale(localPoints[index], collider.transform.lossyScale)); } public virtual Vector2 GetPoint(int index, Vector2 position) { return position + (Vector2)(collider.transform.rotation * Vector2.Scale(localPoints[index], collider.transform.lossyScale)); } public virtual Vector2 GetAABBPoint(int index) { return position + (Vector2)(Vector2.Scale(localPoints[index], collider.transform.lossyScale)); } public virtual Vector2 GetAABBPoint(int index, Vector2 position) { return position + (Vector2)(Vector2.Scale(localPoints[index], collider.transform.lossyScale)); } public bool ContainsPoint (Vector2 p) { p = position + (Vector2)(Quaternion.Inverse(collider.transform.rotation) * (p - position)); bool insideX = p.x > AABBMin.x && p.x < AABBMax.x; bool insideY = p.y > AABBMin.y && p.y < AABBMax.y; return insideX && insideY; } /// /// Collision test along a path /// public CECollision SweepTest(Vector2 dir, float distance) { CECollision hit = new CECollision(); for (int i = 0; i <= CEPrimitives.sweepResolution; i++) { Vector2 currentDistance = dir.normalized * (distance * (i / CEPrimitives.sweepResolution)); hit = BoxCast(position + currentDistance); if (hit.impulse.magnitude != 0.0f) break; } return hit; } /// /// Collision test in an specific point /// public CECollision BoxCast(Vector2 position) { int mask = LayerMask.GetMask("Default"); CECollision collision = new CECollision(); RaycastHit2D outHit = new RaycastHit2D(); for (int i = 0; i < edges.GetLength(0); i++) { outHit = Physics2D.Linecast(GetPoint(edges[i, 0], position), GetPoint(edges[i, 1], position), mask); if (!outHit) { outHit = Physics2D.Linecast(GetPoint(edges[i, 1], position), GetPoint(edges[i, 0], position), mask); } if (outHit) break; } if (outHit) { CECollider agent = new CECollider((BoxCollider2D)outHit.collider); CECollider myAgent = new CEVirtualCollider(position, collider); collision = CECollision.ResolveCollision(myAgent, agent); } return collision; } } public class CEVirtualCollider : CECollider { protected Vector2 virtualPosition; public override Vector2 position { get { return virtualPosition; } } public CEVirtualCollider (Vector2 pos, BoxCollider2D coll) : base(coll) { virtualPosition = pos; } } }