using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Sirenix.OdinInspector;

/// <summary>
/// 马类，用于接受来自玩家的指令、进行物理模拟
/// </summary>
public class Horse : MonoBehaviour
{
    //  _____       _     _ _      
    // |  __ \     | |   | (_)     
    // | |__) |   _| |__ | |_  ___ 
    // |  ___/ | | | '_ \| | |/ __|
    // | |   | |_| | |_) | | | (__ 
    // |_|    \__,_|_.__/|_|_|\___|

    /// <summary>
    /// 马的前腿根部
    /// </summary>
    [BoxGroup("必须绑定的物体")][Header("马的前腿根部")]
    public Transform frontLegRoot;

    /// <summary>
    /// 马的后腿根部
    /// </summary>
    [BoxGroup("必须绑定的物体")][Header("马的后腿根部")]
    public Transform backLegRoot;

    /// <summary>
    /// 马伸直腿后前脚底部
    /// </summary>
    [BoxGroup("必须绑定的物体")][Header("马前脚伸直后的最深位置")]
    public Transform frontFoot;

    /// <summary>
    /// 马伸直腿后后脚底部
    /// </summary>
    [BoxGroup("必须绑定的物体")][Header("马后脚伸直后的最深位置")]
    public Transform backFoot;

    /// <summary>
    /// 马脚Transform
    /// </summary>
    [BoxGroup("必须绑定的物体")][Header("马脚Transform，必须按照左前、右前、左后、右后的顺序绑定")]
    public Transform[] footsTransform;

    /// <summary>
    /// 头部IK控制点
    /// </summary>
    [BoxGroup("必须绑定的物体")][Header("头部IK控制点")]
    public Transform HeadControlPoint;
    
    /// <summary>
    /// 腿做圆周运动的半径
    /// </summary>
    [BoxGroup("马的基本运动信息")][Header("马脚圆周运动半径")]
    public float footMoveRadius;

    /// <summary>
    /// 四条腿分别对输入偏差多少
    /// </summary>
    [ListDrawerSettings] [BoxGroup("马的基本运动信息")][Header("四条腿分别对输入偏差多少")]
    public Vector2[] footOffestOfInput;

    /// <summary>
    /// 马足力量
    /// </summary>
    [BoxGroup("马的基本运动信息")][Header("马足力量")]
    public float footForce;

    /// <summary>
    /// 马蹄推动马身的力度调整值
    /// </summary>
    [BoxGroup("马的基本运动信息")][Header("马前进的力度")]
    public float strength;

    /// <summary>
    /// 马蹄供力有效范围
    /// </summary>
    [BoxGroup("马的基本运动信息")][Header("马蹄供力有效范围")]
    public float effectiveDistance;

    public enum FootType { Front, Back }

    /// <summary>
    /// 马状态，Stand代表无输入，Move为有输入着地行走，Jump为跳跃，当两对足均并拢时进入
    /// </summary>
    public enum HorseState { Stand, Move, Jump, Dead}

    /// <summary>
    /// 单次跳跃过程中的状态量,Ready表示还没开始累计最终力，Charge表示已经开始蓄力，jump表示已经触发跳跃
    /// </summary>
    public enum JumpState { Ready, Charging, Jump }

    /// <summary>
    /// 跳跃判定阈值，只有输入的变化大于该值才会触发跳跃的蓄力
    /// </summary>
    [BoxGroup("马的基本运动信息")][Header("马跳跃蓄力阈值")] 
    public float jumpChargeThreshold;

    /// <summary>
    /// 马跳跃力度
    /// </summary>
    [BoxGroup("马的基本运动信息")][Header("马跳跃力度")]
    public float jumpForce;

    [BoxGroup("马的其他信息")][Header("马被相机挤死后飞出有多大的力")]
    public float deadFlySpeed;

    /// <summary>
    /// 要统计多长时间内的输入变化以供加速？】
    /// </summary>
    [BoxGroup("马的基本运动信息")][Header("要统计多长时间内的输入变化以供加速？")]
    public float accelerationTime;

    /// <summary>
    /// 加速倍率
    /// </summary>
    [BoxGroup("马的基本运动信息")][Header("加速倍率")]
    public float accelerationRate = 1f;

