任务:搭建基本的系统

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

View File

@ -463,7 +463,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 326335321}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -0.9, y: -0.8, z: 0}
m_LocalPosition: {x: -8.16, y: -0.8, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 321454206}
@ -629,7 +629,7 @@ MonoBehaviour:
speed: 10
jumpForce: 20
hammerCD: 1
sickleCD: 10
sickleCD: 0
sicklePrefab: {fileID: 8280362330273855463, guid: 2e2fb120ae20d5e4faaad5a2a2fcca30, type: 3}
HP: 10
hitToflyParameter: {x: 10, y: 10}
@ -1107,7 +1107,7 @@ MonoBehaviour:
m_PersistentCalls:
m_Calls: []
delay: 0
duration: 3
duration: 8
easeType: 1
easeCurve:
serializedVersion: 2
@ -1143,7 +1143,7 @@ MonoBehaviour:
autoPlay: 1
autoKill: 0
relative: 0
isLocal: 0
isLocal: 1
isClosedPath: 1
pathResolution: 10
pathMode: 3
@ -1153,28 +1153,58 @@ MonoBehaviour:
upDirection: {x: 0, y: 1, z: 0}
tweenRigidbody: 0
wps:
- {x: 8.32342, y: -1.0342596, z: 0}
- {x: 1.410517, y: -1.0342596, z: 0}
fullWps: []
path:
wpLengths:
- 0
- 3.503422
- 3.503422
- 4.030519
- 4.030519
wps:
- {x: 4.82, y: -1.03, z: 0}
- {x: 8.32342, y: -1.0342596, z: 0}
- {x: 4.82, y: -1.03, z: 0}
- {x: -2.62, y: -1.03, z: 0}
- {x: 1.410517, y: -1.0342596, z: 0}
- {x: -2.62, y: -1.03, z: 0}
type: 0
subdivisionsXSegment: 10
subdivisions: 30
controlPoints: []
length: 7.006844
length: 8.061038
isFinalized: 1
timesTable:
- 0
- 0.5
- 1
lengthsTable: []
lengthsTable:
- 0.044636283
- 0.17024052
- 0.36435583
- 0.6145263
- 0.9082949
- 1.2332048
- 1.5767996
- 1.9266229
- 2.2702177
- 2.5951276
- 2.8888958
- 3.1390667
- 3.3331816
- 3.4587862
- 3.503422
- 3.5480578
- 3.6736624
- 3.8677778
- 4.117948
- 4.411716
- 4.7366266
- 5.0802217
- 5.430045
- 5.77364
- 6.09855
- 6.3923187
- 6.642488
- 6.8366036
- 6.9622073
- 7.0068436
inspectorMode: 0
pathType: 0
handlesType: 0
@ -1182,9 +1212,9 @@ MonoBehaviour:
handlesDrawMode: 0
perspectiveHandleSize: 0.5
showIndexes: 1
showWpLength: 0
showWpLength: 1
pathColor: {r: 1, g: 1, b: 1, a: 0.5}
lastSrcPosition: {x: 4.82, y: -1.03, z: 0}
lastSrcPosition: {x: -2.62, y: -1.03, z: 0}
lastSrcRotation: {x: 0, y: 0, z: 0, w: 1}
wpsDropdown: 1
dropToFloorOffset: 0
@ -1200,11 +1230,16 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 2127494698a58b642b7d3ec5f92f8974, type: 3}
m_Name:
m_EditorClassIdentifier:
HP: 0
HP: 3
ATK: 1
speed: 1
coin: 0
HPLeft: 0
state: 0
hitToflyParameter: {x: 3, y: 3}
deadRotationRangeMax: 500
deadRotationRangeMin: 500
inPath: 1
--- !u!4 &1478051114
Transform:
m_ObjectHideFlags: 0
@ -1213,7 +1248,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1478051109}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 4.82, y: -1.03, z: 0}
m_LocalPosition: {x: -2.62, y: -1.03, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}

View File

