|
@@ -0,0 +1,559 @@
|
|
|
|
|
+using System.Collections;
|
|
|
|
|
+using System.Collections.Generic;
|
|
|
|
|
+using Unity.VisualScripting;
|
|
|
|
|
+using UnityEngine;
|
|
|
|
|
+using PathCreation;
|
|
|
|
|
+using Sirenix.OdinInspector;
|
|
|
|
|
+
|
|
|
|
|
+public class Monkey : Enemy
|
|
|
|
|
+{
|
|
|
|
|
+ private string currentAnimation;
|
|
|
|
|
+ [Header("逃跑组件")]
|
|
|
|
|
+ public float escapeSpeed; //逃跑速度
|
|
|
|
|
+ public float distanceToTowerDeviation; //怪物逃跑靠近塔的距离偏差,防止怪物堆在一起
|
|
|
|
|
+ public float distanceToTowerBase; //怪物逃跑靠近塔的基础距离
|
|
|
|
|
+ public float distanceToEnemyDeviation; //怪物逃跑靠近坦克敌人的距离偏差,防止怪物堆在一起
|
|
|
|
|
+ public float distanceToEnemyBase; //怪物逃跑靠近坦克敌人的基础距离
|
|
|
|
|
+ private float distanceToTower;
|
|
|
|
|
+ private float distanceToEnemy;
|
|
|
|
|
+ [Header("攀爬组件")]
|
|
|
|
|
+ public float climbSpeed;
|
|
|
|
|
+ public PathCreator pathCreator;
|
|
|
|
|
+ private float dstTravelled;
|
|
|
|
|
+ private bool isReady = false;
|
|
|
|
|
+ private bool isArrived = false;
|
|
|
|
|
+ private float targetPoint;
|
|
|
|
|
+ private bool isOnTree = false;
|
|
|
|
|
+ private EscapeTrigger escapeTrigger;
|
|
|
|
|
+ public MonkeyState monkeyState = MonkeyState.None;
|
|
|
|
|
+
|
|
|
|
|
+ public override void Awake()
|
|
|
|
|
+ {
|
|
|
|
|
+ base.Awake();
|
|
|
|
|
+ searchTrigger.TryGetComponent<EscapeTrigger>(out escapeTrigger);
|
|
|
|
|
+ if (escapeTrigger == null) escapeTrigger = searchTrigger.AddComponent<EscapeTrigger>();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public void ChangeAnimation(string animation,float crossFade = 0.2f)
|
|
|
|
|
+ {
|
|
|
|
|
+ if(currentAnimation == animation) return;
|
|
|
|
|
+ currentAnimation = animation;
|
|
|
|
|
+ ani.CrossFade(currentAnimation, crossFade);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public override void ChangeState(CharacterState newState)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (state == newState)
|
|
|
|
|
+ {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ ChangeMonkeyState(MonkeyState.None);
|
|
|
|
|
+ Debug.Log("从" + state + "切换到" + newState);
|
|
|
|
|
+ switch (state)
|
|
|
|
|
+ {
|
|
|
|
|
+ case CharacterState.Run:
|
|
|
|
|
+ rb.velocity = Vector3.zero;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case CharacterState.Rush:
|
|
|
|
|
+ rb.velocity = Vector3.zero;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case CharacterState.Rise:
|
|
|
|
|
+ if (!canFly)
|
|
|
|
|
+ {
|
|
|
|
|
+ bodyCollider.SetActive(true);
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ case CharacterState.Fall:
|
|
|
|
|
+ rb.velocity = Vector3.zero;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case CharacterState.Attack:
|
|
|
|
|
+ attackController.ChooseAttack(curAttackID);
|
|
|
|
|
+ attackController.isAttackTriggerOn = false;
|
|
|
|
|
+ attackController.attackTrigger.gameObject.SetActive(false);
|
|
|
|
|
+ break;
|
|
|
|
|
+ case CharacterState.Die:
|
|
|
|
|
+ isDie = false;
|
|
|
|
|
+ break;
|
|
|
|
|
+ default:
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ CharacterState oldState = state;
|
|
|
|
|
+ state = newState;
|
|
|
|
|
+ switch (newState)
|
|
|
|
|
+ {
|
|
|
|
|
+ case CharacterState.Idle:
|
|
|
|
|
+ if (!isConAttack || attackController.attackInterval > 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ //ani.Play("idle", 0, 0);
|
|
|
|
|
+ ChangeAnimation("idle");
|
|
|
|
|
+ }
|
|
|
|
|
+ rb.velocity = Vector3.zero;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case CharacterState.Run:
|
|
|
|
|
+ //ani.Play("walk", 0, 0);
|
|
|
|
|
+ ChangeAnimation("walk");
|
|
|
|
|
+ break;
|
|
|
|
|
+ case CharacterState.Rush:
|
|
|
|
|
+ //ani.Play("rush", 0, 0);
|
|
|
|
|
+ ChangeAnimation("rush");
|
|
|
|
|
+ break;
|
|
|
|
|
+ case CharacterState.Attack:
|
|
|
|
|
+ break;
|
|
|
|
|
+ case CharacterState.Die:
|
|
|
|
|
+ //ani.Play("die", 0, 0);
|
|
|
|
|
+ ChangeAnimation("die",0);
|
|
|
|
|
+ isDie = true;
|
|
|
|
|
+ dieKeepTime = totalDieKeepTime;
|
|
|
|
|
+ DropSouls();
|
|
|
|
|
+ break;
|
|
|
|
|
+ case CharacterState.HitStun:
|
|
|
|
|
+ canNotShotDown = true;
|
|
|
|
|
+ if (isOnTree)
|
|
|
|
|
+ {
|
|
|
|
|
+ rb.useGravity = true;
|
|
|
|
|
+ isOnTree = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ default:
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public void ChangeMonkeyState(MonkeyState newState)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (monkeyState == newState)
|
|
|
|
|
+ {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ switch (monkeyState)
|
|
|
|
|
+ {
|
|
|
|
|
+ case MonkeyState.Climb:
|
|
|
|
|
+ if (!isOnTree)
|
|
|
|
|
+ {
|
|
|
|
|
+ rb.useGravity = true;
|
|
|
|
|
+ canNotShotDown = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ monkeyState = newState;
|
|
|
|
|
+ switch (newState)
|
|
|
|
|
+ {
|
|
|
|
|
+ case MonkeyState.None:
|
|
|
|
|
+ ChangeState(CharacterState.Idle);
|
|
|
|
|
+ break;
|
|
|
|
|
+ case MonkeyState.Escape:
|
|
|
|
|
+ distanceToTower = distanceToTowerBase + Random.Range(-distanceToTowerDeviation, distanceToTowerDeviation);
|
|
|
|
|
+ distanceToEnemy = distanceToEnemyBase + Random.Range(-distanceToEnemyDeviation, distanceToEnemyDeviation);
|
|
|
|
|
+ ChangeAnimation("walk");
|
|
|
|
|
+ Turn();
|
|
|
|
|
+ break;
|
|
|
|
|
+ case MonkeyState.WaitForTank:
|
|
|
|
|
+ ChangeAnimation("idle");
|
|
|
|
|
+ rb.velocity = Vector3.zero;
|
|
|
|
|
+ transform.rotation = Quaternion.identity;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case MonkeyState.Climb:
|
|
|
|
|
+ if (!isOnTree)
|
|
|
|
|
+ {
|
|
|
|
|
+ ChangeAnimation("clamp");
|
|
|
|
|
+ isReady = false;
|
|
|
|
|
+ isArrived = false;
|
|
|
|
|
+ dstTravelled = 0f;
|
|
|
|
|
+ targetPoint = Random.Range(0.6f, 1f);
|
|
|
|
|
+ rb.useGravity = false;
|
|
|
|
|
+ isOnTree = true;
|
|
|
|
|
+ canNotShotDown = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public override void FixedUpdate()
|
|
|
|
|
+ {
|
|
|
|
|
+ base.FixedUpdate();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public override void OnState()
|
|
|
|
|
+ {
|
|
|
|
|
+ if (state == CharacterState.None)
|
|
|
|
|
+ {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ //hurtKeepTime -= Time.deltaTime;
|
|
|
|
|
+ dieKeepTime -= Time.deltaTime;
|
|
|
|
|
+ invincibleTime -= Time.deltaTime;
|
|
|
|
|
+ pastAttackTime += Time.deltaTime;
|
|
|
|
|
+ Vector3 leftDir = GetMoveDir();
|
|
|
|
|
+ bool isAttack = GetAttack();
|
|
|
|
|
+ Vector3 velocity = rb.velocity;
|
|
|
|
|
+ Quaternion targetQt = Quaternion.Euler(Vector3.zero);
|
|
|
|
|
+ switch (monkeyState)
|
|
|
|
|
+ {
|
|
|
|
|
+ case MonkeyState.None:
|
|
|
|
|
+ switch (state)
|
|
|
|
|
+ {
|
|
|
|
|
+ case CharacterState.Idle:
|
|
|
|
|
+ if (isAdjustHeight == 1)
|
|
|
|
|
+ {
|
|
|
|
|
+ ChangeState(CharacterState.Rise);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (isAttack)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (pastAttackTime >= attackController.attackInterval)
|
|
|
|
|
+ {
|
|
|
|
|
+ Attack_march();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ if (isOnTree && isArrived) return;
|
|
|
|
|
+ if (!foot.TrigGround && !canFly)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (rb.velocity.y > 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ ChangeState(CharacterState.Rise);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ ChangeState(CharacterState.Fall);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (leftDir.x > 0.3f || leftDir.x < -0.3f)
|
|
|
|
|
+ {
|
|
|
|
|
+ ChangeState(CharacterState.Run);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ velocity.y = 0;
|
|
|
|
|
+ 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);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (RotLerpTime < 1)
|
|
|
|
|
+ {
|
|
|
|
|
+ RotLerpTime += RotLerpSpeed * Time.deltaTime;
|
|
|
|
|
+ transform.rotation = Quaternion.Lerp(transform.rotation, targetQt, RotLerpTime);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ transform.rotation = targetQt;
|
|
|
|
|
+ }
|
|
|
|
|
+ rb.velocity = velocity;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ case CharacterState.Run:
|
|
|
|
|
+ if (isAttack)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (pastAttackTime >= attackController.attackInterval)
|
|
|
|
|
+ {
|
|
|
|
|
+ Attack_march();
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ ChangeState(CharacterState.Idle);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ if (!foot.TrigGround && !canFly)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (rb.velocity.y > 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ ChangeState(CharacterState.Rise);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ ChangeState(CharacterState.Fall);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (leftDir.x < 0.3f && leftDir.x > -0.3f)
|
|
|
|
|
+ {
|
|
|
|
|
+ ChangeState(CharacterState.Idle);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (leftDir.x > 0.3f)
|
|
|
|
|
+ {
|
|
|
|
|
+ velocity.x = moveSpeed;
|
|
|
|
|
+ if (bodyTrans.localScale.x > 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ Turn();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (leftDir.x < -0.3f)
|
|
|
|
|
+ {
|
|
|
|
|
+ velocity.x = -moveSpeed;
|
|
|
|
|
+ if (bodyTrans.localScale.x < 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ Turn();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ velocity.y = 0;
|
|
|
|
|
+ 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);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (RotLerpTime < 1)
|
|
|
|
|
+ {
|
|
|
|
|
+ RotLerpTime += RotLerpSpeed * Time.deltaTime;
|
|
|
|
|
+ transform.rotation = Quaternion.Lerp(transform.rotation, targetQt, RotLerpTime);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ transform.rotation = targetQt;
|
|
|
|
|
+ }
|
|
|
|
|
+ rb.velocity = velocity;
|
|
|
|
|
+ AdjustHeight();
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ case CharacterState.Rise:
|
|
|
|
|
+ if (isAdjustHeight == 1)
|
|
|
|
|
+ {
|
|
|
|
|
+ AdjustHeight();
|
|
|
|
|
+ if (!foot.haveGravity)
|
|
|
|
|
+ {
|
|
|
|
|
+ targetQt = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, platformRotZ);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (RotLerpTime < 1)
|
|
|
|
|
+ {
|
|
|
|
|
+ RotLerpTime += RotLerpSpeed * Time.deltaTime;
|
|
|
|
|
+ transform.rotation = Quaternion.Lerp(transform.rotation, targetQt, RotLerpTime);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ transform.rotation = targetQt;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (isAdjustHeight == 2)
|
|
|
|
|
+ {
|
|
|
|
|
+ ChangeState(CharacterState.Idle);
|
|
|
|
|
+ isAdjustHeight = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ if (rb.velocity.y <= 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ ChangeState(CharacterState.Fall);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ rb.velocity += Vector3.up * extraRiseGravity * Time.deltaTime;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ case CharacterState.Fall:
|
|
|
|
|
+ if (foot.TrigGround || canFly)
|
|
|
|
|
+ {
|
|
|
|
|
+ ChangeState(CharacterState.Idle);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ velocity.y += extraFallGravity * Time.deltaTime;
|
|
|
|
|
+ if (leftDir.x > 0.3f)
|
|
|
|
|
+ {
|
|
|
|
|
+ velocity.x = moveSpeed;
|
|
|
|
|
+ if (bodyTrans.localScale.x > 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ Turn();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (leftDir.x < -0.3f)
|
|
|
|
|
+ {
|
|
|
|
|
+ velocity.x = -moveSpeed;
|
|
|
|
|
+ if (bodyTrans.localScale.x < 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ Turn();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ rb.velocity = velocity;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case CharacterState.Attack:
|
|
|
|
|
+ attackController.JudgeTriggerOnOff();
|
|
|
|
|
+ if (attackController.attackTime <= 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ isAttack = GetAttack();
|
|
|
|
|
+ if (isAttack)
|
|
|
|
|
+ {
|
|
|
|
|
+ isConAttack = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (CheckEscape() && !isOnTree)
|
|
|
|
|
+ {
|
|
|
|
|
+ ChangeMonkeyState(MonkeyState.Escape);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ Debug.Log("切换待机");
|
|
|
|
|
+ ChangeState(CharacterState.Idle);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!foot.haveGravity)
|
|
|
|
|
+ {
|
|
|
|
|
+ targetQt = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, platformRotZ);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (RotLerpTime < 1)
|
|
|
|
|
+ {
|
|
|
|
|
+ RotLerpTime += RotLerpSpeed * Time.deltaTime;
|
|
|
|
|
+ transform.rotation = Quaternion.Lerp(transform.rotation, targetQt, RotLerpTime);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ transform.rotation = targetQt;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ case CharacterState.Die:
|
|
|
|
|
+ if (dieKeepTime <= 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (killer != null && killer.GetComponent<Demonic>())
|
|
|
|
|
+ {
|
|
|
|
|
+ SoldierType st = killer.GetComponent<Demonic>().soldierType;
|
|
|
|
|
+ SoldierEXP.expInstance.AddEXP(st, (int)(exp * LevelSelect.EXPRatio + 0.5f));
|
|
|
|
|
+ }
|
|
|
|
|
+ if (dieEffect)
|
|
|
|
|
+ {
|
|
|
|
|
+ PoolManager.Instantiate(dieEffect, transform.position);
|
|
|
|
|
+ }
|
|
|
|
|
+ gameObject.SetActive(false);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ case CharacterState.HitStun:
|
|
|
|
|
+ hitFeedbackSystem.HitStunUpdate();
|
|
|
|
|
+ break;
|
|
|
|
|
+ case CharacterState.SpecialStatus_Float:
|
|
|
|
|
+ attributeStatus.SpecialStateEffect(SpecialState.FloatState);
|
|
|
|
|
+ break;
|
|
|
|
|
+ case CharacterState.SpecialStatus_BlowUp:
|
|
|
|
|
+ attributeStatus.SpecialStateEffect(SpecialState.BlownUp);
|
|
|
|
|
+ break;
|
|
|
|
|
+ case CharacterState.SpecialStatus_ShotDown:
|
|
|
|
|
+ attributeStatus.SpecialStateEffect(SpecialState.ShotDown);
|
|
|
|
|
+ break;
|
|
|
|
|
+ case CharacterState.SpecialStatus_Weak:
|
|
|
|
|
+ attributeStatus.SpecialStateEffect(SpecialState.Weak);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ case MonkeyState.Escape:
|
|
|
|
|
+ if (!foot.TrigGround && !canFly)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (rb.velocity.y > 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ ChangeState(CharacterState.Rise);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ ChangeState(CharacterState.Fall);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ velocity.x = -escapeSpeed;
|
|
|
|
|
+ if (bodyTrans.localScale.x < 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ Turn();
|
|
|
|
|
+ }
|
|
|
|
|
+ velocity.y = 0;
|
|
|
|
|
+ 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);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (RotLerpTime < 1)
|
|
|
|
|
+ {
|
|
|
|
|
+ RotLerpTime += RotLerpSpeed * Time.deltaTime;
|
|
|
|
|
+ transform.rotation = Quaternion.Lerp(transform.rotation, targetQt, RotLerpTime);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ transform.rotation = targetQt;
|
|
|
|
|
+ }
|
|
|
|
|
+ rb.velocity = velocity;
|
|
|
|
|
+ AdjustHeight();
|
|
|
|
|
+ if (escapeTrigger.IsSafe(distanceToEnemy))
|
|
|
|
|
+ {
|
|
|
|
|
+ ChangeState(CharacterState.Run);
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (escapeTrigger.IsInEnemyTower(distanceToTower))
|
|
|
|
|
+ {
|
|
|
|
|
+ ChangeMonkeyState(MonkeyState.WaitForTank);
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ case MonkeyState.WaitForTank:
|
|
|
|
|
+ if (bodyTrans.localScale.x > 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ Turn();
|
|
|
|
|
+ }
|
|
|
|
|
+ if (escapeTrigger.IsSafe(distanceToEnemy))
|
|
|
|
|
+ {
|
|
|
|
|
+ ChangeState(CharacterState.Run);
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (isAttack)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (pastAttackTime >= attackController.attackInterval)
|
|
|
|
|
+ {
|
|
|
|
|
+ Attack_march();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ case MonkeyState.Climb:
|
|
|
|
|
+ if (!isReady)
|
|
|
|
|
+ {
|
|
|
|
|
+ float moveToStartSpeed = climbSpeed * Time.fixedDeltaTime;
|
|
|
|
|
+ Vector3 startPosition = pathCreator.path.GetPoint(0);
|
|
|
|
|
+ transform.position = Vector3.MoveTowards(transform.position, startPosition, moveToStartSpeed);
|
|
|
|
|
+ if (Vector2.Distance(transform.position, startPosition) < 0.3f)
|
|
|
|
|
+ {
|
|
|
|
|
+ dstTravelled = 0;
|
|
|
|
|
+ isReady = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (!isArrived)
|
|
|
|
|
+ {
|
|
|
|
|
+ float maxDistance = pathCreator.path.length * targetPoint;
|
|
|
|
|
+ float moveStep = climbSpeed * Time.fixedDeltaTime;
|
|
|
|
|
+ if (dstTravelled + moveStep > maxDistance)
|
|
|
|
|
+ {
|
|
|
|
|
+ moveStep = maxDistance - dstTravelled;
|
|
|
|
|
+ isArrived = true;
|
|
|
|
|
+ ChangeState(CharacterState.Idle);
|
|
|
|
|
+ }
|
|
|
|
|
+ dstTravelled += moveStep;
|
|
|
|
|
+ transform.position = pathCreator.path.GetPointAtDistance(dstTravelled, EndOfPathInstruction.Stop);
|
|
|
|
|
+ }
|
|
|
|
|
+ //else
|
|
|
|
|
+ //{
|
|
|
|
|
+ // rb.velocity = Vector3.zero;
|
|
|
|
|
+ // if (isAttack)
|
|
|
|
|
+ // {
|
|
|
|
|
+ // if (pastAttackTime >= attackController.attackInterval)
|
|
|
|
|
+ // {
|
|
|
|
|
+ // Attack_march();
|
|
|
|
|
+ // }
|
|
|
|
|
+ // }
|
|
|
|
|
+ //}
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private bool CheckEscape()
|
|
|
|
|
+ {
|
|
|
|
|
+ return !escapeTrigger.IsSafe(distanceToEnemy) && !escapeTrigger.IsInEnemyTower(distanceToTower);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ protected override void Start()
|
|
|
|
|
+ {
|
|
|
|
|
+ base.Start();
|
|
|
|
|
+ distanceToTower = distanceToTowerBase;
|
|
|
|
|
+ distanceToEnemy = distanceToEnemyBase;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public enum MonkeyState
|
|
|
|
|
+ {
|
|
|
|
|
+ None = 0,
|
|
|
|
|
+ Escape = 1, //正常状态
|
|
|
|
|
+ WaitForTank = 2, //寻找主角位置
|
|
|
|
|
+ Climb = 3, //向主角方向冲刺中
|
|
|
|
|
+ }
|
|
|
|
|
+}
|