using System.Collections; using System.Collections.Generic; using UnityEngine; using Spine; using Spine.Unity; using UnityEngine.LowLevel; using UnityEngine.Playables; using System.ComponentModel; using Unity.VisualScripting; using System; using Base.Common; using cfg; using static UnityEngine.EventSystems.EventTrigger; using UnityEngine.InputSystem; using TMPro; [Serializable] public struct AttackInfo { public int damage; public Vector3 attackDir; public float force; public bool changeHurt; public float repelValue; } public enum PlayerAttackState { Idle = 0, WalkForward = 1, WalkBack = 2, } public class PlayerController : MoveCharacter { //public static PlayerController instance; public List changePrefabs; private GameObject spiritObj; //当前变身的对象 private int endChange = 0; //public float changeTime; //变身时长 //private float pastChangeTime; public List demonicPrefabs; public List demonicSummonPos; public Dictionary> demonicDic; public List demonicId; public UIHP uiMp; public PlayerRope playerRope; public EventTrigger eventTrigger; public SprintLinkTrigger sprintLinkTrigger; public float jumpSpeed = 10; public float airJumpSpeed = 10; //public float moveAcc = 5f; //public float airMoveAcc = 3f; public float rushSpeed = 100; public float flySpeed = 5; public float mp; public float totalMp; public float mpReplySpeed = 1; public float rushCostMp = 5; public float sprintCostMp = 5; //尸体资源 public int corpses = 0; public float rushInvincibleTime = 0.2f; [HideInInspector] public float canJumpTime; //离开平台后仍然可以跳跃的时间,用于提升手感 public float leaveGroundCanJumpTime = 0.1f; [HideInInspector] public float cacheJumpTime; //即将落地时按下跳跃键不会跳跃,手感不好,缓存几帧,在这几帧内落地会立即跳跃; public float totalCacheJumpTime = 0.1f; [HideInInspector] public float tandemJumpTime; //即将落地时按下跳跃键不会跳跃,手感不好,缓存几帧,在这几帧内落地会立即跳跃; public float totalTandemJumpTime = 0.1f; [HideInInspector] public float summonTime; [HideInInspector] public float cacheAttackTime; //无法攻击时按下攻击键不会攻击,手感不好,缓存几帧,在这几帧内落地会立即攻击; public float totalCacheAttackTime = 0.1f; [HideInInspector] public float cachePullRopeTime; public float totalCachePullRopeTime = 0.1f; [HideInInspector] public float cacheSummonTime; //无法召唤时按下召唤键不会召唤,手感不好,缓存几帧,在这几帧内落地会立即召唤; public float totalCacheSummonTime = 0.1f; [HideInInspector] public int cacheSummonId; [HideInInspector] public float rushTime; public float totalRushTime = 0.5f; [HideInInspector] public float cacheRushTime; //无法Rush时按下Rush键不会Rush,手感不好,缓存几帧,在这几帧内落地会立即Rush; public float totalCacheRushTime = 0.1f; public int airJumped; public int jumpNumber = 2; //最大跳跃次数 public PlayerAttackState attackState; public float attackMoveSpeed = 5f; public Vector3 rushDir; private int currentSpirit; //当前将要召唤的英灵种类 private Spirits spirits; public float lostMp; public GameObject soul; private float addMp = 10; public Collider soulCollector; public bool isTransfiguration = false; //已变身 public Vector2 moveVec; //玩家不动时移动数据 public bool btnJumpPress { get { //return Input.GetKeyDown(KeyCode.Space) || isClickBtnJump; return isClickBtnJump; } } [HideInInspector] public bool isClickBtnJump; public bool btnRushPress { get { //return Input.GetKeyDown(KeyCode.LeftShift) || isClickBtnRush; return isClickBtnRush; } } [HideInInspector] public bool isClickBtnRush; public bool btnRushKeep { get { //return Input.GetKey(KeyCode.LeftShift) || isKeepBtnRush; return LBisHold || isKeepBtnRush; } } [HideInInspector] public bool isKeepBtnRush; public bool btnSouthPress { get { //return Input.GetKeyDown(KeyCode.K) || isClickBtnSouth; return isClickBtnSouth; } } [HideInInspector] public bool isClickBtnSouth; public bool btnEastPress { get { //return Input.GetKeyDown(KeyCode.L) || isClickBtnEast; return isClickBtnEast; } } [HideInInspector] public bool isClickBtnEast; public bool btnWestPress { get { //return Input.GetKeyDown(KeyCode.J) || isClickBtnWest; return isClickBtnWest; } } [HideInInspector] public bool isClickBtnWest; public bool btnNorthPress { get { //return Input.GetKeyDown(KeyCode.I) || isClickBtnNorth; return isClickBtnNorth; } } [HideInInspector] public bool isClickBtnNorth; public bool btnSpiritSummon { get { //return Input.GetKeyDown(KeyCode.I) || isClickBtnNorth; return isSpiritSummon; } } [HideInInspector] public bool isSpiritSummon; public bool btnSpiritSummon1 { get { //return Input.GetKeyDown(KeyCode.I) || isClickBtnNorth; return isSpiritSummon1; } } [HideInInspector] public bool isSpiritSummon1; public bool btnSpiritSummon2 { get { //return Input.GetKeyDown(KeyCode.I) || isClickBtnNorth; return isSpiritSummon2; } } [HideInInspector] public bool isSpiritSummon2; public bool btnSpiritSummon3 { get { //return Input.GetKeyDown(KeyCode.I) || isClickBtnNorth; return isSpiritSummon3; } } [HideInInspector] public bool isSpiritSummon3; public bool btnNorthKeep { get { //return Input.GetKey(KeyCode.I) || isKeepBtnNorth; return isKeepBtnNorth; } } [HideInInspector] public bool isKeepBtnNorth; [HideInInspector] public Vector2 leftDir; public int playerId; public SkeletonMecanim skeletonMecanim; public SkeletonDataAsset[] playerSpine; public bool canJump; public bool canfly; //public Vector2 leftDir //{ // get // { // int x = 0; // int y = 0; // if (Input.GetKey(KeyCode.A)) // { // x--; // } // if (Input.GetKey(KeyCode.D)) // { // x++; // } // if (Input.GetKey(KeyCode.S)) // { // y--; // } // if (Input.GetKey(KeyCode.W)) // { // y++; // } // return new Vector2(x, y); // } //} public override void Init() { base.Init(); mp = totalMp; uiMp.Show(mp, totalMp); } private void Awake() { PlayerInput playerInput = transform.GetComponent(); spirits = GetComponent(); playerId = playerInput.playerIndex; transform.position = new Vector3(142 + 4 * playerId, 0, 0); playerRope.playerId = playerId; sprintLinkTrigger.playerID = playerId; if (PlayersInput.instance[1] == PlayersInput.instance[0]) { PlayersInput.instance[1] = this; } PlayersInput.instance[playerId] = this; skeletonMecanim.skeletonDataAsset = playerSpine[playerId]; //else //{ // DestroyImmediate(gameObject); // return; //} demonicDic = new Dictionary>(); demonicId = new List() { 0, 0, 0, 0, 0, 0, 0 }; Init(); } private void Update() { //if (Input.GetKeyDown(KeyCode.LeftShift)) //{ // isClickBtnRush = true; //} //if (Input.GetKey(KeyCode.LeftShift)) //{ // isKeepBtnRush = true; //} //if (Input.GetKeyDown(KeyCode.Space)) //{ // isClickBtnJump = true; //} //if (Input.GetKeyDown(KeyCode.J)) //{ // isClickBtnWest = true; //} //if (Input.GetKeyDown(KeyCode.K)) //{ // isClickBtnSouth = true; //} //if (Input.GetKeyDown(KeyCode.L)) //{ // isClickBtnEast = true; //} //if (Input.GetKeyDown(KeyCode.I)) //{ // isClickBtnNorth = true; //} if (LBisHold) { isKeepBtnRush = true; } if (floatState != 0) { CharacterFloat(); } /* //到时间自动解除变身 if (endChange != 0) { pastChangeTime += Time.deltaTime; if (pastChangeTime >= changeTime) { EndTransfiguration(endChange); endChange = 0; pastChangeTime = 0; } } */ if (isTransfiguration) { bodyTrans.position = spiritObj.transform.position; } } void OnSprintingPress() { LBisHold = true; isClickBtnRush = true; isKeepBtnRush = true; } void OnSprintingRelease() { LBisHold = false; } //手柄按下LB [HideInInspector] public bool LBisHold; //读取手柄参数 private void OnMove(InputValue value) { if (canMove) { leftDir = value.Get(); } else { leftDir = Vector3.zero; moveVec = value.Get(); } } void OnJump() { if (canJump && canMove) { isClickBtnJump = true; } } void OnSummon0() { if (!isFloat && canMove) { isClickBtnWest = true; } } void OnSummon1() { if (!isFloat && canMove) { isClickBtnSouth = true; } } void OnSummon2() { if (!isFloat && canMove) { isClickBtnEast = true; } } public TextMeshProUGUI corpse; public int[] needCorpses; public void ShowCorpse() { corpse.text = "尸体:" + corpses.ToString(); } public bool isUltimate; //英灵释放大招 void OnSummonSpirit() //法师 { if (!isFloat && canMove) { if (!isTransfiguration && corpses >= needCorpses[0]) { isSpiritSummon = true; corpses -= needCorpses[0]; ShowCorpse(); } if(isTransfiguration && currentSpirit == 0) { //释放技能,此处暂时先写解除变身 //isUltimate = true; EndTransfiguration(endChange); } } } void OnSummonSpirit1() //刺客 { if (!isFloat && canMove) { if (!isTransfiguration && corpses >= needCorpses[1]) { isSpiritSummon1 = true; corpses -= needCorpses[1]; ShowCorpse(); } if(isTransfiguration && currentSpirit == 1) { //释放技能,此处暂时先写解除变身 isUltimate = true; //EndTransfiguration(endChange); } } } void OnSummonSpirit1Up() { if (isUltimate) { isUltimate = false; } } void OnSummonSpirit2() //厨师 { if (!isFloat && canMove) { if (!isTransfiguration && corpses >= needCorpses[2]) { isSpiritSummon2 = true; corpses -= needCorpses[2]; ShowCorpse(); } if(isTransfiguration && currentSpirit == 2) { //释放技能,此处暂时先写解除变身 isUltimate = true; //EndTransfiguration(endChange); } } } void OnSummonSpirit3() //隐身 { if (!isFloat && canMove) { if (!isTransfiguration && corpses >= needCorpses[3]) { isSpiritSummon3 = true; corpses -= needCorpses[3]; ShowCorpse(); } if(isTransfiguration && currentSpirit == 3) { //释放技能,此处暂时先写解除变身 isUltimate = true; //EndTransfiguration(endChange); } } } public void Jump() { SetUpSpeed(jumpSpeed); ani.Play("jump", 0, 0); } public void AirJump() { SetUpSpeed(airJumpSpeed); ani.Play("jump", 0, 0); } public void SetUpSpeed(float speed) { ChangeState(CharacterState.Rise); Vector3 velocity = rb.velocity; CheckTurn(); velocity.y = speed; rb.velocity = velocity; //animalAni.SetInteger("state", (int)PlayerState.Rise); } public bool canTranSummon = true; public bool CheckSummon() { if (cacheSummonTime > 0) { Summon(cacheSummonId); return true; } if (btnWestPress) { if (isTransfiguration && !canTranSummon) { return true; } Summon(0); return true; } if (btnSouthPress) { if (isTransfiguration && !canTranSummon) { return true; } Summon(1); return true; } if (btnEastPress) { if (isTransfiguration && !canTranSummon) { return true; } Summon(2); return true; } if (isSpiritSummon) { Transfiguration(3); return true; } if (isSpiritSummon1) { Transfiguration(4); return true; } if (isSpiritSummon2) { Transfiguration(5); return true; } if (isSpiritSummon3) { Transfiguration(6); return true; } return false; } //角色处于可自由活动状态时的通用切换状态逻辑,如Idle、Run状态,以及别的状态结束时准备回到Idle状态前 public bool CheckPlayerChangeState(CharacterState excludeState = CharacterState.None) { if (!foot.TrigGround) { if ((btnRushPress || cacheRushTime > 0) && mp >= rushCostMp) { if (excludeState != CharacterState.Rush) { ChangeState(CharacterState.Rush); return true; } } if (rb.velocity.y > 0) { if (excludeState != CharacterState.Rise) { ChangeState(CharacterState.Rise); return true; } } else { if (excludeState != CharacterState.Fall) { ChangeState(CharacterState.Fall); return true; } } } else { airJumped = 0; //if (btnNorthPress || cacheAttackTime > 0) //{ // if (excludeState != CharacterState.Attack) // { // Attack1(); // return true; // } //} if (eventTrigger.triggedRivet && (btnNorthPress || cachePullRopeTime > 0)) { if (sprintLinkTrigger.linkedEnemy.Count > 0) { eventTrigger.triggedRivet.BindingRopes(sprintLinkTrigger.linkedEnemy); } //ChangeState(CharacterState.PullRope); } if (excludeState != CharacterState.Summon) { if (CheckSummon()) { return true; } } if (excludeState != CharacterState.Transfiguration) { if (CheckSummon()) { return true; } } if ((btnRushPress || cacheRushTime > 0) && mp >= rushCostMp) { if (excludeState != CharacterState.Rush) { ChangeState(CharacterState.Rush); return true; } } if (btnJumpPress || cacheJumpTime > 0) { if (excludeState != CharacterState.Rise) { Jump(); ChangeState(CharacterState.Rise); return true; } } if (canfly) { if (leftDir.x > 0.3f || leftDir.x < -0.3f || leftDir.y > 0.3f || leftDir.y < -0.3f) { if (excludeState != CharacterState.Run) { ChangeState(CharacterState.Run); return true; } } else { if (excludeState != CharacterState.Idle) { ChangeState(CharacterState.Idle); return true; } } } else { if (leftDir.x > 0.3f || leftDir.x < -0.3f) { if (excludeState != CharacterState.Run) { ChangeState(CharacterState.Run); return true; } } else { if (excludeState != CharacterState.Idle) { ChangeState(CharacterState.Idle); return true; } } } } return false; } public override Vector3 GetMoveDir() { return leftDir; } public void CachedPlayerInput() { if (btnRushPress) { cacheRushTime = totalCacheRushTime; } if (btnJumpPress) { cacheJumpTime = totalCacheJumpTime; } if (btnNorthPress) { cacheAttackTime = totalCacheAttackTime; } if (btnWestPress) { cacheSummonTime = totalCacheSummonTime; cacheSummonId = 0; } if (btnSouthPress) { cacheSummonTime = totalCacheSummonTime; cacheSummonId = 1; } if (btnEastPress) { cacheSummonTime = totalCacheSummonTime; cacheSummonId = 2; } if (btnSpiritSummon) { cacheSummonTime = totalCacheSummonTime; cacheSummonId = 3; } if (btnSpiritSummon1) { cacheSummonTime = totalCacheSummonTime; cacheSummonId = 4; } if (btnSpiritSummon2) { cacheSummonTime = totalCacheSummonTime; cacheSummonId = 5; } if (btnSpiritSummon3) { cacheSummonTime = totalCacheSummonTime; cacheSummonId = 6; } } public override void OnState() { base.OnState(); hurtKeepTime -= Time.deltaTime; cacheJumpTime -= Time.deltaTime; cacheAttackTime -= Time.deltaTime; cacheSummonTime -= Time.deltaTime; canJumpTime -= Time.deltaTime; invincibleTime -= Time.deltaTime; attackTime -= Time.deltaTime; summonTime -= Time.deltaTime; rushTime -= Time.deltaTime; cacheRushTime -= Time.deltaTime; dieKeepTime -= Time.deltaTime; weakTime -= Time.deltaTime; Vector3 velocity = rb.velocity; switch (state) { case CharacterState.Idle: if (CheckPlayerChangeState(CharacterState.Idle)) { break; } break; case CharacterState.Run: if (CheckPlayerChangeState(CharacterState.Run)) { break; } CheckTurn(); if (canfly) { rb.velocity = leftDir.normalized * moveSpeed; } else { if (leftDir.x > 0.3f) { rb.velocity = Vector3.right * moveSpeed; } else if (leftDir.x < -0.3f) { rb.velocity = Vector3.left * moveSpeed; } } break; case CharacterState.Rise: if (CheckSummon()) { break; } if ((btnRushPress || cacheRushTime > 0) && mp >= rushCostMp) { ChangeState(CharacterState.Rush); break; } if (rb.velocity.y <= 0) { ChangeState(CharacterState.Fall); break; } if (btnJumpPress || cacheJumpTime > 0) { if (airJumped == 0 && jumpNumber >= 2 && rb.velocity.y < airJumpSpeed) { airJumped = 1; AirJump(); break; } if (airJumped == 1 && jumpNumber >= 3 && rb.velocity.y < airJumpSpeed) { airJumped = 2; AirJump(); break; } isClickBtnJump = false; } CachedPlayerInput(); rb.velocity = AirMove(rb.velocity); break; case CharacterState.Fall: if (CheckSummon()) { break; } if ((btnRushPress || cacheRushTime > 0) && mp >= rushCostMp) { ChangeState(CharacterState.Rush); break; } if (foot.TrigGround) { if (CheckPlayerChangeState()) { break; } } //if (foot.canStepPlayers.Count > 0) //{ // Jump(jumpSpeed / 2); // StepOther(); // break; //} //if (foot.canStepEnemyList.Count > 0) //{ // Jump(jumpSpeed / 2); // StepEnemy(); // break; //} if (btnJumpPress || cacheJumpTime > 0) { if (canJumpTime > 0) { Jump(); break; } else { switch (airJumped) { case 0: if(jumpNumber >= 2) { airJumped = 1; AirJump(); } break; case 1: if(jumpNumber >= 3) { airJumped = 2; AirJump(); } break; } } isClickBtnJump = false; } CachedPlayerInput(); rb.velocity = AirMove(rb.velocity); break; case CharacterState.Hurt: if (hurtKeepTime <= 0 && rb.velocity.magnitude < hurtChangeVelocity) { if (CheckPlayerChangeState()) { break; } } Vector3 vel = rb.velocity; if (!foot.TrigGround) { if (canfly) { vel.y = vel.y * (1 - decelerationRatio * Time.deltaTime); } else { vel += Vector3.up * extraFallGravity * Time.deltaTime; } } vel.x = vel.x * (1 - decelerationRatio * Time.deltaTime); rb.velocity = vel; CachedPlayerInput(); break; case CharacterState.Coma: break; case CharacterState.Attack: if (attackTime <= 0) { if (btnNorthKeep) { ChangeState(CharacterState.KeepAttack); break; } if (CheckPlayerChangeState()) { break; } } CachedPlayerInput(); break; case CharacterState.KeepAttack: if ((btnRushPress) && mp >= rushCostMp) { ChangeState(CharacterState.Rush); break; } if (btnJumpPress && canJumpTime > 0) { Jump(); break; } if (!btnNorthKeep) { if (CheckPlayerChangeState(CharacterState.Attack)) { break; } } switch (attackState) { case PlayerAttackState.Idle: if (bodyTrans.localScale.x > 0) { if (leftDir.x > 0.3f) { SetAttackState(PlayerAttackState.WalkBack); velocity.x = attackMoveSpeed; rb.velocity = velocity; break; } else if (leftDir.x < -0.3f) { SetAttackState(PlayerAttackState.WalkForward); velocity.x = -attackMoveSpeed; rb.velocity = velocity; break; } } else { if (leftDir.x > 0.3f) { SetAttackState(PlayerAttackState.WalkForward); velocity.x = attackMoveSpeed; rb.velocity = velocity; break; } else if (leftDir.x < -0.3f) { SetAttackState(PlayerAttackState.WalkBack); velocity.x = -attackMoveSpeed; rb.velocity = velocity; break; } } velocity.x = 0; rb.velocity = velocity; break; case PlayerAttackState.WalkForward: if (bodyTrans.localScale.x > 0) { if (leftDir.x > 0.3f) { SetAttackState(PlayerAttackState.WalkBack); velocity.x = attackMoveSpeed; rb.velocity = velocity; break; } else if (leftDir.x > -0.3f && leftDir.x < 0.3f) { SetAttackState(PlayerAttackState.Idle); velocity.x = 0; rb.velocity = velocity; break; } else { velocity.x = -attackMoveSpeed; rb.velocity = velocity; } } else { if (leftDir.x < -0.3f) { SetAttackState(PlayerAttackState.WalkBack); velocity.x = -attackMoveSpeed; rb.velocity = velocity; break; } else if (leftDir.x > -0.3f && leftDir.x < 0.3f) { SetAttackState(PlayerAttackState.Idle); velocity.x = 0; rb.velocity = velocity; break; } else { velocity.x = attackMoveSpeed; rb.velocity = velocity; } } break; case PlayerAttackState.WalkBack: if (bodyTrans.localScale.x > 0) { if (leftDir.x < -0.3f) { SetAttackState(PlayerAttackState.WalkForward); velocity.x = -attackMoveSpeed; rb.velocity = velocity; break; } else if (leftDir.x > -0.3f && leftDir.x < 0.3f) { SetAttackState(PlayerAttackState.Idle); velocity.x = 0; rb.velocity = velocity; break; } else { velocity.x = attackMoveSpeed; rb.velocity = velocity; } } else { if (leftDir.x > 0.3f) { SetAttackState(PlayerAttackState.WalkForward); velocity.x = attackMoveSpeed; rb.velocity = velocity; break; } else if (leftDir.x > -0.3f && leftDir.x > 0.3f) { SetAttackState(PlayerAttackState.Idle); velocity.x = 0; rb.velocity = velocity; break; } else { velocity.x = -attackMoveSpeed; rb.velocity = velocity; } } break; default: break; } break; case CharacterState.Summon: if (summonTime <= 0) { if (CheckPlayerChangeState()) { break; } } break; case CharacterState.Rush: if (rushTime <= 0) { if (btnRushKeep) { ChangeState(CharacterState.Sprint); break; } if (CheckPlayerChangeState()) { break; } } CachedPlayerInput(); //if (leftDir.magnitude < 0.3f) //{ // if (bodyTrans.localScale.x > 0) // { // rushDir = Vector3.left; // } // else // { // rushDir = Vector3.right; // } //} //else //{ // rushDir = leftDir.normalized; //} rb.velocity = rushDir * rushSpeed; break; case CharacterState.Sprint: if (!btnRushKeep) { if (CheckPlayerChangeState(CharacterState.Rush)) { break; } } if (mp < sprintCostMp * Time.deltaTime) { if (CheckPlayerChangeState(CharacterState.Rush)) { break; } } mp -= sprintCostMp * Time.deltaTime; uiMp.Show(mp, totalMp); CachedPlayerInput(); //CheckTurn(); //if (leftDir.magnitude < 0.3f) //{ // if (bodyTrans.localScale.x > 0) // { // rushDir = Vector3.left; // } // else // { // rushDir = Vector3.right; // } //} //else //{ // rushDir = leftDir.normalized; //} rb.velocity = rushDir * rushSpeed; break; case CharacterState.Die: if (dieKeepTime <= 0) { gameObject.SetActive(false); break; } break; case CharacterState.Weak: if (weakTime <= 0) { ChangeState(CharacterState.Idle); break; } break; case CharacterState.PullRope: break; default: break; } if (!foot.TrigGround && !canfly) { if (rb.velocity.y > 0) { rb.velocity += Vector3.up * extraRiseGravity * Time.deltaTime; } else { rb.velocity += Vector3.up * extraFallGravity * Time.deltaTime; } } isClickBtnRush = false; isKeepBtnRush = false; isClickBtnJump = false; isClickBtnSouth = false; isClickBtnEast = false; isClickBtnNorth = false; isClickBtnWest = false; isSpiritSummon = false; isSpiritSummon1 = false; isSpiritSummon2 = false; isSpiritSummon3 = false; if (foot.TrigGround) { canJumpTime = leaveGroundCanJumpTime; } SearchTarget(); attackTarget = targetCharacter; if (isMpRepel && floatState == 0) { if (mp < totalMp) { mp += mpReplySpeed * Time.deltaTime; } } if (floatState != 0) { if (mp > 0) { lostMp += mpReplySpeed * Time.deltaTime; mp -= mpReplySpeed * Time.deltaTime; } if (lostMp >= addMp) { Instantiate(soul, transform.position, new Quaternion(0, 0, 0, 0), null); lostMp = 0; } } if (mp > totalMp) { mp = totalMp; } if (mp < 0) { mp = 0; } uiMp.Show(mp, totalMp); } public bool isMpRepel = true; public override void ChangeState(CharacterState newState) { if (state == newState) { return; } Vector3 velocity = rb.velocity; switch (state) { case CharacterState.Idle: break; case CharacterState.Run: velocity.x = 0; break; case CharacterState.Rise: break; case CharacterState.Fall: break; case CharacterState.Hurt: break; case CharacterState.Coma: canMove = true; foreach (GameObject i in HitCols) { i.SetActive(true); } break; case CharacterState.Attack: aniCollider.Play("NotAttack", 1, 0); break; case CharacterState.KeepAttack: aniCollider.Play("NotAttack", 1, 0); break; case CharacterState.Summon: rb.isKinematic = false; break; case CharacterState.Transfiguration: rb.isKinematic = false; break; case CharacterState.Rush: velocity = Vector3.zero; break; case CharacterState.Sprint: velocity = Vector3.zero; break; case CharacterState.Die: isDie = false; break; case CharacterState.Weak: break; default: break; } CharacterState oldState = state; state = newState; switch (newState) { case CharacterState.Idle: aniCollider.Play("Idle", 0, 0); if (oldState == CharacterState.Fall) { ani.Play("fall_end", 0, 0); } else { ani.Play("idle", 0, 0); } velocity = Vector3.zero; //animalAni.SetInteger("state", (int)PlayerState.Idle); break; case CharacterState.Run: aniCollider.Play("Run", 0, 0); ani.Play("run_start", 0, 0); //animalAni.SetInteger("state", (int)PlayerState.Walk); break; case CharacterState.Rise: aniCollider.Play("Rise", 0, 0); canJumpTime = 0; break; case CharacterState.Fall: aniCollider.Play("Fall", 0, 0); ani.Play("fall", 0, 0); //animalAni.SetInteger("state", (int)PlayerState.Fall); break; case CharacterState.Hurt: aniCollider.Play("Hurt", 0, 0); ani.Play("hitted", 0, 0); invincibleTime = totalInvincibleTime; hurtKeepTime = minHurtKeepTime; //ani.Play("Invincible", 2, 0); break; case CharacterState.Coma: //ani.Play("Coma", 0, 0); ani.Play("idle", 0, 0); aniCollider.Play("Idle", 0, 0); rb.velocity = Vector3.zero; foreach (GameObject i in HitCols) { i.SetActive(false); } break; case CharacterState.Attack: attackTime = totalAttack1Time; break; case CharacterState.KeepAttack: aniCollider.Play("Attack1Keep", 1, 0); break; case CharacterState.Summon: aniCollider.Play("Summon", 0, 0); ani.Play("summon", 0, 0); velocity = Vector3.zero; rb.isKinematic = true; break; case CharacterState.Transfiguration: isTransfiguration = true; aniCollider.Play("Transfiguration", 0, 0); ani.Play("transfiguration", 0, 0); velocity = Vector3.zero; rb.isKinematic = true; break; case CharacterState.Rush: aniCollider.Play("Rush", 0, 0); ani.Play("rush_loop", 0, 0); rushTime = totalRushTime; invincibleTime = rushInvincibleTime; //if (leftDir.magnitude < 0.3f) //{ // if (bodyTrans.localScale.x > 0) // { // rushDir = Vector3.left; // } // else // { // rushDir = Vector3.right; // } //} //else //{ // rushDir = leftDir.normalized; //} if (bodyTrans.localScale.x > 0) { rushDir = Vector3.left; } else { rushDir = Vector3.right; } velocity = rushDir * rushSpeed; mp -= rushCostMp; uiMp.Show(mp, totalMp); break; case CharacterState.Sprint: aniCollider.Play("Sprint", 0, 0); ani.Play("rush_loop", 0, 0); velocity = rushDir * rushSpeed; break; case CharacterState.Die: aniCollider.Play("Die", 0, 0); ani.Play("die", 0, 0); isDie = true; dieKeepTime = totalDieKeepTime; break; case CharacterState.Weak: aniCollider.Play("Weak", 0, 0); ani.Play("weak", 0, 0); velocity.y = weakUpSpeed; weakTime = totalWeakTime; break; default: break; } rb.velocity = velocity; } public void CheckTurn() { if (leftDir.x > 0.3f && bodyTrans.localScale.x > 0) { Turn(); } else if (leftDir.x < -0.3f && bodyTrans.localScale.x < 0) { Turn(); } } public float maxFlyHeight; public Vector3 AirMove(Vector3 velocity) { CheckTurn(); if (canfly) { velocity = leftDir.normalized * flySpeed; if (transform.position.y > maxFlyHeight && velocity.y > 0) { velocity.y = 0; } } else { if (leftDir.x > 0.3f) { velocity = new Vector3(moveSpeed, velocity.y, velocity.z); } else if (leftDir.x < -0.3f) { velocity = new Vector3(-moveSpeed, velocity.y, velocity.z); } else { velocity = new Vector3(0, velocity.y, velocity.z); } } return velocity; } private Collider playerSoulCollector; public void Transfiguration(int id) //变身 { playerSoulCollector = soulCollector; id = id - 3; currentSpirit = id; if (id >= changePrefabs.Count) { Debug.LogError("未配置" + id + "号变身"); return; } if (id == 3 && isInvisible) { isInvisible = false; return; } GameObject prefab = changePrefabs[id]; ChangeState(CharacterState.Transfiguration); summonTime = prefab.GetComponent().totalSummonTime; bodyTrans.gameObject.SetActive(false); foot.trigGroundList.Clear(); spiritObj = PoolManager.Instantiate(prefab); Demonic dem = spiritObj.GetComponent(); dem.id = id; dem.playerID = playerId; spiritObj.transform.parent = transform; spiritObj.transform.localEulerAngles = Vector3.zero; spiritObj.transform.localScale = new Vector3(1, 1, 1); if (bodyTrans.localScale.x > 0) { spiritObj.transform.position = transform.position; if (dem.bodyTrans.localScale.x < 0) { dem.Turn(); } } else { spiritObj.transform.position = transform.position; if (dem.bodyTrans.localScale.x > 0) { dem.Turn(); } } mecanim = dem.mecanim; ani = dem.ani; aniCollider = dem.aniCollider; bodyTrans = dem.bodyTrans; beSearchTrigger = dem.beSearchTrigger; bulletPrefab = dem.bulletPrefab; searchTrigger = dem.searchTrigger; foot = dem.foot; spinee = dem.spinee; mesh = dem.mesh; mats = dem.mats; soulCollector = dem.soulCollector; outlineMats = dem.outlineMats; if (dem.canFly) { canfly = true; canJump = false; rb.useGravity = false; } /* 法师出场释放浮空场 if (id == 3) { if ((int)spirits.currentSpirit == 0) { if (!spiritObj.GetComponent().hasEffect) { spiritObj.GetComponent().hasEffect = true; Instantiate(spirits.floatEffect, spiritObj.transform.position, new Quaternion(0, 0, 0, 0), spiritObj.transform); } } } */ endChange = id + 3; dem.hp = hp; ChangeState(CharacterState.Idle); } public bool endTranSummon; //是否在结束变身后召唤英灵 public void EndTransfiguration(int id) { isTransfiguration = false; canfly = false; canJump = true; canMove = true; rb.useGravity = true; mecanim = playerMe; ani = playerAni; aniCollider = playerCol; bodyTrans = playerTran; beSearchTrigger = playerBst; bulletPrefab = playerBullet; searchTrigger = playerST; foot = playerFoot; spinee = playerSpinee; mesh = playerMesh; mats = playerMats; soulCollector = playerSoulCollector; outlineMats = playerOut; bodyTrans.gameObject.SetActive(true); uiHp.gameObject.SetActive(true); spiritObj.transform.parent = null; spiritObj.SetActive(false); if (endTranSummon) { Summon(endChange); } CheckPlayerChangeState(); endChange = 0; } public bool canArrowHitFloat; //可以让弓箭手攻击概率漂浮 public float probability; //攻击的漂浮概率 public float gainAbilityProbability; //弓箭手获得漂浮能力的概率 public int abilityTimes; //弓箭手释放漂浮能力的次数 private bool isFirst = true; public void Summon(int id) { if (id >= demonicPrefabs.Count) { Debug.LogError("未配置" + id + "号使魔"); return; } if (id >= demonicSummonPos.Count) { Debug.LogError("未配置" + id + "号使魔召唤位置"); return; } if (id == 6 && isInvisible) { isInvisible = false; return; } GameObject prefab = demonicPrefabs[id]; if (!CheckCanSummon(id)) { return; } ChangeState(CharacterState.Summon); summonTime = prefab.GetComponent().totalSummonTime; float costMp = prefab.GetComponent().costMp; mp -= costMp; uiMp.Show(mp, totalMp); GameObject demonicObj = PoolManager.Instantiate(prefab); Demonic demonic = demonicObj.GetComponent(); if (canArrowHitFloat && id == 0) { float k = UnityEngine.Random.Range(0, 100); if (isFirst || k <= gainAbilityProbability) { isFirst = false; demonic.attackToFloat = true; demonic.floatProbability = probability; demonic.floatTimes = abilityTimes; } } if (id == 2) { demonic.criticalChance = criticalChance; demonic.criticalMultiplier = criticalMultiplier; } demonic.id = id; demonic.playerID = playerId; if (!demonicDic.ContainsKey(id)) { demonicDic.Add(id, new List()); } demonicDic[id].Add(demonic); demonicObj.transform.parent = null; demonicObj.transform.localEulerAngles = Vector3.zero; demonicObj.transform.localScale = new Vector3(1, 1, 1); Vector3 offset = demonicSummonPos[id]; if (bodyTrans.localScale.x > 0) { demonicObj.transform.position = transform.position + offset; if (demonic.bodyTrans.localScale.x < 0) { demonic.Turn(); } } else { demonicObj.transform.position = transform.position + new Vector3(-offset.x, offset.y, offset.z); if (demonic.bodyTrans.localScale.x > 0) { demonic.Turn(); } } if (demonic.canFly) { demonic.flyHeight = demonic.transform.position.y; } if (id == 3) { if ((int)spirits.currentSpirit == 0) { if (!demonicObj.GetComponent().hasEffect) { demonicObj.GetComponent().hasEffect = true; Instantiate(spirits.floatEffect, demonicObj.transform.position, new Quaternion(0, 0, 0, 0), demonicObj.transform); } } } demonic.player = this; demonic.Init(); demonic.SetSortingOrder(demonic.sortingOrder + demonicId[id]); demonicId[id]++; demonic.Attack1(); } public void OnDemonicRecycle(Demonic demonic) { if (!demonicDic.ContainsKey(demonic.id)) { return; } demonicDic[demonic.id].Remove(demonic); for (int i = 0; i < demonicDic[demonic.id].Count; i++) { demonicDic[demonic.id][i].SetSortingOrder(demonic.id * 1000 + i); } } public bool CheckCanSummon(int id) { GameObject prefab = demonicPrefabs[id]; float costMp = prefab.GetComponent().costMp; if (mp < costMp) { Debug.Log("mp不足召唤失败, 还得加个动画或者音效啥的"); return false; } return true; } public override void Attack1() { base.Attack1(); if (leftDir.x > 0.3f) { if (bodyTrans.localScale.x > 0) { Turn(); } SetAttackState(PlayerAttackState.WalkForward); } else if (leftDir.x < -0.3f) { if (bodyTrans.localScale.x < 0) { Turn(); } SetAttackState(PlayerAttackState.WalkForward); } else { SetAttackState(PlayerAttackState.Idle); } } public void SetAttackState(PlayerAttackState value) { attackState = value; ani.SetInteger("attackState", (int)value); aniCollider.Play("Attack1Keep", 1, 0); } public void SearchTarget() { targetCharacter = searchTrigger.GetMinDisTarget(targetTypes, canHitFly); } }