using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.InputSystem; using DG.Tweening; using Sirenix.OdinInspector; // _ // | | // _ __ | | __ _ _ _ ___ _ __ // | '_ \| |/ _` | | | |/ _ \ '__| // | |_) | | (_| | |_| | __/ | // | .__/|_|\__,_|\__, |\___|_| // | | __/ | // |_| |___/ /// /// 玩家类,控制玩家相关的东西 /// public class MyPlayer : MonoBehaviour { // _____ _ _ _ // | __ \ | | | (_) // | |__) | _| |__ | |_ ___ // | ___/ | | | '_ \| | |/ __| // | | | |_| | |_) | | | (__ // |_| \__,_|_.__/|_|_|\___| [Header("玩家平时地面移动的速度")][FoldoutGroup("Info")] public float speed = 10f; [Header("玩家跳跃力度的大小")][FoldoutGroup("Info")] public float jumpForce = 10f; [BoxGroup("CD")][Header("挥动锤子的CD时长")] public float hammerCD = 1f; [BoxGroup("CD")][Header("发射镰刀的CD时长")] public float sickleCD = 10f; [Header("镰刀游戏物体")][BoxGroup("预制体")] public GameObject sicklePrefab; public enum AtkMethod{镰刀,锤子,反弹炸弹}; /// /// 生命值上限 /// [FoldoutGroup("Info")][Header("生命值上限")] public float HP; /// /// 被击飞后的飞行方向的调整值 /// [Header("被攻击后击飞的力度调整值")][FoldoutGroup("其他",false,0)] public Vector2 hitToflyParameter; // _____ _ _ // | __ \ (_) | | // | |__) | __ ___ ____ _| |_ ___ // | ___/ '__| \ \ / / _` | __/ _ \ // | | | | | |\ V / (_| | || __/ // |_| |_| |_| \_/ \__,_|\__\___| private Rigidbody2D m_rigidbody;//自身刚体组件 [SerializeField][ReadOnly][FoldoutGroup("Info")] private int inputDir;//当前输入方向,-1左,1右,0静止 [SerializeField][ReadOnly][FoldoutGroup("Info")] private bool isLanding;//记录自己当前是否着地 private DOTweenAnimation wavingAnimation;//锤子挥动动画组件 private SpriteRenderer hammerSprite;//锤子的图片组件 private BoxCollider2D hammerCollider;//锤子的碰撞体 [BoxGroup("CD")][Header("挥动锤子的CD还剩多长时间")][SerializeField][ReadOnly] private float hammerCDLeft = 0f; [BoxGroup("CD")][Header("发射镰刀的CD还剩多长时间")][SerializeField][ReadOnly] private float sickleCDLeft = 0f; private int faceDir = 1;//面部朝向 private Transform sickleFirePoint;//镰刀发射点的transform private Transform sickleClearerL;//左边的镰刀清除触发器 private Transform sickleClearerR;//右边的镰刀清除触发器 [FoldoutGroup("其他",false,1)][Header("玩家现在是否处于控制状态下(物理)")][SerializeField][ReadOnly] private bool inControl = true; [SerializeField][ReadOnly][ProgressBar(0,10,0.15f,0.47f,0.74f)] private float HPLeft; // _____ _ _ ____ _ // / ____| | | | _ \ | | // | | __ _| | | |_) | __ _ ___| | __ // | | / _` | | | _ < / _` |/ __| |/ / // | |___| (_| | | | |_) | (_| | (__| < // \_____\__,_|_|_|____/ \__,_|\___|_|\_\ void Start() { Init();//初始化一些参数 } void Update() { CountCD(); } void FixedUpdate() { Move();//处理水平移动 } // _ _ _ // | \ | | | | // | \| | ___ _ __ _ __ ___ __ _| | // | . ` |/ _ \| '__| '_ ` _ \ / _` | | // | |\ | (_) | | | | | | | | (_| | | // |_| \_|\___/|_| |_| |_| |_|\__,_|_| //初始化函数 private void Init() { m_rigidbody = GetComponent();//找到自己身上的刚体组件 wavingAnimation = transform.Find("锤子的旋转中心").GetComponent(); hammerSprite = transform.Find("锤子的旋转中心").Find("锤子").GetComponent(); hammerCollider = transform.Find("锤子的旋转中心").Find("锤子").GetComponent(); sickleFirePoint = transform.Find("镰刀发射点"); sickleClearerL = transform.Find("镰刀飞出消除触发器左"); sickleClearerL.gameObject.AddComponent(); sickleClearerR = transform.Find("镰刀飞出消除触发器右"); sickleClearerR.gameObject.AddComponent(); HPLeft = HP; } //移动函数,处理水平方向移动 private void Move() { if(inControl) //直接修改刚体速度 m_rigidbody.velocity = new Vector2(inputDir * speed,//水平方向以输入方向乘以预设速度大小 m_rigidbody.velocity.y);//垂直方向不变 } //计算CD的函数,每帧调用 private void CountCD() { if(hammerCDLeft > 0) hammerCDLeft -= Time.deltaTime; if(sickleCDLeft > 0) sickleCDLeft -= Time.deltaTime; } private void TurnAround() { faceDir = inputDir; transform.localScale = new Vector3( //x乘-1以显示转身 transform.localScale.x * -1, //y、z不变 transform.localScale.y, transform.localScale.z); } /// /// 被击飞的时候Call这个 /// /// 被击方向 public void BeHitToFly(int dir) { m_rigidbody.velocity += new Vector2( -1 * dir * hitToflyParameter.x, hitToflyParameter.y ); } //碰撞检测代码 // _____ _ _ _ _ // / ____| | | (_) (_) // | | ___ | | |_ ___ _ ___ _ __ // | | / _ \| | | / __| |/ _ \| '_ \ // | |___| (_) | | | \__ \ | (_) | | | | // \_____\___/|_|_|_|___/_|\___/|_| |_| private void OnCollisionEnter2D(Collision2D collision)//当有物体碰上 { if(collision.transform.tag == "地面") {isLanding = true;//若碰撞物体标签为地面,标记自身着地 inControl = true;} } private void OnCollisionExit2D(Collision2D collision)//当有碰撞体离开 { if(collision.transform.tag == "地面") {isLanding = false;}//若碰撞物体标签为地面,标记自身未着地 } // 以下为操作监听事件 // _____ _ _____ _ // |_ _| | | / ____| | | // | | _ __ _ __ _ _| |_| (___ _ _ ___| |_ ___ _ __ ___ // | | | '_ \| '_ \| | | | __|\___ \| | | / __| __/ _ \ '_ ` _ \ // _| |_| | | | |_) | |_| | |_ ____) | |_| \__ \ || __/ | | | | | // |_____|_| |_| .__/ \__,_|\__|_____/ \__, |___/\__\___|_| |_| |_| // | | __/ | // |_| |___/ public void OnMove(InputAction.CallbackContext context)//OnMove事件 { //决定输入方向inputDir if(!context.ReadValue().Equals(0)) inputDir = (context.ReadValue() > 0) ? 1 : -1; else inputDir = 0; if(faceDir * inputDir < 0) { TurnAround(); } } public void OnJump(InputAction.CallbackContext context)//OnJump事件 { //当按下跳跃键 if(context.performed) { if(isLanding)//如果当前着地 //给予自身刚体 m_rigidbody.velocity = new Vector2(m_rigidbody.velocity.x,//水平方向速度不变 jumpForce);//垂直方向给予预设跳跃速度 } } public void OnWave(InputAction.CallbackContext context) { //当执行Wave动作 if (context.performed && hammerCDLeft <= 0) { hammerSprite.DOFade(1, 0f);//把锤子显示,Debug用,后期请删除 hammerCollider.enabled = true;// wavingAnimation.DOPlay();//播放挥动锤子动画 hammerCDLeft = hammerCD;//挥动成功,重置CD剩余时间 } } public void OnSickle(InputAction.CallbackContext context) { if(context.started && sickleCDLeft <= 0) { Sickle sickle = Instantiate( sicklePrefab, sickleFirePoint.position, Quaternion.identity). GetComponent(); sickle.dir = faceDir; sickleCDLeft = sickleCD; } } // ______ _ // | ____| | | // | |____ _____ _ __ | |_ // | __\ \ / / _ \ '_ \| __| // | |___\ V / __/ | | | |_ // |______\_/ \___|_| |_|\__| //当挥动锤子动画结束后触发 public void OnWaveEnd() { //为挥动动画倒带 wavingAnimation.DORewind(); //把锤子隐藏,Debug用,后期请删除 hammerSprite.DOFade(0,0f); //关闭锤子的碰撞体 hammerCollider.enabled = false; } /// /// 当玩家被打则Call这个函数 /// /// 遭受的攻击力 /// 攻击来源的方向,-1左,1右 public void OnBeHit(float atk, int dir) { Debug.Log("我被攻击了!受到的攻击力是:" + atk + "攻击方向来自" + ((dir == 1) ? "右边" : "左边")); BeHitToFly(dir); inControl = false; HPLeft -= atk; } // _______ _ _____ _ // |__ __| | |/ ____| | // | | ___ ___ | | | | | __ _ ___ ___ // | |/ _ \ / _ \| | | | |/ _` / __/ __| // | | (_) | (_) | | |____| | (_| \__ \__ \ // |_|\___/ \___/|_|\_____|_|\__,_|___/___/ private class SickleClearer : MonoBehaviour { //一个工具小插件,单独写脚本实在太浪费,所以在这里写一下。 //当触发器检测到有东西进入,会试图获取它身上的镰刀脚本,如果有就说明镰刀到屏幕边缘了,把这个镰刀删除 //没有的话说明是其他物体,不作处理 void OnTriggerEnter2D(Collider2D other) { if(other.TryGetComponent(out Sickle temp)) Destroy(temp.gameObject); } } }