@ -19,25 +19,24 @@ public class Enemy : MonoBehaviour
/// <summary>
/// 生命值上限
/// </summary>
[BoxGroup("属性")][Header("生命值上限")]
[FoldoutGroup("属性")][Header("生命值上限")]
public float HP;
/// <summary>
/// 攻击力
/// </summary>
[BoxGroup("属性")][Header("攻击力")]
[FoldoutGroup("属性")][Header("攻击力")]
public float ATK;
/// <summary>
/// 速度
/// </summary>
[BoxGroup("属性")]
public float speed{get{return speed;} set{speed = value;}}
[FoldoutGroup("属性")][Header("移动速度")]
public float speed;
/// <summary>
/// 打死后掉多少金币
/// </summary>
[BoxGroup("属性")][Header("掉落金币数")]
[FoldoutGroup("属性")][Header("掉落金币数")]
public int coin;
/// <summary>
@ -55,13 +54,13 @@ public class Enemy : MonoBehaviour
/// <summary>
/// 当前生命值
/// </summary>
[ReadOnly][SerializeField][ProgressBar(0,10,0.15f,0.47f,0.74f)][BoxGroup("状态")]
[ReadOnly][SerializeField][ProgressBar(0,10,0.15f,0.47f,0.74f)][FoldoutGroup("状态")]
protected float HPLeft;
/// <summary>
/// 当前状态
/// </summary>
[EnumPaging][SerializeField][ReadOnly][Header("当前状态")][BoxGroup("状态")]
[EnumPaging][SerializeField][ReadOnly][Header("当前状态")][FoldoutGroup("状态")]
protected State state;
// ______ _
@ -74,7 +73,7 @@ public class Enemy : MonoBehaviour
/// <summary>
/// 当怪物死的时候Call这个函数
/// </summary>
protected void OnDead(){}
protected virtual void OnDead(){}
/// <summary>
/// 当怪物触碰到玩家的时候Call这个
@ -86,12 +85,28 @@ public class Enemy : MonoBehaviour
/// </summary>
/// <param name="hitMethod">攻击方式枚举类型具体看MyPlayer</param>
/// <param name="hitDir">受击方向,-1左1右</param>
protected void OnBeHit(MyPlayer.AtkMethod hitMethod,int hitDir){}
protected virtual void OnBeHit(MyPlayer.AtkMethod hitMethod,int hitDir){}
/// <summary>
/// 当怪物发现玩家的时候Call这个
/// </summary>
protected void OnFindThePlayer(){}
/// <summary>
/// 当怪物着地的时候触发一次
/// </summary>
protected virtual void OnRetouchedTheGround(){}
// _ _ _
// | \ | | | |
// | \| | ___ _ __ _ __ ___ __ _| |
// | . ` |/ _ \| '__| '_ ` _ \ / _` | |
// | |\ | (_) | | | | | | | | (_| | |
// |_| \_|\___/|_| |_| |_| |_|\__,_|_|
/// <summary>
/// 看看死了没
/// </summary>
protected bool CheckDead(){return !(HPLeft > 0);}
// _____ _ _ _ _
@ -104,6 +119,19 @@ public class Enemy : MonoBehaviour
{
if(other.gameObject.TryGetComponent<MyPlayer>(out MyPlayer player))
{OnTouchThePlayer(player);}//如果创到的是玩家则Call事件
//如果被镰刀创到Call一下OnBeHit事件传入攻击方式和攻击来袭方向
else if(other.gameObject.TryGetComponent<Sickle>(out Sickle sickle))
{OnBeHit(MyPlayer.AtkMethod.,
(transform.position.x -
sickle.transform.position.x > 0) ? -1 : 1);
Destroy(sickle.gameObject);}
//如果被锤子锤到,和上面一样
else if(other.gameObject.TryGetComponent<Hammer>(out Hammer hammer))
{OnBeHit(MyPlayer.AtkMethod.,
(transform.position.x -
hammer.transform.position.x > 0) ? -1 : 1);}
else if(other.gameObject.tag == "地面")
{OnRetouchedTheGround();}
}
protected void OnTriggerEnter2D(Collider2D other)
{

8
Assets/Scripts/Hammer.cs Normal file
View File

@ -0,0 +1,8 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Hammer : MonoBehaviour
{
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e8542bc5f7711d44d8c471ae7ca4eb87
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -30,11 +30,11 @@ public class MyPlayer : MonoBehaviour
public float speed = 10f;
[Header("玩家跳跃力度的大小")][FoldoutGroup("Info")]
public float jumpForce = 10f;
[BoxGroup("CD")][Header("挥动锤子的CD时长")]
[FoldoutGroup("CD")][Header("挥动锤子的CD时长")]
public float hammerCD = 1f;
[BoxGroup("CD")][Header("发射镰刀的CD时长")]
[FoldoutGroup("CD")][Header("发射镰刀的CD时长")]
public float sickleCD = 10f;
[Header("镰刀游戏物体")][BoxGroup("预制体")]
[Header("镰刀游戏物体")][FoldoutGroup("预制体")]
public GameObject sicklePrefab;
public enum AtkMethod{,,};
/// <summary>
@ -47,6 +47,11 @@ public class MyPlayer : MonoBehaviour
/// </summary>
[Header("被攻击后击飞的力度调整值")][FoldoutGroup("其他",false,0)]
public Vector2 hitToflyParameter;
/// <summary>
/// 攻击方式的倍率列表
/// </summary>
[DictionaryDrawerSettings()][Header("攻击方式的倍率列表")][ShowInInspector][FoldoutGroup("其他",false,0)]
public static Dictionary<AtkMethod,int> atkMethodMagnification;
// _____ _ _
// | __ \ (_) | |
@ -63,9 +68,9 @@ public class MyPlayer : MonoBehaviour
private DOTweenAnimation wavingAnimation;//锤子挥动动画组件
private SpriteRenderer hammerSprite;//锤子的图片组件
private BoxCollider2D hammerCollider;//锤子的碰撞体
[BoxGroup("CD")][Header("挥动锤子的CD还剩多长时间")][SerializeField][ReadOnly]
[FoldoutGroup("CD")][Header("挥动锤子的CD还剩多长时间")][SerializeField][ReadOnly]
private float hammerCDLeft = 0f;
[BoxGroup("CD")][Header("发射镰刀的CD还剩多长时间")][SerializeField][ReadOnly]
[FoldoutGroup("CD")][Header("发射镰刀的CD还剩多长时间")][SerializeField][ReadOnly]
private float sickleCDLeft = 0f;
private int faceDir = 1;//面部朝向
private Transform sickleFirePoint;//镰刀发射点的transform
@ -73,7 +78,7 @@ public class MyPlayer : MonoBehaviour
private Transform sickleClearerR;//右边的镰刀清除触发器
[FoldoutGroup("其他",false,1)][Header("玩家现在是否处于控制状态下(物理)")][SerializeField][ReadOnly]
private bool inControl = true;
[SerializeField][ReadOnly][ProgressBar(0,10,0.15f,0.47f,0.74f)]
[SerializeField][ReadOnly][ProgressBar(0,10,0.15f,0.47f,0.74f)][FoldoutGroup("Info")]
private float HPLeft;
// _____ _ _ ____ _
@ -117,6 +122,10 @@ public class MyPlayer : MonoBehaviour
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);
}
//移动函数,处理水平方向移动