    /// <summary>
    /// 最后一节马足的骨骼，必须按照左前、右前、左后、右后的顺序绑定
    /// </summary>
    [ BoxGroup("必须绑定的物体")][Header("最后一节马足的骨骼，必须按照左前、右前、左后、右后的顺序绑定")]
    public Transform[] lastFoots;

    [BoxGroup("马的基本运动信息")][Header("最后一节马前脚的旋转区间")]
    public Vector2 lastFrontFootRotationRange;
    [BoxGroup("马的基本运动信息")][Header("最后一节马后脚的旋转区间")]
    public Vector2 lastBackFootRotationRange;
    [BoxGroup("马的基本运动信息")][Header("马头追踪速度")]
    public float headSpeed;
    [BoxGroup("马的基本运动信息")][Header("马尾追踪速度")]
    public float tailSpeed;
    [BoxGroup("马的基本运动信息")][Header("马尾旋转范围")]
    public Vector2 horseTailRotationRange;
    /// <summary>
    /// 马尾骨骼
    /// </summary>
    [BoxGroup("必须绑定的物体")][Header("马尾IK控制点")]
    public Transform tailControlPoint;

    
    


    //   _____      _            _       
    //  |  __ \    (_)          | |      
    //  | |__) | __ ___   ____ _| |_ ___ 
    //  |  ___/ '__| \ \ / / _` | __/ _ \
    //  | |   | |  | |\ V / (_| | ||  __/
    //  |_|   |_|  |_| \_/ \__,_|\__\___|  

    struct foot
    {
        /// <summary>
        /// 腿对输入偏差多少
        /// </summary>
        public Vector2 footOffestOfInput;

        /// <summary>
        /// 马脚控制点，通过transform找到
        /// </summary>
        public Transform footControlPoint;

        /// <summary>
        /// 真实的马脚的Transform
        /// </summary>
        public Transform footRealTransform;
        
        /// <summary>
        /// 马脚此时目标位置，每帧计算
        /// </summary>
        public Vector3 footTargetPosition;

        /// <summary>
        /// 马蹄刚体组件
        /// </summary>
        public Rigidbody2D footRigidbody2D;

        /// <summary>
        /// 马蹄的碰撞体，但是不绑在马蹄上，而是为了物理计算绑在马身上
        /// </summary>
        public BoxCollider2D footBoxCollider2D;

        /// <summary>
        /// 马蹄前一帧的位置
        /// </summary>
        public Vector3 footPreviousPosition;

        /// <summary>
        /// 最后一节马足的骨骼Transform，需要模拟其弯曲
        /// </summary>
        public Transform lastFootTransform;
    }

    private foot[] foots;

    /// <summary>
    /// 马前腿长度
    /// </summary>
    private float frontLegLength;

    /// <summary>
    /// 马后腿长度
    /// </summary>
    private float backLegLength;

    /// <summary>
    /// 从前腿根骨骼到马脚运动圆心的距离，用来推算最终马脚位置
    /// </summary>
    private float frontRootDistanceToCenterOfCircle;

    /// <summary>
    /// 从后腿根骨骼到马脚运动圆心的距离，用来推算最终马脚位置
    /// </summary>
    private float backRootDistanceToCenterOfCircle;

    /// <summary>
    /// 输入的马前脚信息
    /// </summary>
    private Vector2 inputFrontVector;

    /// <summary>
    /// 上一帧马前脚信息
    /// </summary>
    private Vector2 pInputFrontVector;

    /// <summary>
    /// 输入的马后脚信息
    /// </summary>
    private Vector2 inputBackVector;

    /// <summary>
    /// 上一帧马后脚信息
    /// </summary>
    private Vector2 pInputBackVector;

    /// <summary>
    /// 前一帧的前马脚输入向量
    /// </summary>
    private Vector2 previousInputFrontVector;

    /// <summary>
    /// 前一帧的后马脚输入向量
    /// </summary>
    private Vector2 previousInputBackVector;

    /// <summary>
    /// 一段时间内的变化总量
    /// </summary>
    private float chargeCount = 0;


    /// <summary>
    /// 原重力尺度，在Start中通过随意一条腿的刚体获取
    /// </summary>
    private float oriGravityScale;

