summaryrefslogtreecommitdiff
path: root/Assets/Scripts/Unit
diff options
context:
space:
mode:
Diffstat (limited to 'Assets/Scripts/Unit')
-rw-r--r--Assets/Scripts/Unit/Collider/ColliderBox_Hitbox.cs13
-rw-r--r--Assets/Scripts/Unit/Collider/CollisionSystem.cs110
-rw-r--r--Assets/Scripts/Unit/Component/MonsterAnimation.cs8
-rw-r--r--Assets/Scripts/Unit/Component/MonsterState.cs40
-rw-r--r--Assets/Scripts/Unit/Component/PCAnimation.cs2
-rw-r--r--Assets/Scripts/Unit/Component/UnitCollider.cs22
-rw-r--r--Assets/Scripts/Unit/Controller/MonsterController.cs41
-rw-r--r--Assets/Scripts/Unit/Controller/PCController.cs21
-rw-r--r--Assets/Scripts/Unit/Controller/UnitController.cs16
9 files changed, 247 insertions, 26 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
diff --git a/Assets/Scripts/Unit/Component/MonsterAnimation.cs b/Assets/Scripts/Unit/Component/MonsterAnimation.cs
index f536c5ef..a59443e0 100644
--- a/Assets/Scripts/Unit/Component/MonsterAnimation.cs
+++ b/Assets/Scripts/Unit/Component/MonsterAnimation.cs
@@ -86,9 +86,15 @@ public class MonsterAnimation : UnitAnimation
m_Owner.unitRootMotion.UpdateRootMotion();
}
-
public void AnimIdle()
{
m_Animator.CrossFade("Idle", 0.2f, 0);
}
+
+ public void AnimHitLight()
+ {
+ m_Animator.Play("HitLight", 0, 0);
+ //m_Animator.CrossFade("HitLight", 0.05f, 0, 0, 0);
+ }
+
}
diff --git a/Assets/Scripts/Unit/Component/MonsterState.cs b/Assets/Scripts/Unit/Component/MonsterState.cs
index 2beba0d5..b1ff9cbd 100644
--- a/Assets/Scripts/Unit/Component/MonsterState.cs
+++ b/Assets/Scripts/Unit/Component/MonsterState.cs
@@ -14,6 +14,7 @@ public class MonsterState : UnitState
Move,
+ HitLight,
HitAir,
HitGround,
HitFall,
@@ -73,23 +74,25 @@ public class MonsterState : UnitState
public struct LandingParam { }
+ public struct HitLightParam { }
+
#region Idle
IEnumerator Idle(IdleParam param)
{
- if (m_Owner.isInAir) // 浮空切换到landing
- {
- ChangeState(EUnitState.Landing, new LandingParam());
- }
- else // idle
- {
+ //if (m_Owner.isInAir) // 浮空切换到landing
+ //{
+ // ChangeState(EUnitState.Landing, new LandingParam());
+ //}
+ //else // idle
+ //{
m_Owner.SetYPosition(0);
m_Owner.monsterAnimation.AnimIdle();
while (true)
{
yield return null;
}
- }
+ //}
}
void OnIdleExit(EUnitState nextState)
@@ -97,5 +100,28 @@ public class MonsterState : UnitState
}
#endregion
+ #region HitLight
+
+ IEnumerator HitLight(HitLightParam param)
+ {
+ m_Owner.monsterAnimation.AnimHitLight();
+ yield return null;
+ while (true)
+ {
+ bool reachEnd = m_Owner.monsterAnimation.layers[0].playbackNomralizedTime == 1;
+ if(reachEnd)
+ {
+ ChangeState(EUnitState.Idle, new IdleParam());
+ }
+ yield return null;
+ }
+ }
+
+ void OnHitLightExit(EUnitState nextState)
+ {
+ }
+
+ #endregion
+
} \ No newline at end of file
diff --git a/Assets/Scripts/Unit/Component/PCAnimation.cs b/Assets/Scripts/Unit/Component/PCAnimation.cs
index 878c9b7c..9c2a77ec 100644
--- a/Assets/Scripts/Unit/Component/PCAnimation.cs
+++ b/Assets/Scripts/Unit/Component/PCAnimation.cs
@@ -152,6 +152,7 @@ public class PCAnimation : UnitAnimation
public void AnimAirAttack(int id)
{
+ m_Owner.unitCollider.OnAnimationChange();
#if ANIM_CROSS_FADE
m_Animator.CrossFade("AirAttack" + id, 0.05f);
#else
@@ -162,6 +163,7 @@ public class PCAnimation : UnitAnimation
public void AnimAttack(int id)
{
+ m_Owner.unitCollider.OnAnimationChange();
m_Animator.CrossFade("Attack" + id, 0.05f);
}
diff --git a/Assets/Scripts/Unit/Component/UnitCollider.cs b/Assets/Scripts/Unit/Component/UnitCollider.cs
index 8813ccef..f3170d1b 100644
--- a/Assets/Scripts/Unit/Component/UnitCollider.cs
+++ b/Assets/Scripts/Unit/Component/UnitCollider.cs
@@ -50,17 +50,27 @@ public class UnitCollider : UnitComponent
public void OnAnimationChange()
{
hitMask.Clear();
-
}
- public void RecordCollision()
+ public void RecordCollision(int colliderHash, int targetHash)
{
+ List<int> record;
+ if (!hitMask.TryGetValue(colliderHash, out record))
+ {
+ record = new List<int>();
+ hitMask.Add(colliderHash, record);
+ }
+ record.Add(targetHash);
+ }
- }
-
- public bool CanCollide()
+ public bool CanCollide(int colliderHash, int targetHash)
{
- return true;
+ List<int> record;
+ if(!hitMask.TryGetValue(colliderHash, out record))
+ {
+ return true;
+ }
+ return !record.Contains(targetHash);
}
#if UNITY_EDITOR
diff --git a/Assets/Scripts/Unit/Controller/MonsterController.cs b/Assets/Scripts/Unit/Controller/MonsterController.cs
index ba738dfc..29ac9dcd 100644
--- a/Assets/Scripts/Unit/Controller/MonsterController.cs
+++ b/Assets/Scripts/Unit/Controller/MonsterController.cs
@@ -1,9 +1,21 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
+#if UNITY_EDITOR
+using UnityEditor;
+#endif
public class MonsterController : UnitController
{
+ public override UnitType type { get { return UnitType.Monster; } }
+
+ public Vector3 center
+ {
+ get
+ {
+ return GetComponentInChildren<Renderer>().bounds.center;
+ }
+ }
public override void Initialize(GameObject obj, string folder)
{
@@ -19,9 +31,34 @@ public class MonsterController : UnitController
public override void Update()
{
base.Update();
+ }
-
+ public override void OnHit(CollisionInfo info)
+ {
}
+ public override void OnGetHit(CollisionInfo info)
+ {
+ ColliderBox hitbox = info.collider.colliderInfo.collider;
+ Debug.Assert(hitbox.type == ColliderBox.EColliderType.HitBox);
+
+ if(hitbox.hitResponse == ColliderBox.EHitResponse.Light)
+ {
+ monsterState.ChangeState(MonsterState.EUnitState.HitLight, new MonsterState.HitLightParam());
+ }
+ else if(hitbox.hitResponse == ColliderBox.EHitResponse.HitAir)
+ {
+ }
+
+ string path = hitbox.sparkPath;
+#if UNITY_EDITOR
+ GameObject vfx = AssetDatabase.LoadAssetAtPath<GameObject>(path);
+ if(vfx != null)
+ {
+ GameObject go = GameObject.Instantiate(vfx);
+ go.transform.position = center;
+ }
+#endif
+ }
-}
+} \ No newline at end of file
diff --git a/Assets/Scripts/Unit/Controller/PCController.cs b/Assets/Scripts/Unit/Controller/PCController.cs
index 5ad3abc1..93228d31 100644
--- a/Assets/Scripts/Unit/Controller/PCController.cs
+++ b/Assets/Scripts/Unit/Controller/PCController.cs
@@ -8,7 +8,9 @@ public class PCController : UnitController
{
public static PCController instance;
- private void Awake()
+ public override UnitType type { get { return UnitType.PC; } }
+
+ private void Awake()
{
instance = this;
}
@@ -29,4 +31,21 @@ public class PCController : UnitController
base.Update();
}
+ public override void OnHit(CollisionInfo info)
+ {
+ }
+
+ public override void OnGetHit(CollisionInfo info)
+ {
+ }
+
+ public override void OnGrab()
+ {
+ }
+
+ public override void OnPull()
+ {
+ }
+
+
}
diff --git a/Assets/Scripts/Unit/Controller/UnitController.cs b/Assets/Scripts/Unit/Controller/UnitController.cs
index b1db29d4..3568cb4e 100644
--- a/Assets/Scripts/Unit/Controller/UnitController.cs
+++ b/Assets/Scripts/Unit/Controller/UnitController.cs
@@ -11,6 +11,15 @@ using UnityEngine;
public class UnitController : MonoBehaviour/*, Interactable*/
{
+ public enum UnitType
+ {
+ PC,
+ Monster,
+ Prop,
+ }
+
+ public virtual UnitType type { get; }
+
// 角色共有的组件
public UnitRender unitRender;
@@ -106,11 +115,11 @@ public class UnitController : MonoBehaviour/*, Interactable*/
{
}
- public virtual void OnHit()
+ public virtual void OnHit(CollisionInfo info)
{
}
- public virtual void OnHurt()
+ public virtual void OnGetHit(CollisionInfo info)
{
}
@@ -118,6 +127,9 @@ public class UnitController : MonoBehaviour/*, Interactable*/
{
}
+ public virtual void OnPull()
+ {
+ }
public void SetYPosition(float y)
{