diff options
Diffstat (limited to 'Assets/Scripts/Unit/Collider')
-rw-r--r-- | Assets/Scripts/Unit/Collider/ColliderBox_Hitbox.cs | 13 | ||||
-rw-r--r-- | Assets/Scripts/Unit/Collider/CollisionSystem.cs | 110 |
2 files changed, 116 insertions, 7 deletions
diff --git a/Assets/Scripts/Unit/Collider/ColliderBox_Hitbox.cs b/Assets/Scripts/Unit/Collider/ColliderBox_Hitbox.cs index be0749fd..2044ae7d 100644 --- a/Assets/Scripts/Unit/Collider/ColliderBox_Hitbox.cs +++ b/Assets/Scripts/Unit/Collider/ColliderBox_Hitbox.cs @@ -37,14 +37,25 @@ public partial class ColliderBox Red = 2,
}
+ // 击中反馈
+ public enum EHitResponse
+ {
+ Light = 0,
+ Heavy = 1,
+ HitAir = 2,
+ HitGround = 3
+ }
+
[ColliderType(EColliderType.HitBox)]
[Tooltip("允许多次击中")] public bool multiHit;
+ public EHitResponse hitResponse;
+
[Tooltip("击退距离")]
public Vector3 hitBack; -
+ [Comment("[ 击中效果 ]", TextAnchor.MiddleCenter)]
[Foldout("时间效果", 2)]
diff --git a/Assets/Scripts/Unit/Collider/CollisionSystem.cs b/Assets/Scripts/Unit/Collider/CollisionSystem.cs index efbb2784..d5c96d0c 100644 --- a/Assets/Scripts/Unit/Collider/CollisionSystem.cs +++ b/Assets/Scripts/Unit/Collider/CollisionSystem.cs @@ -8,10 +8,18 @@ public struct ColliderDescriptor public UnitCollider unitCollider; } +public struct Box
+{
+ public Vector3 center;
+ public Vector3 size;
+} + public struct CollisionInfo { - ColliderDescriptor collider; // 主动 - ColliderDescriptor collidee; // 从动 + public ColliderDescriptor collider; // 主动
+ public ColliderDescriptor collidee; // 从动 + public Box intersection; + public bool isCollision; } public class CollisionSystem : SingletonMB<CollisionSystem> @@ -77,10 +85,19 @@ public class CollisionSystem : SingletonMB<CollisionSystem> for (int j = 0; j < hurtboxes.Count; ++j) { ColliderDescriptor hurtbox = hurtboxes[j]; - if (hitbox.unitCollider == hurtbox.unitCollider) // 同一个角色的hitbox和hurtbox不交互 - continue; - - } + if (hitbox.unitCollider == hurtbox.unitCollider) + continue;
+ if (hitbox.unitCollider.owner.type == hurtbox.unitCollider.owner.type) + continue; + CollisionInfo collision = ColliderUtility.GetCollision(hitbox, hurtbox); + if (!collision.isCollision) + continue; + if (!hitbox.unitCollider.CanCollide(hitbox.colliderInfo.colliderHash, hurtbox.unitCollider.owner.GetHashCode())) + continue; + hitbox.unitCollider.RecordCollision(hitbox.colliderInfo.colliderHash, hurtbox.unitCollider.owner.GetHashCode()); + hitbox.unitCollider.owner.OnHit(collision); + hurtbox.unitCollider.owner.OnGetHit(collision); + } } ListPool<ColliderDescriptor>.Release(hitboxes); @@ -105,4 +122,85 @@ public class CollisionSystem : SingletonMB<CollisionSystem> } + private void OnDrawGizmos()
+ {
+ } + } + +public static class ColliderUtility
+{
+ public static CollisionInfo GetCollision(ColliderDescriptor collider, ColliderDescriptor collidee)
+ {
+ CollisionInfo collision = new CollisionInfo();
+ collision.collider = collider;
+ collision.collidee = collidee;
+ Box colliderBox = GetColliderInWorldSpace(collider);
+ Box collideeBox = GetColliderInWorldSpace(collidee);
+ Box intersection = GetIntersection(colliderBox, collideeBox);
+ collision.intersection = intersection;
+ collision.isCollision = intersection.size.magnitude != 0;
+ return collision;
+ }
+
+ public static Box GetColliderInWorldSpace(ColliderDescriptor collider)
+ {
+ Box box = new Box();
+ Vector3 fac = new Vector3(1, 1, collider.unitCollider.owner.transform.forward.normalized == Vector3.forward ? 1 : -1);
+ Vector3 unitPos = collider.unitCollider.owner.transform.position;
+ Vector3 pos = Vector3.zero; // gizmo位置
+ Vector3 localPos = collider.colliderInfo.position;
+ Vector3 localSize = collider.colliderInfo.size;
+ var pivot = collider.colliderInfo.pivot;
+ switch (pivot)
+ {
+ case ColliderBox.Pivot.MiddleBottom:
+ localPos.y += localSize.y / 2;
+ break;
+ }
+ pos = unitPos + Vector3.Scale(localPos, fac);
+ box.center = pos;
+ box.size = localSize;
+ return box;
+ }
+
+ public static Box GetIntersection(Box b1, Box b2)
+ {
+ bool isIntersection = true;
+
+ float l1 = b1.center.x - b1.size.x / 2;
+ float r1 = b1.center.x + b1.size.x / 2;
+ float l2 = b2.center.x - b2.size.x / 2;
+ float r2 = b2.center.x + b2.size.x / 2;
+ isIntersection &= r1 >= l2 && l1 <= r2;
+
+ float o1 = b1.center.y - b1.size.y / 2;
+ float t1 = b1.center.y + b1.size.y / 2;
+ float o2 = b2.center.y - b2.size.y / 2;
+ float t2 = b2.center.y + b2.size.y / 2;
+ isIntersection &= t1 >= o2 && o1 <= t2;
+
+ float c1 = b1.center.z - b1.size.z / 2;
+ float f1 = b1.center.z + b1.size.z / 2;
+ float c2 = b2.center.z - b2.size.z / 2;
+ float f2 = b2.center.z + b2.size.z / 2;
+ isIntersection &= f1 >= c2 && c1 <= f2;
+
+ if(!isIntersection)
+ {
+ return new Box();
+ }
+
+ Box box = new Box();
+ float l = Mathf.Max(l1, l2);
+ float r = Mathf.Min(r1, r2);
+ float b = Mathf.Max(o1, o2);
+ float t = Mathf.Min(t1, t2);
+ float c = Mathf.Max(c1, c2);
+ float f = Mathf.Max(f1, f2);
+ box.center = new Vector3((l + r) / 2, (b + t) / 2, (c + f) / 2 );
+ box.size = new Vector3(r - l, t - b, f - c);
+ return box;
+ }
+
+}
\ No newline at end of file |