    /// <summary>
    /// 马蹄碰撞体数组
    /// </summary>
    private BoxCollider2D[] footBoxColliders;

    /// <summary>
    /// 马的刚体组件
    /// </summary>
    private Rigidbody2D horseRig;

    /// <summary>
    /// 四条腿分别对输入偏差多少,但是是原始值，不会改变，用于还原并拢的脚
    /// </summary>
    private Vector2[] oriFootOffestOfInput;

    /// <summary>
    /// 马此时的状态
    /// </summary>
    private HorseState horseState;

    /// <summary>
    /// 此时前腿并拢着吗？
    /// </summary>
    private bool isFrontFootMerged = false;

    /// <summary>
    /// 此时后腿并拢着吗？
    /// </summary>
    private bool isBackFootMerged = false;

    /// <summary>
    /// 此时的跳跃状态
    /// </summary>
    private JumpState jumpState = JumpState.Ready;

    /// <summary>
    /// 跳跃蓄力的速度
    /// </summary>
    private Vector2 jumpChargeVelocity;

    /// <summary>
    /// 死亡后的旋转中心
    /// </summary>
    private Transform rotateCenter;

    /// <summary>
    /// 保存了最近若干秒内的输入充能
    /// </summary>
    private Queue <float> footInputChargeQueue;
    /// <summary>
    /// 应有的输入加速累计队列的长度
    /// </summary>
    private int footInputChargeQueueLength;

    /// <summary>
    /// 本帧中，累计的充能值
    /// </summary>
    public float footInputCharge = 0;

    /// <summary>
    /// 马头控制点的Pos应同步于此
    /// </summary>
    private Transform horseHeadDelay;

    /// <summary>
    /// 马头的默认位置
    /// </summary>
    private Transform horseHeadDefault;

    /// <summary>
    /// 马尾的控制点的Pos应同步于此
    /// </summary>
    private Transform horseTailDelay;

    /// <summary>
    /// 马尾的默认位置
    /// </summary>
    private Transform horseTailDefault;

    

    void Start()
    {
        //初始化
        Init();
        //找到必要的物体和组件
        FindSth();
        //计算必要的量
        CaculateSth();
    }

    void Update()
    {
        //更新一些数据
        UpdateDataEarly();
        if(horseState != HorseState.Dead)
        {
            //计算马脚目标位置
            CaculateTargetPosition();
            //让马脚朝着目标移动
            MoveFoot();
            //让马整体运动
            MoveHorse();
            //计算此时马脚在Y轴上的进程，并根据此进程对马蹄旋转插值，模拟最后一节马蹄的弯曲
            CaculateLastFootRotation();
            //跳跃检测和物理实现
            if(horseState == HorseState.Jump) CheckJump();
            //让马头控制点运动
            MoveHorseHead();
            //让马尾根据马刚体速度运动
            MoveHorseTail();

        }
        //更新一些数据
        UpdateDataLate();
    }

    void FixedUpdate() {
        CaculateFootInputCharge();
    }


    void MoveHorseTail(){
        Vector2 dir = horseTailDefault.position - horseTailDelay.position;
        Vector2 horseV = horseRig.velocity;
        dir = new Vector2(
            dir.x  * 0.05f,
            dir.y  * 0.05f
        );
        horseTailDelay.position += new Vector3(
            dir.x * Time.deltaTime * tailSpeed,
            dir.y * Time.deltaTime * tailSpeed,
            0
        );
        tailControlPoint.position = horseTailDelay.position;
    }




    void MoveHorseHead(){
        Vector2 dir = horseHeadDefault.position - horseHeadDelay.position;
        Vector2 horseV = horseRig.velocity;
        dir = new Vector2(
            dir.x += horseV.x * 0.05f,
            dir.y -= horseV.x*0.05f
        );
        horseHeadDelay.position += new Vector3(
            dir.x * Time.deltaTime * headSpeed,
            dir.y * Time.deltaTime * headSpeed,
            0
        );
        HeadControlPoint.position = horseHeadDelay.position;
    }


