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;

[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<GameObject> demonicPrefabs;
    public List<Vector3> demonicSummonPos;
    public Dictionary<int, List<Demonic>> demonicDic;
    public List<int> 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 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 summonTime;
    public float totalSummonTime = 0.5f;
    [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;
    [HideInInspector]
    public bool airJumped;
    public PlayerAttackState attackState;
    public float attackMoveSpeed = 5f;
    public Vector3 rushDir;

    private int currentSpirit;  //当前将要召唤的英灵种类
    private Spirits spirits;
    

    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 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 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<PlayerInput>();
        spirits = GetComponent<Spirits>();
        playerId = playerInput.playerIndex;
        if (playerId == 0)
        {
            transform.position = new Vector3(142, 0, 0);
            skeletonMecanim.skeletonDataAsset = playerSpine[0];
            PlayersInput.instance[0] = this;
        }
        else
        {
            transform.position = new Vector3(146, 0, 0);
            skeletonMecanim.skeletonDataAsset = playerSpine[1];
            PlayersInput.instance[1] = this;
        }
        
        if (!PlayersInput.instance[0])
        {
            PlayersInput.instance[0] = this;
        }
        //else
        //{
        //    DestroyImmediate(gameObject);
        //    return;
        //}
        demonicDic = new Dictionary<int, List<Demonic>>();
        demonicId = new List<int>() { 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;
        }
    }
    

    void OnSprintingPress()
    {
        LBisHold = true;
        isClickBtnRush = true;
        isKeepBtnRush = true;
    }
    void OnSprintingRelease()
    {
        LBisHold = false;
    }
    //手柄按下LB
    [HideInInspector]
    public bool LBisHold;
    //读取手柄参数
    private void OnMove(InputValue value)
    {
        leftDir = value.Get<Vector2>();
    }
    void OnJump()
    {
        isClickBtnJump = true;
    }
    void OnSummon0()
    {
        isClickBtnWest = true;
    }
    void OnSummon1()
    {
        isClickBtnSouth = true;
    }
    void OnSummon2()
    {
        isClickBtnEast = true;
    }
    void OnSummonSpirit()
    {
        isSpiritSummon = true;
    }
    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 CheckSummon()
    {
        if (cacheSummonTime > 0)
        {
            Summon(cacheSummonId);
            return true;
        }
        if (btnWestPress)
        {
            Summon(0);
            return true;
        }
        if (btnSouthPress)
        {
            Summon(1);
            return true;
        }
        if (btnEastPress)
        {
            Summon(2);
            return true;
        }
        if (isSpiritSummon)
        {
            Summon((int)spirits.currentSpirit + 3);
            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 = false;
            //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 ((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 (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 = (int)spirits.currentSpirit + 3;
        }
    }

    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 (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 && rb.velocity.y < airJumpSpeed)
                    {
                        airJumped = true;
                        AirJump();
                        break;
                    }
                }
                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 if (!airJumped)
                    {
                        airJumped = true;
                        AirJump();
                        break;
                    }
                }
                CachedPlayerInput();
                rb.velocity = AirMove(rb.velocity);
                break;
            case CharacterState.Hurt:
                if (hurtKeepTime <= 0 && rb.velocity.magnitude < hurtChangeVelocity)
                {
                    if (CheckPlayerChangeState())
                    {
                        break;
                    }
                }
                if (!foot.TrigGround)
                {
                    rb.velocity += Vector3.up * extraFallGravity * Time.deltaTime;
                }
                Vector3 vel = rb.velocity;
                vel.x = vel.x * (1 - decelerationRatio * Time.deltaTime);
                rb.velocity = vel;
                CachedPlayerInput();
                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)
        {
            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;

        if (foot.TrigGround)
        {
            canJumpTime = leaveGroundCanJumpTime;
        }
        SearchTarget();
        attackTarget = targetCharacter;

        if (mp < totalMp)
        {
            mp += mpReplySpeed * Time.deltaTime;
        }
        if (mp > totalMp)
        {
            mp = totalMp;
        }
        uiMp.Show(mp, totalMp);
    }

    public override void ChangeState(CharacterState newState)
    {
        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.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.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.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);
                summonTime = totalSummonTime;
                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;
                }
                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 Vector3 AirMove(Vector3 velocity)
    {
        CheckTurn();
        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;
    }

    public void Summon(int id)
    {
        if (id >= demonicPrefabs.Count)
        {
            Debug.LogError("未配置" + id + "号使魔");
            return;
        }
        if (id >= demonicSummonPos.Count)
        {
            Debug.LogError("未配置" + id + "号使魔召唤位置");
            return;
        }
        GameObject prefab = demonicPrefabs[id];
        if (!CheckCanSummon(id))
        {
            return;
        }
        ChangeState(CharacterState.Summon);
        float costMp = prefab.GetComponent<Demonic>().costMp;
        mp -= costMp;
        uiMp.Show(mp, totalMp);
        GameObject demonicObj = PoolManager.Instantiate(prefab);
        Demonic demonic = demonicObj.GetComponent<Demonic>();
        demonic.id = id;
        if (!demonicDic.ContainsKey(id))
        {
            demonicDic.Add(id, new List<Demonic>());
        }
        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();
            }
        }
        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<Demonic>().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);
    }
}
