|
|
@@ -6,8 +6,8 @@ public class ESpirits_Assassin : Enemy
|
|
|
public enum ESpiritsState
|
|
|
{
|
|
|
None,
|
|
|
- Normal, //正常状态
|
|
|
- FindPlayer, //寻找主角位置
|
|
|
+ Normal, //等待状态
|
|
|
+ FindCharacter, //寻找主角位置
|
|
|
Ready, //冲刺预警
|
|
|
Rushing, //向主角方向冲刺中
|
|
|
ReadyToDown, //准备落地斩
|
|
|
@@ -22,6 +22,7 @@ public class ESpirits_Assassin : Enemy
|
|
|
[Title("ESpirits_Assassin属性")]
|
|
|
[DisplayOnly] public float time;
|
|
|
public float attackCD;
|
|
|
+ [FoldoutGroup("冲刺")] [LabelText("锁敌逻辑")] [Tooltip("X为锁定玩家次数Y为锁定玩家次数,出场优先锁定玩家")] public Vector2 lockingLogic;
|
|
|
[FoldoutGroup("冲刺")] [LabelText("预警距离")] public float readyDistance;
|
|
|
[FoldoutGroup("冲刺")] [LabelText("冲刺距离")] public float rushDistance;
|
|
|
[FoldoutGroup("冲刺")] [LabelText("瞄准时间")] public float readyTime;
|
|
|
@@ -32,6 +33,10 @@ public class ESpirits_Assassin : Enemy
|
|
|
private float endTime;
|
|
|
public AnimationClip fall_endAnimationClip;
|
|
|
private int oldHitResistance;
|
|
|
+ public bool targetIsPlayer;
|
|
|
+ public MoveCharacter lockCharacter;
|
|
|
+ public int lockingNum;
|
|
|
+ public PlayerController player;
|
|
|
public override void Awake()
|
|
|
{
|
|
|
base.Awake();
|
|
|
@@ -44,160 +49,108 @@ public class ESpirits_Assassin : Enemy
|
|
|
base.Start();
|
|
|
len = 1;
|
|
|
dashTrigger.attackMethod.attackInfo.damage = attackController.attackMethod_summon[0].attackInfo.damage;
|
|
|
+
|
|
|
}
|
|
|
|
|
|
public override void Init()
|
|
|
{
|
|
|
base.Init();
|
|
|
time = attackCD;
|
|
|
+ player = PlayersInput.instance[0];
|
|
|
+ lockingNum = 0;
|
|
|
+ targetIsPlayer = true;
|
|
|
}
|
|
|
public override void OnState()
|
|
|
{
|
|
|
- PlayerController playerController = PlayersInput.instance[0];
|
|
|
switch (state)
|
|
|
{
|
|
|
- case CharacterState.Idle:
|
|
|
- case CharacterState.Run:
|
|
|
- switch (eSpiritsState)
|
|
|
+ case CharacterState.Die:
|
|
|
+ base.OnState();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ switch (eSpiritsState)
|
|
|
+ {
|
|
|
+ case ESpiritsState.Normal:
|
|
|
+ time += Time.deltaTime;
|
|
|
+ if (time > attackCD)
|
|
|
{
|
|
|
- case ESpiritsState.Normal:
|
|
|
- time += Time.deltaTime;
|
|
|
- if (time > attackCD)
|
|
|
- {
|
|
|
- eSpiritsState = ESpiritsState.FindPlayer;
|
|
|
- }
|
|
|
- break;
|
|
|
- case ESpiritsState.FindPlayer:
|
|
|
- if (playerController && !playerController.isDie)
|
|
|
- {
|
|
|
- if(Vector3.Distance(playerController.transform.position, transform.position) < readyDistance)
|
|
|
- {
|
|
|
- ChangeState(CharacterState.Attack);
|
|
|
- eSpiritsState = ESpiritsState.Ready;
|
|
|
- hitResistance = 100;
|
|
|
- attributeStatus.resistances.controlOrder = 1;
|
|
|
- rb.useGravity = false;
|
|
|
- rb.velocity = Vector3.zero;
|
|
|
- bodyCollider.SetActive(false);
|
|
|
- ani.Play("charge", 0, 0);
|
|
|
- aimPrefab.transform.localScale = new Vector3(rushDistance / 1.5f, 1, 1);
|
|
|
- directionToTarget = (playerController.transform.position + Vector3.up - aimPrefab.transform.position).normalized;
|
|
|
- angleToTarget = Mathf.Atan2(directionToTarget.y, directionToTarget.x) * Mathf.Rad2Deg;
|
|
|
- aimPrefab.transform.rotation = Quaternion.Euler(0, 0, angleToTarget);
|
|
|
- aimPrefab.SetActive(true);
|
|
|
- time = 0;
|
|
|
- hitFeedbackSystem.canBeHitStun = false;
|
|
|
- }
|
|
|
- }
|
|
|
- break;
|
|
|
- default:
|
|
|
- Debug.LogError("有bug导致刺客状态出错");
|
|
|
- return;
|
|
|
+ ChangeESpiritsState(ESpiritsState.FindCharacter);
|
|
|
}
|
|
|
break;
|
|
|
- case CharacterState.Attack:
|
|
|
- switch (eSpiritsState)
|
|
|
+ case ESpiritsState.FindCharacter:
|
|
|
+ if (lockCharacter == null || lockCharacter.isDie)
|
|
|
{
|
|
|
- case ESpiritsState.Ready:
|
|
|
- time += Time.deltaTime;
|
|
|
- if(time > readyTime)
|
|
|
- {
|
|
|
- time = 0;
|
|
|
- aimPrefab.SetActive(false);
|
|
|
- ani.Play("attack_summon", 0, 0);
|
|
|
- //dashTrigger.SetActive(true);
|
|
|
- eSpiritsState = ESpiritsState.Rushing;
|
|
|
- transform.rotation = Quaternion.Euler(0, 0,
|
|
|
- bodyTrans.localScale.x > 0 ?
|
|
|
- angleToTarget - 180
|
|
|
- : angleToTarget);
|
|
|
- startRushPos = transform.position;
|
|
|
- dashTrigger.gameObject.SetActive(true);
|
|
|
- }
|
|
|
- break;
|
|
|
- case ESpiritsState.Rushing:
|
|
|
- rb.velocity = directionToTarget * rushSpeed;
|
|
|
- if(Vector3.Distance(startRushPos,transform.position) > rushDistance)
|
|
|
- {
|
|
|
- dashTrigger.gameObject.SetActive(false);
|
|
|
- rb.velocity = Vector3.zero;
|
|
|
- Quaternion targetQt = Quaternion.Euler(Vector3.zero);
|
|
|
- if (foot.TrigGround)
|
|
|
- {
|
|
|
- bodyCollider.SetActive(true);
|
|
|
- eSpiritsState = ESpiritsState.DownEnd;
|
|
|
- ani.Play("fall_end", 0, 0);
|
|
|
- rb.useGravity = true;
|
|
|
- if (!foot.haveGravity)
|
|
|
- {
|
|
|
- transform.position = new Vector3(transform.position.x, platformPosY, transform.position.z);
|
|
|
- targetQt = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, platformRotZ);
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- eSpiritsState = ESpiritsState.ReadyToDown;
|
|
|
- ani.Play("charge", 0, 0);
|
|
|
- directionToTarget = Vector3.down;
|
|
|
- angleToTarget = 270;
|
|
|
- }
|
|
|
- transform.rotation = targetQt;
|
|
|
- time = 0;
|
|
|
- }
|
|
|
- break;
|
|
|
- case ESpiritsState.ReadyToDown:
|
|
|
- time += Time.deltaTime;
|
|
|
- if (time > readyTime)
|
|
|
- {
|
|
|
- ani.Play("attack_summon", 0, 0);
|
|
|
- transform.rotation = Quaternion.Euler(0, 0,
|
|
|
- bodyTrans.localScale.x > 0 ?
|
|
|
- angleToTarget - 180
|
|
|
- : angleToTarget);
|
|
|
- //dashTrigger.SetActive(true);
|
|
|
- eSpiritsState = ESpiritsState.Down;
|
|
|
- startRushPos = transform.position;
|
|
|
- }
|
|
|
- break;
|
|
|
- case ESpiritsState.Down:
|
|
|
- rb.velocity = directionToTarget * rushSpeed;
|
|
|
- if (foot.TrigGround)
|
|
|
- {
|
|
|
- bodyCollider.SetActive(true);
|
|
|
- eSpiritsState = ESpiritsState.DownEnd;
|
|
|
- rb.velocity = Vector3.zero;
|
|
|
- ani.Play("fall_end", 0, 0);
|
|
|
- rb.useGravity = true;
|
|
|
- Quaternion targetQt = Quaternion.Euler(Vector3.zero);
|
|
|
- if (!foot.haveGravity)
|
|
|
- {
|
|
|
- transform.position = new Vector3(transform.position.x, platformPosY, transform.position.z);
|
|
|
- targetQt = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, platformRotZ);
|
|
|
- }
|
|
|
- transform.rotation = targetQt;
|
|
|
- time = 0;
|
|
|
- }
|
|
|
- break;
|
|
|
- case ESpiritsState.DownEnd:
|
|
|
- time += Time.deltaTime;
|
|
|
- if(time > endTime)
|
|
|
+ ChooseLockingTarget();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (Vector3.Distance(lockCharacter.transform.position, transform.position) < readyDistance)
|
|
|
+ {
|
|
|
+ ChangeESpiritsState(ESpiritsState.Ready);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ base.OnState();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case ESpiritsState.Ready:
|
|
|
+ time += Time.deltaTime;
|
|
|
+ if (time > readyTime)
|
|
|
+ {
|
|
|
+ ChangeESpiritsState(ESpiritsState.Rushing);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case ESpiritsState.Rushing:
|
|
|
+ rb.velocity = directionToTarget * rushSpeed;
|
|
|
+ if (Vector3.Distance(startRushPos, transform.position) > rushDistance)
|
|
|
+ {
|
|
|
+ dashTrigger.gameObject.SetActive(false);
|
|
|
+ rb.velocity = Vector3.zero;
|
|
|
+ Quaternion targetQt = Quaternion.Euler(Vector3.zero);
|
|
|
+ if (foot.TrigGround)
|
|
|
+ {
|
|
|
+ ChangeESpiritsState(ESpiritsState.DownEnd);
|
|
|
+ if (!foot.haveGravity)
|
|
|
{
|
|
|
- eSpiritsState = ESpiritsState.Normal;
|
|
|
- ani.Play("idle", 0, 0);
|
|
|
- time = 0;
|
|
|
- hitResistance = oldHitResistance;
|
|
|
- attributeStatus.resistances.controlOrder = 0;
|
|
|
- hitFeedbackSystem.canBeHitStun = true;
|
|
|
- ChangeState(CharacterState.Idle);
|
|
|
+ transform.position = new Vector3(transform.position.x, platformPosY, transform.position.z);
|
|
|
+ targetQt = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, platformRotZ);
|
|
|
}
|
|
|
- break;
|
|
|
- default:
|
|
|
- base.OnState();
|
|
|
- break;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ ChangeESpiritsState(ESpiritsState.ReadyToDown);
|
|
|
+ }
|
|
|
+ transform.rotation = targetQt;
|
|
|
}
|
|
|
- return;
|
|
|
+ break;
|
|
|
+ case ESpiritsState.ReadyToDown:
|
|
|
+ time += Time.deltaTime;
|
|
|
+ if (time > readyTime)
|
|
|
+ {
|
|
|
+ ChangeESpiritsState(ESpiritsState.Down);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case ESpiritsState.Down:
|
|
|
+ rb.velocity = directionToTarget * rushSpeed;
|
|
|
+ if (foot.TrigGround)
|
|
|
+ {
|
|
|
+ ChangeESpiritsState(ESpiritsState.DownEnd);
|
|
|
+ Quaternion targetQt = Quaternion.Euler(Vector3.zero);
|
|
|
+ if (!foot.haveGravity)
|
|
|
+ {
|
|
|
+ transform.position = new Vector3(transform.position.x, platformPosY, transform.position.z);
|
|
|
+ targetQt = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, platformRotZ);
|
|
|
+ }
|
|
|
+ transform.rotation = targetQt;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case ESpiritsState.DownEnd:
|
|
|
+ time += Time.deltaTime;
|
|
|
+ if (time > endTime)
|
|
|
+ {
|
|
|
+ ChangeESpiritsState(ESpiritsState.Normal);
|
|
|
+ }
|
|
|
+ break;
|
|
|
}
|
|
|
- base.OnState();
|
|
|
}
|
|
|
|
|
|
public override Vector3 GetMoveDir()
|
|
|
@@ -205,15 +158,14 @@ public class ESpirits_Assassin : Enemy
|
|
|
Vector3 moveDir = Vector3.zero;
|
|
|
switch (eSpiritsState)
|
|
|
{
|
|
|
- case ESpiritsState.FindPlayer:
|
|
|
- PlayerController playerController = PlayersInput.instance[0];
|
|
|
- if (playerController && !playerController.isDie)
|
|
|
+ case ESpiritsState.FindCharacter:
|
|
|
+ if (lockCharacter && !lockCharacter.isDie)
|
|
|
{
|
|
|
- if (playerController.transform.position.x - transform.position.x < -1)
|
|
|
+ if (lockCharacter.transform.position.x - transform.position.x < -1)
|
|
|
{
|
|
|
moveDir = Vector3.left;
|
|
|
}
|
|
|
- else if (playerController.transform.position.x - transform.position.x > 1)
|
|
|
+ else if (lockCharacter.transform.position.x - transform.position.x > 1)
|
|
|
{
|
|
|
moveDir = Vector3.right;
|
|
|
}
|
|
|
@@ -228,7 +180,6 @@ public class ESpirits_Assassin : Enemy
|
|
|
return Vector3.zero;
|
|
|
}
|
|
|
return base.GetMoveDir();
|
|
|
-
|
|
|
}
|
|
|
|
|
|
public override bool GetAttack()
|
|
|
@@ -245,11 +196,20 @@ public class ESpirits_Assassin : Enemy
|
|
|
|
|
|
public override void ChangeState(CharacterState newState)
|
|
|
{
|
|
|
+ switch (newState)
|
|
|
+ {
|
|
|
+ case CharacterState.Die:
|
|
|
+ base.ChangeState(newState);
|
|
|
+ return;
|
|
|
+ }
|
|
|
switch (eSpiritsState)
|
|
|
{
|
|
|
case ESpiritsState.Ready:
|
|
|
switch (newState)
|
|
|
{
|
|
|
+ case CharacterState.Attack:
|
|
|
+ state = CharacterState.Attack;
|
|
|
+ break;
|
|
|
case CharacterState.Die:
|
|
|
base.ChangeState(newState);
|
|
|
break;
|
|
|
@@ -260,4 +220,139 @@ public class ESpirits_Assassin : Enemy
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ public void ChangeESpiritsState(ESpiritsState newESpiritsState)
|
|
|
+ {
|
|
|
+ switch (eSpiritsState)
|
|
|
+ {
|
|
|
+ case ESpiritsState.Normal:
|
|
|
+ case ESpiritsState.Ready:
|
|
|
+ case ESpiritsState.ReadyToDown:
|
|
|
+ time = 0;
|
|
|
+ break;
|
|
|
+ case ESpiritsState.Rushing:
|
|
|
+ case ESpiritsState.Down:
|
|
|
+ dashTrigger.gameObject.SetActive(false);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ eSpiritsState = newESpiritsState;
|
|
|
+ switch (eSpiritsState)
|
|
|
+ {
|
|
|
+ case ESpiritsState.Normal:
|
|
|
+ time = 0;
|
|
|
+ ani.Play("idle", 0, 0);
|
|
|
+ hitResistance = oldHitResistance;
|
|
|
+ attributeStatus.resistances.controlOrder = 0;
|
|
|
+ hitFeedbackSystem.canBeHitStun = true;
|
|
|
+ ChangeState(CharacterState.Idle);
|
|
|
+ break;
|
|
|
+ case ESpiritsState.FindCharacter:
|
|
|
+ ChooseLockingTarget();
|
|
|
+ ChangeSearchState(SearchState.InSearchScope);
|
|
|
+ break;
|
|
|
+ case ESpiritsState.Ready:
|
|
|
+ ChangeState(CharacterState.Attack);
|
|
|
+ hitResistance = 100;
|
|
|
+ attributeStatus.resistances.controlOrder = 1;
|
|
|
+ rb.useGravity = false;
|
|
|
+ rb.velocity = Vector3.zero;
|
|
|
+ bodyCollider.SetActive(false);
|
|
|
+ ani.Play("charge", 0, 0);
|
|
|
+ aimPrefab.transform.localScale = new Vector3(rushDistance / 1.5f, 1, 1);
|
|
|
+ directionToTarget = (lockCharacter.transform.position + Vector3.up - aimPrefab.transform.position).normalized;
|
|
|
+ CheckTurn(directionToTarget.x);
|
|
|
+ angleToTarget = Mathf.Atan2(directionToTarget.y, directionToTarget.x) * Mathf.Rad2Deg;
|
|
|
+ aimPrefab.transform.rotation = Quaternion.Euler(0, 0, angleToTarget);
|
|
|
+ aimPrefab.SetActive(true);
|
|
|
+ time = 0;
|
|
|
+ hitFeedbackSystem.canBeHitStun = false;
|
|
|
+ break;
|
|
|
+ case ESpiritsState.Rushing:
|
|
|
+ time = 0;
|
|
|
+ aimPrefab.SetActive(false);
|
|
|
+ ani.Play("attack_summon", 0, 0);
|
|
|
+ transform.rotation = Quaternion.Euler(0, 0,
|
|
|
+ bodyTrans.localScale.x > 0 ?
|
|
|
+ angleToTarget - 180
|
|
|
+ : angleToTarget);
|
|
|
+ startRushPos = transform.position;
|
|
|
+ dashTrigger.gameObject.SetActive(true);
|
|
|
+ break;
|
|
|
+ case ESpiritsState.DownEnd:
|
|
|
+ bodyCollider.SetActive(true);
|
|
|
+ ani.Play("fall_end", 0, 0);
|
|
|
+ rb.useGravity = true;
|
|
|
+ break;
|
|
|
+ case ESpiritsState.ReadyToDown:
|
|
|
+ ani.Play("charge", 0, 0);
|
|
|
+ directionToTarget = Vector3.down;
|
|
|
+ angleToTarget = 270;
|
|
|
+ break;
|
|
|
+ case ESpiritsState.Down:
|
|
|
+ ani.Play("attack_summon", 0, 0);
|
|
|
+ transform.rotation = Quaternion.Euler(0, 0,
|
|
|
+ bodyTrans.localScale.x > 0 ?
|
|
|
+ angleToTarget - 180
|
|
|
+ : angleToTarget);
|
|
|
+ startRushPos = transform.position;
|
|
|
+ dashTrigger.gameObject.SetActive(true);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void ChooseLockingTarget()
|
|
|
+ {
|
|
|
+ lockingNum++;
|
|
|
+ if (targetIsPlayer)
|
|
|
+ {
|
|
|
+ if (lockingNum > lockingLogic.x)
|
|
|
+ {
|
|
|
+ targetIsPlayer = false;
|
|
|
+ lockingNum = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ lockCharacter = player;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (lockingNum > lockingLogic.y)
|
|
|
+ {
|
|
|
+ targetIsPlayer = true;
|
|
|
+ lockingNum = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if(player.demonicDic[0].Count == 0)
|
|
|
+ {
|
|
|
+ lockCharacter = player;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ lockCharacter = player.demonicDic[0][0];
|
|
|
+ Vector3 myPos = transform.position;
|
|
|
+ float minDistance = Vector3.Distance(myPos, lockCharacter.transform.position);
|
|
|
+ for (int i = 0; i < player.demonicDic[0].Count; i++)
|
|
|
+ {
|
|
|
+ Demonic demonic = player.demonicDic[0][i];
|
|
|
+ float distance = Vector3.Distance(myPos, demonic.transform.position);
|
|
|
+ if(minDistance > distance)
|
|
|
+ {
|
|
|
+ minDistance = distance;
|
|
|
+ lockCharacter = demonic;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public override void OnSearchState()
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
}
|