    void CaculateLastFootRotation(){
        for(int i = 0; i < 4; i++){
            //用脚底深度减去马足深度，ABS。得到一个Progress
            float footBottle = (i < 2) ? frontFoot.position.y : backFoot.position.y;
            float footY = foots[i].footRealTransform.position.y;
            float progress = Mathf.Abs(footBottle - footY) / (2*footMoveRadius);
            //if(i == 1) Debug.Log("左前脚Progress：" + progress);
            Vector2 lastFootRotationRange = (i < 2) ? lastFrontFootRotationRange : lastBackFootRotationRange;
            //插值,让最后一节马脚弯曲
            foots[i].lastFootTransform.rotation = Quaternion.Euler(
                0,0,
                Mathf.Lerp(
                    lastFootRotationRange.x,
                    lastFootRotationRange.y,
                    progress)
            );
        }
    }

    void CaculateFootInputCharge()
    {
        //计算上一帧和这一帧的输入的角度差
        float angleDiff = Vector2.Angle(pInputFrontVector, inputFrontVector) + 
                          Vector2.Angle(pInputBackVector, inputBackVector);
        //把它存入队列
        footInputChargeQueue.Enqueue(angleDiff);
        //如果队列的长度超过了一定的数量，就把最前面的一个去掉
        if(footInputChargeQueue.Count > footInputChargeQueueLength)
            footInputChargeQueue.Dequeue();
        
        //计算马脚的输入充能
        footInputCharge = 0;
        foreach(float angle in footInputChargeQueue)
            footInputCharge += angle;

        
        //估算了一下，充能最快大概是每秒3000.这里/3000 * 时间，即可得到一个大约0-1的值
        footInputCharge /= (3000 * accelerationTime);
        //Debug.Log("footInputCharge: " + footInputCharge);

        //更新上一帧信息
        pInputFrontVector = inputFrontVector;
        pInputBackVector = inputBackVector;
    }

    public void Death(GameController.Death deathInfo)
    {
        //修改状态至死亡
        horseState = HorseState.Dead;
        //关闭马蹄的碰撞体,并给一个右上角的速度和旋转,让马的模型掉出地图
        foreach(foot foot in foots){
            //foot.footBoxCollider2D.enabled = false;
            //马蹄刚体也需要给速度，否则会黏在地上飞不起来
            foot.footRigidbody2D.velocity = Vector2.one * deadFlySpeed * 1.5f;
        }
        //马身体的碰撞体也要关
        List<Collider2D> temp = new List<Collider2D>();
        GetComponentsInChildren<Collider2D>(temp);
        foreach(Collider2D box in temp)
            box.enabled = false;

        horseRig.velocity = Vector2.one * deadFlySpeed;
        //horseRig.AddTorque(deadFlySpeed * 20f);
    }
    
    /// <summary>
    /// 一次跳跃的最终触发函数
    /// </summary>
    private void Jump()
    {
        if(horseRig.velocity.y > 3f)
            return;

        //horseRig.velocity = Vector2.zero;
        //修改状态至跳跃
        jumpState = JumpState.Jump;

        Vector2 jumpVelocity = jumpChargeVelocity * jumpForce * -1 * new Vector2(1.5f,1.5f);
        Vector2 fix = new Vector2( (jumpChargeVelocity.x > 0 ? -1 : 1) *13f, 28f);
        jumpVelocity = 0.2f * jumpVelocity + 0.8f * fix;

        //屏蔽出了问题的极大值
        if(jumpVelocity.magnitude > 30f) jumpVelocity *= 0.1f;

        Debug.Log("Jump Velocity: " + jumpVelocity);
        horseRig.velocity = jumpVelocity;
        jumpChargeVelocity = Vector2.zero;
    }


