diff --git a/Assets/IsoTools/Addons/Physics/IsoCollider.cs b/Assets/IsoTools/Addons/Physics/IsoCollider.cs index 2b1bb4a..b8b2ff6 100644 --- a/Assets/IsoTools/Addons/Physics/IsoCollider.cs +++ b/Assets/IsoTools/Addons/Physics/IsoCollider.cs @@ -13,7 +13,7 @@ namespace IsoTools.Physics { IsoFakeCollider _fakeCollider; Collider _realCollider = null; - protected Collider realCollider { + public Collider realCollider { get { return _realCollider; } } diff --git a/Assets/IsoTools/Addons/Physics/IsoPhysics.cs b/Assets/IsoTools/Addons/Physics/IsoPhysics.cs index 984cedd..d0d769b 100644 --- a/Assets/IsoTools/Addons/Physics/IsoPhysics.cs +++ b/Assets/IsoTools/Addons/Physics/IsoPhysics.cs @@ -4,117 +4,313 @@ using IsoTools.Physics.Internal; namespace IsoTools.Physics { public static class IsoPhysics { + // + // Ignore collision helpers + // + + public static bool GetIgnoreLayerCollision(int layer1, int layer2) { + return UnityEngine.Physics.GetIgnoreLayerCollision(layer1, layer2); + } + + public static void IgnoreCollision(IsoCollider iso_collider1, IsoCollider iso_collider2, + bool ignore = true) + { + UnityEngine.Physics.IgnoreCollision( + iso_collider1.realCollider, iso_collider2.realCollider, ignore); + } + + public static void IgnoreLayerCollision(int layer1, int layer2, + bool ignore = true) + { + UnityEngine.Physics.IgnoreLayerCollision(layer1, layer2, ignore); + } + // // Raycast // - public static bool Raycast(Ray ray, out IsoRaycastHit iso_hit_info) { - return Raycast(ray, out iso_hit_info, - Mathf.Infinity, UnityEngine.Physics.DefaultRaycastLayers, - QueryTriggerInteraction.UseGlobal); - } - public static bool Raycast(Ray ray, out IsoRaycastHit iso_hit_info, - float max_distance) - { - return Raycast(ray, out iso_hit_info, - max_distance, UnityEngine.Physics.DefaultRaycastLayers, - QueryTriggerInteraction.UseGlobal); - } - - public static bool Raycast(Ray ray, out IsoRaycastHit iso_hit_info, - float max_distance, int layer_mask) - { - return Raycast(ray, out iso_hit_info, - max_distance, layer_mask, - QueryTriggerInteraction.UseGlobal); - } - - public static bool Raycast(Ray ray, out IsoRaycastHit iso_hit_info, - float max_distance, int layer_mask, - QueryTriggerInteraction query_trigger_interaction) + float max_distance = Mathf.Infinity, + int layer_mask = UnityEngine.Physics.DefaultRaycastLayers, + QueryTriggerInteraction query_trigger_interaction = QueryTriggerInteraction.UseGlobal) { var hit_info = new RaycastHit(); var result = UnityEngine.Physics.Raycast(ray, out hit_info, - max_distance, layer_mask, query_trigger_interaction); + max_distance, + layer_mask, + query_trigger_interaction); iso_hit_info = result ? new IsoRaycastHit(hit_info) : new IsoRaycastHit(); return result; } - // - // RaycastAll - // - - public static IsoRaycastHit[] RaycastAll(Ray ray) { - return RaycastAll(ray, - Mathf.Infinity, UnityEngine.Physics.DefaultRaycastLayers, - QueryTriggerInteraction.UseGlobal); - } - - public static IsoRaycastHit[] RaycastAll(Ray ray, - float max_distance) - { - return RaycastAll(ray, - max_distance, UnityEngine.Physics.DefaultRaycastLayers, - QueryTriggerInteraction.UseGlobal); - } - - public static IsoRaycastHit[] RaycastAll(Ray ray, - float max_distance, int layer_mask) - { - return RaycastAll(ray, - max_distance, layer_mask, - QueryTriggerInteraction.UseGlobal); - } - - public static IsoRaycastHit[] RaycastAll(Ray ray, - float max_distance, int layer_mask, - QueryTriggerInteraction query_trigger_interaction) - { - var hits_info = UnityEngine.Physics.RaycastAll(ray, - max_distance, layer_mask, query_trigger_interaction); - return IsoPhysicsUtils.IsoConvertRaycastHits(hits_info); - } - // // RaycastNonAlloc // - public static int RaycastNonAlloc(Ray ray, IsoRaycastHit[] results) { - return RaycastNonAlloc(ray, results, - Mathf.Infinity, UnityEngine.Physics.DefaultRaycastLayers, - QueryTriggerInteraction.UseGlobal); - } - public static int RaycastNonAlloc(Ray ray, IsoRaycastHit[] results, - float max_distance) - { - return RaycastNonAlloc(ray, results, - max_distance, UnityEngine.Physics.DefaultRaycastLayers, - QueryTriggerInteraction.UseGlobal); - } - - public static int RaycastNonAlloc(Ray ray, IsoRaycastHit[] results, - float max_distance, int layer_mask) - { - return RaycastNonAlloc(ray, results, - max_distance, layer_mask, - QueryTriggerInteraction.UseGlobal); - } - - static RaycastHit[] _raycastNonAllocBuffer = new RaycastHit[128]; - public static int RaycastNonAlloc(Ray ray, IsoRaycastHit[] results, - float max_distance, int layer_mask, - QueryTriggerInteraction query_trigger_interaction) + float max_distance = Mathf.Infinity, + int layer_mask = UnityEngine.Physics.DefaultRaycastLayers, + QueryTriggerInteraction query_trigger_interaction = QueryTriggerInteraction.UseGlobal) { var hit_count = UnityEngine.Physics.RaycastNonAlloc(ray, _raycastNonAllocBuffer, - max_distance, layer_mask, query_trigger_interaction); + max_distance, + layer_mask, + query_trigger_interaction); + return RaycastBufferToIsoRaycastHits(hit_count, results); + } + + // + // Linecast + // + + public static bool Linecast( + Vector3 start, Vector3 end, out IsoRaycastHit iso_hit_info, + int layer_mask = UnityEngine.Physics.DefaultRaycastLayers, + QueryTriggerInteraction query_trigger_interaction = QueryTriggerInteraction.UseGlobal) + { + var hit_info = new RaycastHit(); + var result = UnityEngine.Physics.Linecast(start, end, out hit_info, + layer_mask, + query_trigger_interaction); + iso_hit_info = result ? new IsoRaycastHit(hit_info) : new IsoRaycastHit(); + return result; + } + + // + // CheckBox + // + + public static bool CheckBox( + Vector3 center, Vector3 half_extents, + int layer_mask = UnityEngine.Physics.DefaultRaycastLayers, + QueryTriggerInteraction query_trigger_interaction = QueryTriggerInteraction.UseGlobal) + { + return UnityEngine.Physics.CheckBox( + center, half_extents, + Quaternion.identity, + layer_mask, + query_trigger_interaction); + } + + // + // CheckCapsule + // + + public static bool CheckCapsule( + Vector3 start, Vector3 end, float radius, + int layer_mask = UnityEngine.Physics.DefaultRaycastLayers, + QueryTriggerInteraction query_trigger_interaction = QueryTriggerInteraction.UseGlobal) + { + return UnityEngine.Physics.CheckCapsule( + start, end, radius, + layer_mask, + query_trigger_interaction); + } + + // + // CheckSphere + // + + public static bool CheckSphere( + Vector3 position, float radius, + int layer_mask = UnityEngine.Physics.DefaultRaycastLayers, + QueryTriggerInteraction query_trigger_interaction = QueryTriggerInteraction.UseGlobal) + { + return UnityEngine.Physics.CheckSphere( + position, radius, + layer_mask, + query_trigger_interaction); + } + + // + // BoxCast + // + + public static bool BoxCast( + Vector3 center, Vector3 half_extents, Vector3 direction, out IsoRaycastHit iso_hit_info, + float max_distance = Mathf.Infinity, + int layer_mask = UnityEngine.Physics.DefaultRaycastLayers, + QueryTriggerInteraction query_trigger_interaction = QueryTriggerInteraction.UseGlobal) + { + var hit_info = new RaycastHit(); + var result = UnityEngine.Physics.BoxCast( + center, half_extents, direction, out hit_info, + Quaternion.identity, + max_distance, + layer_mask, + query_trigger_interaction); + iso_hit_info = result ? new IsoRaycastHit(hit_info) : new IsoRaycastHit(); + return result; + } + + // + // BoxCastNonAlloc + // + + public static int BoxCastNonAlloc( + Vector3 center, Vector3 half_extents, Vector3 direction, IsoRaycastHit[] results, + float max_distance = Mathf.Infinity, + int layer_mask = UnityEngine.Physics.DefaultRaycastLayers, + QueryTriggerInteraction query_trigger_interaction = QueryTriggerInteraction.UseGlobal) + { + var hit_count = UnityEngine.Physics.BoxCastNonAlloc( + center, half_extents, direction, _raycastNonAllocBuffer, + Quaternion.identity, + max_distance, + layer_mask, + query_trigger_interaction); + return RaycastBufferToIsoRaycastHits(hit_count, results); + } + + // + // CapsuleCast + // + + public static bool CapsuleCast( + Vector3 point1, Vector3 point2, float radius, Vector3 direction, out IsoRaycastHit iso_hit_info, + float max_distance = Mathf.Infinity, + int layer_mask = UnityEngine.Physics.DefaultRaycastLayers, + QueryTriggerInteraction query_trigger_interaction = QueryTriggerInteraction.UseGlobal) + { + var hit_info = new RaycastHit(); + var result = UnityEngine.Physics.CapsuleCast( + point1, point2, radius, direction, out hit_info, + max_distance, + layer_mask, + query_trigger_interaction); + iso_hit_info = result ? new IsoRaycastHit(hit_info) : new IsoRaycastHit(); + return result; + } + + // + // CapsuleCastNonAlloc + // + + public static int CapsuleCastNonAlloc( + Vector3 point1, Vector3 point2, float radius, Vector3 direction, IsoRaycastHit[] results, + float max_distance = Mathf.Infinity, + int layer_mask = UnityEngine.Physics.DefaultRaycastLayers, + QueryTriggerInteraction query_trigger_interaction = QueryTriggerInteraction.UseGlobal) + { + var hit_count = UnityEngine.Physics.CapsuleCastNonAlloc( + point1, point2, radius, direction, _raycastNonAllocBuffer, + max_distance, + layer_mask, + query_trigger_interaction); + return RaycastBufferToIsoRaycastHits(hit_count, results); + } + + // + // SphereCast + // + + public static bool SphereCast( + Vector3 origin, float radius, Vector3 direction, out IsoRaycastHit iso_hit_info, + float max_distance = Mathf.Infinity, + int layer_mask = UnityEngine.Physics.DefaultRaycastLayers, + QueryTriggerInteraction query_trigger_interaction = QueryTriggerInteraction.UseGlobal) + { + var hit_info = new RaycastHit(); + var result = UnityEngine.Physics.SphereCast( + origin, radius, direction, out hit_info, + max_distance, + layer_mask, + query_trigger_interaction); + iso_hit_info = result ? new IsoRaycastHit(hit_info) : new IsoRaycastHit(); + return result; + } + + // + // SphereCastNonAlloc + // + + public static int SphereCastNonAlloc( + Vector3 origin, float radius, Vector3 direction, IsoRaycastHit[] results, + float max_distance = Mathf.Infinity, + int layer_mask = UnityEngine.Physics.DefaultRaycastLayers, + QueryTriggerInteraction query_trigger_interaction = QueryTriggerInteraction.UseGlobal) + { + var hit_count = UnityEngine.Physics.SphereCastNonAlloc( + origin, radius, direction, _raycastNonAllocBuffer, + max_distance, + layer_mask, + query_trigger_interaction); + return RaycastBufferToIsoRaycastHits(hit_count, results); + } + + // + // OverlapBoxNonAlloc + // + + public static int OverlapBoxNonAlloc( + Vector3 center, Vector3 half_extents, IsoCollider[] results, + int layer_mask = UnityEngine.Physics.AllLayers, + QueryTriggerInteraction query_trigger_interaction = QueryTriggerInteraction.UseGlobal) + { + var collider_count = UnityEngine.Physics.OverlapBoxNonAlloc( + center, half_extents, _overlapNonAllocBuffer, + Quaternion.identity, + layer_mask, + query_trigger_interaction); + return OverlapBufferToIsoColliders(collider_count, results); + } + + // + // OverlapCapsuleNonAlloc + // + + public static int OverlapCapsuleNonAlloc( + Vector3 point0, Vector3 point1, float radius, IsoCollider[] results, + int layer_mask = UnityEngine.Physics.AllLayers, + QueryTriggerInteraction query_trigger_interaction = QueryTriggerInteraction.UseGlobal) + { + var collider_count = UnityEngine.Physics.OverlapCapsuleNonAlloc( + point0, point1, radius, _overlapNonAllocBuffer, + layer_mask, + query_trigger_interaction); + return OverlapBufferToIsoColliders(collider_count, results); + } + + // + // OverlapSphereNonAlloc + // + + public static int OverlapSphereNonAlloc( + Vector3 position, float radius, IsoCollider[] results, + int layer_mask = UnityEngine.Physics.AllLayers, + QueryTriggerInteraction query_trigger_interaction = QueryTriggerInteraction.UseGlobal) + { + var collider_count = UnityEngine.Physics.OverlapSphereNonAlloc( + position, radius, _overlapNonAllocBuffer, + layer_mask, + query_trigger_interaction); + return OverlapBufferToIsoColliders(collider_count, results); + } + + // --------------------------------------------------------------------- + // + // Private + // + // --------------------------------------------------------------------- + + static RaycastHit[] _raycastNonAllocBuffer = new RaycastHit[128]; + static int RaycastBufferToIsoRaycastHits(int hit_count, IsoRaycastHit[] results) { var min_hit_count = Mathf.Min(hit_count, results.Length); for ( var i = 0; i < min_hit_count; ++i ) { results[i] = new IsoRaycastHit(_raycastNonAllocBuffer[i]); } - System.Array.Clear(_raycastNonAllocBuffer, 0, _raycastNonAllocBuffer.Length); + System.Array.Clear(_raycastNonAllocBuffer, 0, hit_count); return min_hit_count; } + + static Collider[] _overlapNonAllocBuffer = new Collider[128]; + static int OverlapBufferToIsoColliders(int collider_count, IsoCollider[] results) { + var min_collider_count = Mathf.Min(collider_count, results.Length); + for ( var i = 0; i < min_collider_count; ++i ) { + results[i] = IsoPhysicsUtils.IsoConvertCollider(_overlapNonAllocBuffer[i]); + } + System.Array.Clear(_overlapNonAllocBuffer, 0, collider_count); + return min_collider_count; + } } } \ No newline at end of file diff --git a/Assets/IsoTools/Examples/Scripts/Kenney/AlienDestroyer.cs b/Assets/IsoTools/Examples/Scripts/Kenney/AlienDestroyer.cs index 7ddf6d5..faecc4a 100644 --- a/Assets/IsoTools/Examples/Scripts/Kenney/AlienDestroyer.cs +++ b/Assets/IsoTools/Examples/Scripts/Kenney/AlienDestroyer.cs @@ -4,14 +4,16 @@ using System.Collections; namespace IsoTools.Examples.Kenney { public class AlienDestroyer : MonoBehaviour { + static IsoRaycastHit[] _raycastBuffer = new IsoRaycastHit[16]; + void Update () { var iso_world = IsoWorld.Instance; if ( iso_world && Input.GetMouseButtonDown(0) ) { var iso_mouse_pos = iso_world.MouseIsoPosition(); var ray_from_iso_camera = iso_world.RayFromIsoCameraToIsoPoint(iso_mouse_pos); - var hits = IsoPhysics.RaycastAll(ray_from_iso_camera); - for ( var i = 0; i < hits.Length; ++i ) { - var alien_go = hits[i].collider.gameObject; + var hit_count = IsoPhysics.RaycastNonAlloc(ray_from_iso_camera, _raycastBuffer); + for ( var i = 0; i < hit_count; ++i ) { + var alien_go = _raycastBuffer[i].collider.gameObject; if ( alien_go.GetComponent() ) { Destroy(alien_go); }