summaryrefslogtreecommitdiff
path: root/Assets/Scripts/Unit/Components/UnitCollider.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Assets/Scripts/Unit/Components/UnitCollider.cs')
-rw-r--r--Assets/Scripts/Unit/Components/UnitCollider.cs123
1 files changed, 123 insertions, 0 deletions
diff --git a/Assets/Scripts/Unit/Components/UnitCollider.cs b/Assets/Scripts/Unit/Components/UnitCollider.cs
new file mode 100644
index 00000000..63e1ff7f
--- /dev/null
+++ b/Assets/Scripts/Unit/Components/UnitCollider.cs
@@ -0,0 +1,123 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+// 角色当前的碰撞盒
+[DisallowMultipleComponent]
+public class UnitCollider : UnitComponent
+{
+ public bool showGizmos;
+
+ private Dictionary<int/*hitbox hash*/, List<int/*unitController hash*/>> m_HitMask = new Dictionary<int, List<int>>();
+
+ public override void Awake()
+ {
+ base.Awake();
+
+ ColliderRegistry.Instance.AddCollider(this);
+ }
+
+ public override void OnDestroy()
+ {
+ ColliderRegistry.Instance.RemoveCollider(this);
+
+ base.OnDestroy();
+ }
+
+ public override void Initialize()
+ {
+ base.Initialize();
+ showGizmos = true;
+ }
+
+ // 返回当前激活的对应类型的碰撞盒数据
+ public ColliderInfo[] GetCurrentBoxesInfoByType(ColliderBox.EColliderType type, int layer = 0)
+ {
+ var layerInfo = m_Owner.unitAnimation.layers[0];
+ AnimationData animData = layerInfo.animationData;
+ AnimatorClipInfo[] clipInfos = layerInfo.clipInfo;
+ //if(clipInfos == null || clipInfos.Length == 0)
+ //{
+ // return null;
+ //}
+ float playbackTime = layerInfo.playbackNormalizedTime * clipInfos[0].clip.length;
+ //float playbackTime = layerInfo.playbackRealTimeInSeconds;
+ ColliderInfo[] infos = animData.GetActiveCollidersInfo(type, playbackTime);
+ return infos;
+ }
+
+ // 动作切换,重置collider mask
+ public void OnAnimationChange()
+ {
+ m_HitMask.Clear();
+ }
+
+ public void RecordCollision(int colliderHash, int targetHash)
+ {
+ List<int> record;
+ if (!m_HitMask.TryGetValue(colliderHash, out record))
+ {
+ record = new List<int>();
+ m_HitMask.Add(colliderHash, record);
+ }
+ record.Add(targetHash);
+ }
+
+ public bool CanCollide(int colliderHash, int targetHash)
+ {
+ List<int> record;
+ if(!m_HitMask.TryGetValue(colliderHash, out record))
+ {
+ return true;
+ }
+ return !record.Contains(targetHash);
+ }
+
+#if UNITY_EDITOR
+
+ // 绘制collider调试
+ public void OnDrawGizmos()
+ {
+ if (!showGizmos)
+ return;
+
+ Vector3 unitPos = m_Owner.transform.position;
+
+ OnDrawColliders(ColliderBox.EColliderType.HurtBox, Color.green);
+ OnDrawColliders(ColliderBox.EColliderType.HitBox, Color.red);
+ }
+
+ void OnDrawColliders(ColliderBox.EColliderType type, Color color)
+ {
+ ColliderInfo[] boxes = GetCurrentBoxesInfoByType(type);
+ if (boxes == null || boxes.Length == 0)
+ return;
+ Vector3 unitPos = m_Owner.transform.position;
+ Quaternion right = Quaternion.Euler(0, 0, 0);
+ Vector3 fac = new Vector3(1,1, m_Owner.transform.forward.normalized == Vector3.forward ? 1 : -1);
+ Color oldC = Gizmos.color;
+ Gizmos.color = color * 0.5f;
+ for (int i = 0; i < boxes.Length; ++i)
+ {
+ var box = boxes[i];
+ if (!box.isValid)
+ continue;
+ Vector3 localPos = box.position;
+ Vector3 localSize = box.size;
+ var pivot = box.pivot;
+ Vector3 pos = Vector3.zero; // gizmo位置
+ switch (pivot)
+ {
+ case ColliderBox.Pivot.MiddleBottom:
+ localPos.y += localSize.y / 2;
+ break;
+ }
+ pos = unitPos + Vector3.Scale(localPos, fac);
+ Gizmos.DrawCube(pos, localSize);
+ }
+ Gizmos.color = oldC;
+ }
+
+#endif
+
+}