    /// <summary>
    /// 在跳跃状态时每帧执行，用于检测跳跃和实现跳跃的物理
    /// </summary>
    private void CheckJump()
    {
        //通过本帧输入向量减上一帧输入向量得到一个瞬时速度
        Vector2 frontInstantaneousSpeed = inputFrontVector - previousInputFrontVector;
        Vector2 backInstantaneousSpeed = inputBackVector - previousInputBackVector;
        //如果任意一组的y大于0，说明在上升，不考虑它的跳跃
        if(frontInstantaneousSpeed.y > 0 || backInstantaneousSpeed.y > 0) return;
        else
        {
            //此时双腿在下降，开始检测跳跃蓄力
            //首先看前后腿输入变化的瞬时速度的模长和是否大于蓄力标准
            if(frontInstantaneousSpeed.magnitude + backInstantaneousSpeed.magnitude > jumpChargeThreshold)
            {
                //若输入的瞬时速度大于蓄力标准时，看马的跳跃状态，若处于准备态，则转移至蓄力态
                if(jumpState == JumpState.Ready) jumpState = JumpState.Charging;
                //若已处于蓄力态，累计力大小
                if(jumpState == JumpState.Charging)
                {
                    jumpChargeVelocity += (frontInstantaneousSpeed + backInstantaneousSpeed);
                }
            }
            else
            {
                //若输入的瞬时速度小于蓄力标准时，看马的跳跃状态，若处于蓄力态，则触发跳跃
                if(jumpState == JumpState.Charging) Jump();
            }
        }

    }




    /// <summary>
    /// 在Update之前更新一些数据
    /// </summary>
    private void UpdateDataEarly()
    {
        //判断是否两腿均并拢，若是，进入跳跃状态，否则设置为Stand状态
        if(horseState != HorseState.Dead)
        {
            if (isFrontFootMerged && isBackFootMerged) horseState = HorseState.Jump;
            else horseState = HorseState.Stand;
        }

        //Debug.Log("jumpState = " + jumpState);

    }



    /// <summary>
    /// 使马并拢输入的双腿，
    /// </summary>
    public void MergeFoot(FootType type)
    {
        //根据输入的组类型，判断需要更改偏移值的是那一个索引下的脚
        int index = type == FootType.Front ?  1 : 3;
        footOffestOfInput[index] = Vector2.zero;
        if(type == FootType.Front) isFrontFootMerged = true;
        else isBackFootMerged = true;
    }

    /// <summary>
    /// 恢复输入的并拢的双腿至有偏移状态
    /// </summary>
    /// <param name="type">需要恢复的是哪一组腿</param>
    public void RecoverFoot(FootType type)
    {
        //根据输入的组类型，判断需要更改偏移值的是那一个索引下的脚
        int index = type == FootType.Front ?  1 : 3;
        footOffestOfInput[index] = oriFootOffestOfInput[index];
        if(type == FootType.Front) isFrontFootMerged = false;
        else isBackFootMerged = false;
    }

    /// <summary>
    /// 移动马身体
    /// </summary>
    private void MoveHorse()
    {   
        Vector2 v = new Vector2();

        for(int i = 0; i < 4; i++)
        {
            //仅在有输入的情况下，会考虑给速度
            //看此时该脚是否有输入
            bool hasInput = i < 2 ? inputFrontVector.magnitude > 0.1f : inputBackVector.magnitude > 0.1f;
            if(!hasInput) continue;
            //从足底向正下方发射射线，获取碰撞到的物体
            RaycastHit2D hit = Physics2D.Raycast(
                                                    foots[i].footRealTransform.position, 
                                                    Vector2.down, 
                                                    1000f,
                                                    LayerMask.NameToLayer("foot")
                                                );
            //如果击中物体的距离已经超过了有效范围，则不贡献速度
            if(hit.distance > effectiveDistance) continue;
            //判断本帧中，马足位置是否低于圆心+调整值，仅低于时，需要计算影响
            //根位置
            Vector3 rootPosition = i < 2 ? frontLegRoot.position : backLegRoot.position;
            //L
            float L = i < 2 ? frontLegLength : backLegLength;
            //圆心y坐标
            float centerY = L - footMoveRadius;
            centerY += effectiveDistance;
            //仅低于时，需要计算影响
            if(foots[i].footRealTransform.position.y >= centerY) continue;
            //本帧位置减上帧位置
            Vector3 trans = foots[i].footRealTransform.position - foots[i].footPreviousPosition;
            Vector2 v_ = trans;
            //把本足的影响加到速度中
            v += v_;
        }

        //给速度乘以力量，得到最终理论速度
        v *= strength * (1 + footInputCharge * accelerationRate);
        //取反，因为是模拟反作用力
        v*=-1;
        //减弱y轴的影响，不要让马在平地上起飞
        v *= new Vector2(1,0.2f);

        //如果模长超过5，那必是触发了什么逆天Bug，会导致马起飞，需要避免这些错误
        if(v.magnitude > 20f){
            v = Vector2.zero;
            Debug.Log("莫动");
        } 

        //如果马处于跳跃状态，则不让马蹄提供速度
        if(horseState == HorseState.Jump)
            v = Vector2.zero;
        
        //把速度加给马的刚体
        horseRig.velocity += v;
    }