View File

@ -1,14 +1,158 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using Sirenix.OdinInspector;
/// <summary>
/// 普通怪物类,三关都有的那个
/// </summary>
public class NormalEnemy : Enemy
{
protected override void OnTouchThePlayer(MyPlayer player)
{
// _____ _ _ _
// | __ \ | | | (_)
// | |__) | _| |__ | |_ ___
// | ___/ | | | '_ \| | |/ __|
// | | | |_| | |_) | | | (__
// |_| \__,_|_.__/|_|_|\___|
[Header("被攻击后击飞的力度调整值")][FoldoutGroup("其他",false,0)]
public Vector2 hitToflyParameter;
[FoldoutGroup("其他",false,0)][Header("怪物死后旋转速度的随机区间")]
public float deadRotationRangeMax;
[FoldoutGroup("其他",false,0)]
public float deadRotationRangeMin;
// _____ _ _
// | __ \ (_) | |
// | |__) | __ ___ ____ _| |_ ___
// | ___/ '__| \ \ / / _` | __/ _ \
// | | | | | |\ V / (_| | || __/
// |_| |_| |_| \_/ \__,_|\__\___|
protected Rigidbody2D m_rigidbody;
/// <summary>
/// 死的时候的受击朝向
/// </summary>
protected int deadDir;
/// <summary>
/// 记录一下游戏开始时怪物的位置,方便被击飞后怪物重新回到巡逻起点
/// </summary>
protected Vector3 sourcePosition;
protected DOTweenPath doTweenPath;
[SerializeField][ReadOnly][FoldoutGroup("状态")]
protected bool inPath = true;
/// <summary>
/// 现在正在执行的动画,在受击中断的时候用
/// </summary>
private Tween tweenNow;
// _____ _ _ ____ _
// / ____| | | | _ \ | |
// | | __ _| | | |_) | __ _ ___| | __
// | | / _` | | | _ < / _` |/ __| |/ /
// | |___| (_| | | | |_) | (_| | (__| <
// \_____\__,_|_|_|____/ \__,_|\___|_|\_\
void Start(){Init();}
// _ _ _
// | \ | | | |
// | \| | ___ _ __ _ __ ___ __ _| |
// | . ` |/ _ \| '__| '_ ` _ \ / _` | |
// | |\ | (_) | | | | | | | | (_| | |
// |_| \_|\___/|_| |_| |_| |_|\__,_|_|
protected void Init(){
//生命值初始化为满
HPLeft = HP;
//Get插件
doTweenPath = GetComponent<DOTweenPath>();
m_rigidbody = GetComponent<Rigidbody2D>();
sourcePosition = transform.position;
//初始话目前播放的Tween动画为巡逻
tweenNow = doTweenPath.tween;
}
/// <summary>
/// 协程用,删除自己这个游戏物体
/// </summary>
protected void Dead(){Destroy(gameObject);}
/// <summary>
/// 被击飞的击飞效果处理
/// </summary>
/// <param name="dir">被击方向</param>
public void BeHitToFly(int dir){
m_rigidbody.velocity += new Vector2( //给予自身一个
-1 * dir * hitToflyParameter.x,//X方向为力度系数乘以受击方向
hitToflyParameter.y//Y方向为力度系数
//的绝对的速度
);
}
// ______ _
// | ____| | |
// | |____ _____ _ __ | |_
// | __\ \ / / _ \ '_ \| __|
// | |___\ V / __/ | | | |_
// |______\_/ \___|_| |_|\__|
protected override void OnTouchThePlayer(MyPlayer player){
//告诉玩家,你被攻击了
player.OnBeHit(ATK,
((transform.position.x -
player.transform.position.x)
> 0) ? 1 : -1);
> 0) ? 1 : -1);//通过自身位置和玩家位置的比较来返回玩家本次的受击方向
}
protected override void OnBeHit(MyPlayer.AtkMethod hitMethod, int hitDir){
//结束当前动画
tweenNow.Pause();
//让自己被击飞
BeHitToFly(hitDir);
//修改标志表示自己当前不在Path中
inPath = false;
//结算生命值
HPLeft -= MyPlayer.atkMethodMagnification[hitMethod];
//看下死了没
//死了就记录下死亡时候的面部朝向用来做死亡翻滚效果然后再Call一下死亡事件
if(CheckDead()) {deadDir = hitDir;OnDead();}
}
protected override void OnRetouchedTheGround(){
if(!inPath){//如果此时怪物没在巡逻且着地了,说明时被击飞然后着地了
//新建一个动画,让怪物回到初始记录位置
Tween tween = transform.DOMove(sourcePosition,
Mathf.Abs(sourcePosition.x - transform.position.x) / speed,
false);
//设置该动画插值方式为线性
tween.SetEase(Ease.Linear);
//更改记录的此时正在执行的动画
tweenNow = tween;
//写一个委托,插入这个新动画的结束事件
TweenCallback myCallBack = () =>
//结束说明回到了初始点,此时让怪物重新开始巡逻,同时更改记录中的正在执行的动画为巡逻
{doTweenPath.DORestart(); tweenNow = doTweenPath.tween;};
//插入写的委托
tween.OnComplete(myCallBack);
//标记自身重新回到巡逻动画
inPath = true;
//矫正一下faceDir的问题
transform.rotation = Quaternion.
Euler
(transform.rotation.x,
((sourcePosition.x - transform.position.x > 0) ? 0:-180),
transform.rotation.z);
}
}
protected override void OnDead()
{
//标记当前状态为死亡
state = State.dead;
//加一个扭矩,营造死亡的效果
m_rigidbody.AddTorque(Random.Range(deadRotationRangeMin,deadRotationRangeMax) * deadDir);
//关掉自己的碰撞体
GetComponent<BoxCollider2D>().enabled = false;
//两秒后自己毁灭
Invoke("Dead",2f);
}
}