religion/Assets/Scripts/MyPlayer.cs
Roman ff4639d2cf 任务:搭建基本的系统
1.编写普通小怪受击逻辑
(1.受击时获得受击方式和受击方向
(*:新建tweenNow变量记录正在播放的动画
(2.受击瞬间停止tweenNow(否则怪物的物理路径将被锁定在tween中
(*:向玩家类中添加字典,用来查询不同攻击方式的攻击倍率
(*:向怪物基类中添加CheckDead功能
(*:编写受击击飞效果,类似于player
(3.减少生命值,同时呼唤CheckDead
(4.若死亡,更改怪物状态为Dead,呼唤OnDead,编写OnDead,给予其范围内随机一个旋转角速度,同时关闭其碰撞体,同时开启一个协程,使其一定时间后被销毁。
(*:给普通怪物添加positionSource变量,记录游戏开始时怪物的位置
(*:给普通小怪类添加inPath变量,记录一下目前是否正在执行path动画
(5.若未死亡,则让怪物着地后Dotween到初始位置,结束后触发事件,重新开始巡逻
(*:修复速度无法控制怪物真实速度的问题
(*:我超,由于插件存在不可忽略的缺陷,要修改怪物的移动速度做不到自动化了,必须通过在Path组件自行输入持续时间,其实就是多做一个小学算数,呐
2021-11-28 23:34:14 +08:00

302 lines
12 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using DG.Tweening;
using Sirenix.OdinInspector;
// _
// | |
// _ __ | | __ _ _ _ ___ _ __
// | '_ \| |/ _` | | | |/ _ \ '__|
// | |_) | | (_| | |_| | __/ |
// | .__/|_|\__,_|\__, |\___|_|
// | | __/ |
// |_| |___/
/// <summary>
/// 玩家类,控制玩家相关的东西
/// </summary>
public class MyPlayer : MonoBehaviour
{
// _____ _ _ _
// | __ \ | | | (_)
// | |__) | _| |__ | |_ ___
// | ___/ | | | '_ \| | |/ __|
// | | | |_| | |_) | | | (__
// |_| \__,_|_.__/|_|_|\___|
[Header("玩家平时地面移动的速度")][FoldoutGroup("Info")]
public float speed = 10f;
[Header("玩家跳跃力度的大小")][FoldoutGroup("Info")]
public float jumpForce = 10f;
[FoldoutGroup("CD")][Header("挥动锤子的CD时长")]
public float hammerCD = 1f;
[FoldoutGroup("CD")][Header("发射镰刀的CD时长")]
public float sickleCD = 10f;
[Header("镰刀游戏物体")][FoldoutGroup("预制体")]
public GameObject sicklePrefab;
public enum AtkMethod{,,};
/// <summary>
/// 生命值上限
/// </summary>
[FoldoutGroup("Info")][Header("生命值上限")]
public float HP;
/// <summary>
/// 被击飞后的飞行方向的调整值
/// </summary>
[Header("被攻击后击飞的力度调整值")][FoldoutGroup("其他",false,0)]
public Vector2 hitToflyParameter;
/// <summary>
/// 攻击方式的倍率列表
/// </summary>
[DictionaryDrawerSettings()][Header("攻击方式的倍率列表")][ShowInInspector][FoldoutGroup("其他",false,0)]
public static Dictionary<AtkMethod,int> atkMethodMagnification;
// _____ _ _
// | __ \ (_) | |
// | |__) | __ ___ ____ _| |_ ___
// | ___/ '__| \ \ / / _` | __/ _ \
// | | | | | |\ 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;//锤子的碰撞体
[FoldoutGroup("CD")][Header("挥动锤子的CD还剩多长时间")][SerializeField][ReadOnly]
private float hammerCDLeft = 0f;
[FoldoutGroup("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)][FoldoutGroup("Info")]
private float HPLeft;
// _____ _ _ ____ _
// / ____| | | | _ \ | |
// | | __ _| | | |_) | __ _ ___| | __
// | | / _` | | | _ < / _` |/ __| |/ /
// | |___| (_| | | | |_) | (_| | (__| <
// \_____\__,_|_|_|____/ \__,_|\___|_|\_\
void Start()
{
Init();//初始化一些参数
}
void Update()
{
CountCD();
}
void FixedUpdate()
{
Move();//处理水平移动
}
// _ _ _
// | \ | | | |
// | \| | ___ _ __ _ __ ___ __ _| |
// | . ` |/ _ \| '__| '_ ` _ \ / _` | |
// | |\ | (_) | | | | | | | | (_| | |
// |_| \_|\___/|_| |_| |_| |_|\__,_|_|
//初始化函数
private void Init()
{
m_rigidbody = GetComponent<Rigidbody2D>();//找到自己身上的刚体组件
wavingAnimation = transform.Find("锤子的旋转中心").GetComponent<DOTweenAnimation>();
hammerSprite = transform.Find("锤子的旋转中心").Find("锤子").GetComponent<SpriteRenderer>();
hammerCollider = transform.Find("锤子的旋转中心").Find("锤子").GetComponent<BoxCollider2D>();
sickleFirePoint = transform.Find("镰刀发射点");
sickleClearerL = transform.Find("镰刀飞出消除触发器左");
sickleClearerL.gameObject.AddComponent<SickleClearer>();
sickleClearerR = transform.Find("镰刀飞出消除触发器右");
sickleClearerR.gameObject.AddComponent<SickleClearer>();
HPLeft = HP;
atkMethodMagnification = new Dictionary<AtkMethod, int>();
atkMethodMagnification.Add(AtkMethod.,1);
atkMethodMagnification.Add(AtkMethod.,1);
atkMethodMagnification.Add(AtkMethod.,2);
}
//移动函数,处理水平方向移动
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);
}
/// <summary>
/// 被击飞的时候Call这个
/// </summary>
/// <param name="dir">被击方向</param>
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<float>().Equals(0))
inputDir = (context.ReadValue<float>() > 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>();
sickle.dir = faceDir;
sickleCDLeft = sickleCD;
}
}
// ______ _
// | ____| | |
// | |____ _____ _ __ | |_
// | __\ \ / / _ \ '_ \| __|
// | |___\ V / __/ | | | |_
// |______\_/ \___|_| |_|\__|
//当挥动锤子动画结束后触发
public void OnWaveEnd()
{
//为挥动动画倒带
wavingAnimation.DORewind();
//把锤子隐藏Debug用后期请删除
hammerSprite.DOFade(0,0f);
//关闭锤子的碰撞体
hammerCollider.enabled = false;
}
/// <summary>
/// 当玩家被打则Call这个函数
/// </summary>
/// <param name="atk">遭受的攻击力</param>
/// <param name="dir">攻击来源的方向,-1左1右</param>
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<Sickle>(out Sickle temp))
Destroy(temp.gameObject);
}
}
}