    private void UpdateDataLate()
    {
        //更新四足的上帧位置
        for(int i = 0; i < 4; i++)
            foots[i].footPreviousPosition = foots[i].footRealTransform.position;

        //更新上帧输入
        previousInputFrontVector = inputFrontVector;
        previousInputBackVector = inputBackVector;
    }

    void Init()
    {
        foots = new foot[4];
        oriFootOffestOfInput = new Vector2[4];
        footBoxColliders = new BoxCollider2D[4];
        for(int i = 0; i < 4; i++) foots[i].footPreviousPosition = transform.position;
        for(int i = 0; i < 4; i++) oriFootOffestOfInput[i] = footOffestOfInput[i];
        horseState = HorseState.Stand;
        footInputChargeQueue = new Queue<float>();

        //初始化马背接收系统
        GameObject.Find("接收人用的马背（不可改名）").AddComponent<HoseBack>();
    }

    private class HoseBack : MonoBehaviour{
        private void OnTriggerEnter2D(Collider2D other) {
            //当马背接受到人，触发人的Recover();
            if(other.TryGetComponent<Person>(out Person person) && person.state == Person.PersonState.FallingOff)    person.Recover();
        }
    }



    void FindSth()
    {
        //把四只脚的目标点找到，0：左前 1：右前 2：左后 3：右后
        foots[0].footControlPoint = transform.Find("左前脚").GetChild(0);
        foots[1].footControlPoint = transform.Find("右前脚").GetChild(0);
        foots[2].footControlPoint = transform.Find("左后脚").GetChild(0);
        foots[3].footControlPoint = transform.Find("右后脚").GetChild(0);

        //同步四只脚的输入偏差
        for (int i = 0; i < 4; i++) foots[i].footOffestOfInput = footOffestOfInput[i];

        //找到马蹄刚体组件
        for(int i = 0; i < 4; i++) foots[i].footRigidbody2D = foots[i].footControlPoint.GetComponent<Rigidbody2D>();

        //找到马蹄的真实Transform
        for(int i = 0; i < 4; i++) foots[i].footRealTransform = footsTransform[i];

        //找到马蹄的碰撞体
        footBoxColliders = GetComponents<BoxCollider2D>();

        //给foots的碰撞体赋值
        for (int i = 0; i < 4; i++)
        {
            foots[i].footBoxCollider2D = footBoxColliders[i];
            footBoxColliders[i].offset = foots[i].footControlPoint.localPosition ;
        }

        //找到马的刚体
        horseRig = GetComponent<Rigidbody2D>();

        //
        rotateCenter = transform.Find("马死后的旋转中心");
        
        //
        for(int i = 0; i < 4; i++){
            foots[i].lastFootTransform = lastFoots[i];
        }

        //
        horseHeadDelay = GameObject.Find("马头IK延迟（不可改名）").transform;
        horseHeadDefault = transform.Find("马头默认位置（不可改名）");
        
        //
        //tailBone = transform.Find("bone_10");
        horseTailDelay = GameObject.Find("马尾IK延迟（不可改名）").transform;
        horseTailDefault = transform.Find("马尾默认位置（不可改名）");
    }

    /// <summary>
    /// 计算一些不会变的必要的量
    /// </summary>
    void CaculateSth()
    {
        //计算前后腿马腿长度
        frontLegLength = Vector3.Distance(frontLegRoot.position, frontFoot.position);
        backLegLength = Vector3.Distance(backLegRoot.position, backFoot.position);
        //计算从腿根骨骼到马脚运动圆心的距离
        frontRootDistanceToCenterOfCircle = frontLegLength - footMoveRadius;
        backRootDistanceToCenterOfCircle = backLegLength - footMoveRadius;
        //取得原始重力尺度
        oriGravityScale = foots[0].footRigidbody2D.gravityScale;
        //计算要记录多少帧的输入，用秒计算，每秒60次FixedUpdate
        footInputChargeQueueLength = (int)accelerationTime * 60;


    }

