
1.优化一些手感和战斗效果 (1.走动时轻微震动手柄(通过动画Event实现,以匹配脚步) (2.被打的时候剧烈震动手柄,中幅度震动屏幕 (3.锤子击中的时候中幅度震动手柄 (*.完善震动管理员逻辑以解决震动的覆盖问题 (4.发射镰刀的时候轻微震动手柄,轻微震动屏幕 (5.为发射镰刀添加动画 (6.为锤子的空挥添加轻微震动 2.创建木马BossStageTest场景 (1.创建一些必要的元素 (2.创建木马逻辑组件 3.编写木马逻辑 (1.继承自Enemy (2.参考地藏逻辑,做出三种攻击的协程 (3.让木马动起来,始终向右 (4.让相机上下轻微震动起来 (5.让手柄一直震动,模拟大型物体的感觉 (6.将空气墙绑在马身上 (7.编写召唤小怪的攻击方式 (*:当触发召唤小怪的攻击,在视野右边,每隔若干随机时间生成一个伊斯兰,生成到指定数量后,发送攻击结束信号。 4.编写地面逻辑 (1.让地面能够无限向右平铺 (*:在地面的末端安排一个触发器,当木马完全离开触发器,使地面移动至地面宽度两倍的右边 (2.将光源绑在地面,这样不会出现远了会失去光照的问题 *:目前伊斯兰小怪在BossStage有一些Bug,明天再修吧
186 lines
5.6 KiB
C#
186 lines
5.6 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using Sirenix.OdinInspector;
|
|
using DG.Tweening;
|
|
|
|
/// <summary>
|
|
/// 木马类
|
|
/// </summary>
|
|
public class TrojanHorse : Enemy
|
|
{
|
|
// _____ _ _ _
|
|
// | __ \ | | | (_)
|
|
// | |__) | _| |__ | |_ ___
|
|
// | ___/ | | | '_ \| | |/ __|
|
|
// | | | |_| | |_) | | | (__
|
|
// |_| \__,_|_.__/|_|_|\___|
|
|
|
|
/// <summary>
|
|
/// 攻击之间的间隔时间
|
|
/// </summary>
|
|
[Header("攻击之间的间隔时间")][FoldoutGroup("木马")]
|
|
public float timeBetweenAttacks;
|
|
/// <summary>
|
|
/// 伊斯兰小怪的预制体
|
|
/// </summary>
|
|
[Header("伊斯兰小怪的预制体")][FoldoutGroup("预制体")]
|
|
public GameObject yiSiLan;
|
|
/// <summary>
|
|
/// 召唤小怪攻击中,生成小怪之间间隔的最短时间
|
|
/// </summary>
|
|
[Header("召唤小怪攻击中,生成小怪之间间隔的最短时间")][FoldoutGroup("木马")]
|
|
public float yiSiLanMinTime;
|
|
// <summary>
|
|
/// 召唤小怪攻击中,生成小怪之间间隔的最长时间
|
|
/// </summary>
|
|
[Header("召唤小怪攻击中,生成小怪之间间隔的最长时间")][FoldoutGroup("木马")]
|
|
public float yiSiLanMaxTime;
|
|
|
|
// _____ _ _
|
|
// | __ \ (_) | |
|
|
// | |__) | __ ___ ____ _| |_ ___
|
|
// | ___/ '__| \ \ / / _` | __/ _ \
|
|
// | | | | | |\ V / (_| | || __/
|
|
// |_| |_| |_| \_/ \__,_|\__\___|
|
|
|
|
/// <summary>
|
|
/// 返回类型为协程、参数为空的委托类型
|
|
/// </summary>
|
|
private delegate IEnumerator Action();
|
|
/// <summary>
|
|
/// 开关,控制此时木马是否在移动
|
|
/// </summary>
|
|
[SerializeField][Header("此时木马是否在移动")][FoldoutGroup("状态")]
|
|
private bool isMove = false;
|
|
/// <summary>
|
|
/// 召唤伊斯兰小怪的初始位置
|
|
/// </summary>
|
|
private Transform callYiSiLanPosition;
|
|
|
|
// _____ _ _ ____ _
|
|
// / ____| | | | _ \ | |
|
|
// | | __ _| | | |_) | __ _ ___| | __
|
|
// | | / _` | | | _ < / _` |/ __| |/ /
|
|
// | |___| (_| | | | |_) | (_| | (__| <
|
|
// \_____\__,_|_|_|____/ \__,_|\___|_|\_\
|
|
|
|
void Start(){Init();}
|
|
|
|
void Update(){
|
|
if(isMove)
|
|
Move();
|
|
}
|
|
|
|
// _ _ _
|
|
// | \ | | | |
|
|
// | \| | ___ _ __ _ __ ___ __ _| |
|
|
// | . ` |/ _ \| '__| '_ ` _ \ / _` | |
|
|
// | |\ | (_) | | | | | | | | (_| | |
|
|
// |_| \_|\___/|_| |_| |_| |_|\__,_|_|
|
|
private void Init(){
|
|
callYiSiLanPosition = transform.Find("小怪召唤点");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 执行一次攻击
|
|
/// </summary>
|
|
private new IEnumerator ATK(){
|
|
//等待攻击间隔
|
|
yield return new WaitForSeconds(timeBetweenAttacks);
|
|
//决定行动
|
|
Action action = DecideAAction();
|
|
StartCoroutine(action());
|
|
}
|
|
|
|
private Action DecideAAction(){
|
|
Action action;
|
|
///从0、1、2中随机生成一种
|
|
int r = Random.Range(0,3);
|
|
if(r == 0)
|
|
action = CallYiSiLan;
|
|
else if(r == 1)
|
|
action = SprayBoomer;
|
|
else
|
|
action = CallBoomer;
|
|
return CallYiSiLan;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 攻击方式:召唤小怪
|
|
/// </summary>
|
|
private IEnumerator CallYiSiLan(){
|
|
Debug.Log("正在使用:召唤伊斯兰");
|
|
//循环若干次(这里先硬编码成3次)
|
|
for(int i = 0; i < 3; i++){
|
|
//实例化预制体
|
|
YiSiLan yi = Instantiate(
|
|
yiSiLan,
|
|
callYiSiLanPosition.position,
|
|
Quaternion.identity
|
|
).GetComponent<YiSiLan>();
|
|
//等待范围内的随机时间
|
|
yield return new WaitForSeconds(
|
|
Random.Range(yiSiLanMinTime,yiSiLanMaxTime)
|
|
);
|
|
}
|
|
ATKEnd();
|
|
}
|
|
/// <summary>
|
|
/// 攻击方式:喷射炸弹💣
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private IEnumerator SprayBoomer(){
|
|
yield return new WaitForEndOfFrame();
|
|
Debug.Log("正在使用:喷射炸弹");
|
|
ATKEnd();
|
|
}
|
|
/// <summary>
|
|
/// 攻击方式:召唤炸弹💣
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private IEnumerator CallBoomer(){
|
|
yield return new WaitForEndOfFrame();
|
|
Debug.Log("正在使用:召唤炸弹");
|
|
ATKEnd();
|
|
}
|
|
/// <summary>
|
|
/// 木马不停右移的函数,每帧调用一次,有开关控制
|
|
/// </summary>
|
|
private void Move(){
|
|
//给自身位置加上向右的速度
|
|
transform.position += new Vector3(
|
|
speed * Time.deltaTime,0,0
|
|
);
|
|
}
|
|
|
|
// ______ _
|
|
// | ____| | |
|
|
// | |____ _____ _ __ | |_
|
|
// | __\ \ / / _ \ '_ \| __|
|
|
// | |___\ V / __/ | | | |_
|
|
// |______\_/ \___|_| |_|\__|
|
|
|
|
/// <summary>
|
|
/// 当玩家进入监视范围(前期调试,后期可能需要安排演出)
|
|
/// </summary>
|
|
/// <param name="target"></param>
|
|
protected override void OnFindThePlayer(Transform target){
|
|
if(state == State.wander){
|
|
//修改状态为发现玩家
|
|
state = State.atk;
|
|
//开始攻击
|
|
StartCoroutine(ATK());
|
|
//开始屏幕震动
|
|
FindObjectOfType<VibrationManager>().HorseShake();
|
|
//开始向右移动
|
|
isMove = true;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 攻击结束的时候触发,重新开始新一轮攻击
|
|
/// </summary>
|
|
public void ATKEnd(){StartCoroutine(ATK());}
|
|
}
|