    /// <summary>
    /// 根据记录的输入向量计算马脚本帧的目标位置，保存到footTargetPoints数组中
    /// </summary>
    private void CaculateTargetPosition()
    {   
        //循环4次
        for(int i = 0; i < 4; i++)
        {
            //整体公式为：Target = 根位置 - V（0，L - r） + inputdir * offest * r
            //根位置
            Vector3 rootPosition = i < 2 ? frontLegRoot.position : backLegRoot.position;
            //L
            float L = i < 2 ? frontLegLength : backLegLength;
            //中间向量
            Vector3 middleVector = new Vector3(0,L - footMoveRadius,0);
            //inputdir
            Vector2 inputVector = i < 2 ? inputFrontVector : inputBackVector;
            //inputTrans
            Vector3 inputTrans = new Vector3
                                (
                                    inputVector.x * ( footOffestOfInput[i].x + 1),
                                    inputVector.y * ( footOffestOfInput[i].y + 1),
                                    0
                                )
                                * footMoveRadius;
            //最终计算
            //footTargetPoints[i] = rootPosition - middleVector + inputTrans;
            foots[i].footTargetPosition = rootPosition - middleVector + inputTrans;
        }
    }

    /// <summary>
    /// 把马脚朝着算好的目标点移动
    /// </summary>
    private void MoveFoot()
    {
        //循环4次
        for(int i = 0; i < 4; i++)
        {
            //看此时该脚是否有输入
            bool hasInput = i < 2 ? inputFrontVector.magnitude > 0.1f : inputBackVector.magnitude > 0.1f;
            //如果有输入，则把马脚朝着目标移动
            Vector3 targetPosition = hasInput ?  
                                        foots[i].footTargetPosition : 
                                        foots[i].footTargetPosition - new Vector3(0,footMoveRadius + 0.5f,0);
            // if(hasInput)
            if(true)
            {
                //若无输入，则把目标定在可以使马腿伸直的地方
                // Vector3 targetPosition = hasInput ?  
                //                             foots[i].footTargetPosition : 
                //                             foots[i].footTargetPosition - new Vector3(0,footMoveRadius + 0.5f,0);
                //给刚体以target位置-自身位置作为力的方向
                Vector2 Dir = targetPosition - foots[i].footControlPoint.position;
                //如果已经很接近目标点了，则不再给速度，同时解除重力，防止出现抖动问题
                if(Dir.magnitude < 0.1f)
                {
                    foots[i].footRigidbody2D.gravityScale = 0;
                    foots[i].footRigidbody2D.velocity = Vector2.zero;
                    continue;
                }
                //标准化马脚移动方向
                Dir.Normalize();
                //最终计算应有的速度
                Vector2 force = Dir * footForce * (horseRig.velocity.magnitude * 0.1f + 1);
                //赋予脚的刚体以速度
                foots[i].footRigidbody2D.velocity = foots[i].footRigidbody2D.velocity * 0.8f + force * 0.2f;
                //foots[i].footRigidbody2D.velocity = force;
                //foots[i].footRigidbody2D.AddForce(force);
            }
            // // 强制把马脚移到目标点
            //foots[i].footControlPoint.position = foots[i].footTargetPosition;
            //foots[i].footControlPoint.position = targetPosition;
            // 恢复重力
            foots[i].footRigidbody2D.gravityScale = oriGravityScale;
            // 刷新碰撞体位置
            footBoxColliders[i].offset = foots[i].footRealTransform.position - transform.position;
        }
    }

    public void SetInputFrontVector(Vector2 input) => inputFrontVector = input;

    public void SetInputBackVector(Vector2 input) => inputBackVector = input;

    public bool IsHorseStillAlive() => horseState != HorseState.Dead;


    //撞击地面后，修改跳跃状态
    void OnCollisionEnter2D(Collision2D collision)
    {
        if(collision.gameObject.tag == "Ground")
        {
            jumpState = JumpState.Ready;
        }
    }
}
