
1.编写留言系统 (1.当玩家无Catch的时候,记录长按Y的时间,若时间大于两秒,呼唤UI,触发相应事件 *.编写撰写留言板逻辑 (*.清空操作地图 (1.呼出留言板UI (2.当按下确认键,确认建立一个本地留言板,并初始化该本地留言板,恢复操作地图 (3.将留言板数据传向云端 *.编写留言板逻辑 (1.内含BoardInfo内的信息 (2.继承于可交互物体 (3.当交互,呼出留言板UI,显示内容、UID等信息 (4.当按下返回键,关闭UI *.编写拉取留言板系统 (1.加在开幕演出中,开幕时呼叫sql上的脚本,拉取若干条留言板 (2.在场景内创建留言板,并初始化信息 *.替换和实装美术素材,增加部分动画 1.增加村内上树动画 2.更新村场景,使得玩家可以走到村下 3.制作以撒闪电攻击动画 4.制作以撒冲撞攻击动画 5.制作以撒雕像碎裂动画 6.贴上对话框 7.制作以撒闪电攻击动画 8.制作村民和贵族的待机角色 9.制作特洛伊木马死亡动画 10.制作特洛伊木马的喷射动画 *优化和修复 1.修复佛教前置关掉怪陷阱有时不会触发的问题 2.重做渲染层,避免出现覆盖问题 3.修复玩家会卡在村里桥上的问题 4.解决了屎山代码的warming问题 5.删除了子弹时间,效果太差 建议: 1.给击中添加一些效果,目前还是打击感太弱 2.目前木马死后,灰尘不会消失 *.至此,留言系统全部完成 下班
343 lines
12 KiB
C#
343 lines
12 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using Sirenix.OdinInspector;
|
|
using DG.Tweening;
|
|
|
|
/// <summary>
|
|
/// 木马类
|
|
/// </summary>
|
|
public class TrojanHorse : Enemy, Boomer.I_CanBeBoomedObj
|
|
{
|
|
// _____ _ _ _
|
|
// | __ \ | | | (_)
|
|
// | |__) | _| |__ | |_ ___
|
|
// | ___/ | | | '_ \| | |/ __|
|
|
// | | | |_| | |_) | | | (__
|
|
// |_| \__,_|_.__/|_|_|\___|
|
|
|
|
/// <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;
|
|
/// <summary>
|
|
/// 炸弹的预制体,用来喷射的那种
|
|
/// </summary>
|
|
[Header("炸弹的预制体,用来喷射的那种")][FoldoutGroup("预制体")]
|
|
public GameObject sprayBoomer;
|
|
/// <summary>
|
|
/// 喷射炸弹的时间间隔
|
|
/// </summary>
|
|
[Header("喷射炸弹的时间间隔")][FoldoutGroup("木马")]
|
|
public float sprayBoomerTime;
|
|
/// <summary>
|
|
/// 喷射炸弹的方向
|
|
/// </summary>
|
|
[Header("喷射炸弹的方向")][FoldoutGroup("木马")]
|
|
public Vector2 sprayBoomerDir;
|
|
/// <summary>
|
|
/// 喷射炸弹的力度倍数
|
|
/// </summary>
|
|
[Header("喷射炸弹的力度倍数")][FoldoutGroup("木马")]
|
|
public float sprayBoomerMultiple;
|
|
/// <summary>
|
|
/// 召唤炸弹攻击,炸弹从天而降的初速度
|
|
/// </summary>
|
|
[Header("召唤炸弹攻击,炸弹从天而降的初速度")][FoldoutGroup("木马")]
|
|
public Vector2 callBoomStartVelocity;
|
|
|
|
// _____ _ _
|
|
// | __ \ (_) | |
|
|
// | |__) | __ ___ ____ _| |_ ___
|
|
// | ___/ '__| \ \ / / _` | __/ _ \
|
|
// | | | | | |\ V / (_| | || __/
|
|
// |_| |_| |_| \_/ \__,_|\__\___|
|
|
|
|
/// <summary>
|
|
/// 返回类型为协程、参数为空的委托类型
|
|
/// </summary>
|
|
private delegate IEnumerator Action();
|
|
/// <summary>
|
|
/// 开关,控制此时木马是否在移动
|
|
/// </summary>
|
|
[SerializeField][Header("此时木马是否在移动")][FoldoutGroup("状态")][ReadOnly]
|
|
public bool isMove = false;
|
|
/// <summary>
|
|
/// 召唤伊斯兰小怪的初始位置
|
|
/// </summary>
|
|
private Transform callYiSiLanPosition;
|
|
/// <summary>
|
|
/// 喷射炸弹的起点
|
|
/// </summary>
|
|
private Transform sprayBoomerPosition;
|
|
/// <summary>
|
|
/// 召唤炸弹攻击的最左边
|
|
/// </summary>
|
|
private Transform callBoomerPositonLeft;
|
|
/// <summary>
|
|
/// 召唤炸弹攻击的最右边
|
|
/// </summary>
|
|
private Transform callBoomerPositonRight;
|
|
/// <summary>
|
|
/// 此时是否被打断?主要用来停止喷射攻击
|
|
/// </summary>
|
|
[Header("此时是否被打断")][SerializeField][FoldoutGroup("状态")][ReadOnly]
|
|
private bool wasInterupt = false;
|
|
|
|
// _____ _ _ ____ _
|
|
// / ____| | | | _ \ | |
|
|
// | | __ _| | | |_) | __ _ ___| | __
|
|
// | | / _` | | | _ < / _` |/ __| |/ /
|
|
// | |___| (_| | | | |_) | (_| | (__| <
|
|
// \_____\__,_|_|_|____/ \__,_|\___|_|\_\
|
|
|
|
void Start(){Init();}
|
|
|
|
void Update(){
|
|
//如果开关开着,则移动
|
|
if(isMove)
|
|
Move();
|
|
}
|
|
|
|
// _ _ _
|
|
// | \ | | | |
|
|
// | \| | ___ _ __ _ __ ___ __ _| |
|
|
// | . ` |/ _ \| '__| '_ ` _ \ / _` | |
|
|
// | |\ | (_) | | | | | | | | (_| | |
|
|
// |_| \_|\___/|_| |_| |_| |_|\__,_|_|
|
|
private void Init(){
|
|
//初始化生命值
|
|
HPLeft = HP;
|
|
//找到必须的组件和物体
|
|
callYiSiLanPosition = transform.Find("小怪召唤点");
|
|
sprayBoomerPosition = transform.Find("喷射炸弹点");
|
|
callBoomerPositonLeft = transform.Find("召唤炸弹攻击最左点");
|
|
callBoomerPositonRight = transform.Find("召唤炸弹攻击最右点");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 执行一次攻击
|
|
/// </summary>
|
|
private IEnumerator StartAATK(){
|
|
//等待攻击间隔
|
|
yield return new WaitForSeconds(timeBetweenAttacks);
|
|
//决定行动
|
|
Action action = DecideAAction();
|
|
//开始行动
|
|
StartCoroutine(action());
|
|
}
|
|
|
|
/// <summary>
|
|
/// 决定行动的函数
|
|
/// </summary>
|
|
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 SprayBoomer;
|
|
}
|
|
|
|
/// <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(){
|
|
//开始喷射动画
|
|
GetComponent<Animator>().SetBool("isSpray",true);
|
|
yield return new WaitForSeconds(1f);
|
|
Debug.Log("正在使用:喷射炸弹");
|
|
//循环若干次(这里先硬编码成3次)
|
|
for(int i = 0; i < 3; i++){
|
|
if(wasInterupt) break;
|
|
//实例化预制体
|
|
Boomer boomer = Instantiate(
|
|
sprayBoomer,
|
|
sprayBoomerPosition.position,
|
|
Quaternion.identity
|
|
).GetComponent<Boomer>();
|
|
//初始化喷出的炸弹
|
|
//给予初始的速度
|
|
yield return new WaitForEndOfFrame();
|
|
boomer.m_rigidbody.velocity = sprayBoomerDir * (i + 1) * sprayBoomerMultiple;
|
|
boomer.isThisCanBeReturned = true;
|
|
boomer.GetComponent<ParticleSystem>().Play();
|
|
//给予炸弹扭矩
|
|
boomer.m_rigidbody.angularVelocity = 500f;
|
|
//等待喷射炸弹时间间隔
|
|
yield return new WaitForSeconds(sprayBoomerTime);
|
|
}
|
|
//结束喷射动画
|
|
yield return new WaitForSeconds(2f);
|
|
GetComponent<Animator>().SetBool("isSpray",false);
|
|
wasInterupt = false;
|
|
ATKEnd();
|
|
}
|
|
/// <summary>
|
|
/// 攻击方式:召唤炸弹💣
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private IEnumerator CallBoomer(){
|
|
Debug.Log("正在使用:召唤炸弹");
|
|
//循环若干次(这里先硬编码成3次)
|
|
for(int i = 0; i < 3; i++){
|
|
//实例化预制体
|
|
Boomer boomer = Instantiate(
|
|
sprayBoomer,
|
|
new Vector3(
|
|
//x取余范围内随机
|
|
Random.Range(callBoomerPositonLeft.position.x,
|
|
callBoomerPositonRight.position.x),
|
|
//yz随起点
|
|
callBoomerPositonLeft.position.y,
|
|
callBoomerPositonLeft.position.z
|
|
),
|
|
Quaternion.identity
|
|
).GetComponent<Boomer>();
|
|
//初始化喷出的炸弹
|
|
//先等待本帧结束,创建炸弹完毕
|
|
yield return new WaitForEndOfFrame();
|
|
//给予初始的速度
|
|
boomer.m_rigidbody.velocity = callBoomStartVelocity;
|
|
//修改炸弹的落地爆炸时间
|
|
boomer.landBoomTime = 1f;
|
|
//等待喷射炸弹时间间隔
|
|
yield return new WaitForSeconds(sprayBoomerTime);
|
|
}
|
|
ATKEnd();
|
|
}
|
|
/// <summary>
|
|
/// 木马不停右移的函数,每帧调用一次,有开关控制
|
|
/// </summary>
|
|
private void Move(){
|
|
//给自身位置加上向右的速度
|
|
transform.position += new Vector3(
|
|
speed * Time.deltaTime,0,0
|
|
);
|
|
}
|
|
|
|
// ______ _
|
|
// | ____| | |
|
|
// | |____ _____ _ __ | |_
|
|
// | __\ \ / / _ \ '_ \| __|
|
|
// | |___\ V / __/ | | | |_
|
|
// |______\_/ \___|_| |_|\__|
|
|
|
|
/// <summary>
|
|
/// 当玩家进入监视范围(前期调试,后期可能需要安排演出)
|
|
/// </summary>
|
|
/// <param name="target"></param>
|
|
public override void OnFindThePlayer(Transform target){
|
|
if(state == State.wander){
|
|
//修改状态为发现玩家
|
|
state = State.atk;
|
|
//开始攻击
|
|
StartCoroutine(StartAATK());
|
|
//开始屏幕震动
|
|
FindObjectOfType<VibrationManager>().HorseShakeScream();
|
|
//开始向右移动
|
|
isMove = true;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 攻击结束的时候触发,重新开始新一轮攻击
|
|
/// </summary>
|
|
public void ATKEnd(){
|
|
if(state == State.atk) StartCoroutine(StartAATK());
|
|
}
|
|
|
|
protected override void OnTouchThePlayer(MyPlayer player){
|
|
//
|
|
Debug.Log("创到玩家了");
|
|
//
|
|
//当创到玩家,让玩家受伤
|
|
//告诉玩家,你被攻击了
|
|
player.OnBeHit(ATK,
|
|
((transform.position.x -
|
|
player.transform.position.x)
|
|
> 0) ? 1 : -1);//通过自身位置和玩家位置的比较来返回玩家本次的受击方向
|
|
}
|
|
|
|
public override void OnDead(){
|
|
//播放死亡动画
|
|
GetComponent<Animator>().SetBool("isDead",true);
|
|
Debug.Log("啊我死了");
|
|
isMove = false;
|
|
state = State.dead;
|
|
FindObjectOfType<VibrationManager>().inHorseStage = false;
|
|
FindObjectOfType<VibrationManager>().StopHorseShakeScream();
|
|
FindObjectOfType<Transfer>().GetComponent<BoxCollider2D>().enabled = true;
|
|
//上传玩家进度
|
|
FindObjectOfType<PlayerInfo>().rate = (int) MyPlayer.Progress.过伊;
|
|
FindObjectOfType<PlayerInfo>().UpdatePlayerInfo();
|
|
}
|
|
|
|
public override void OnBeHit(MyPlayer.AtkMethod hitMethod,int hitDir){
|
|
//结算生命值
|
|
HPLeft -= MyPlayer.atkMethodMagnification[hitMethod];
|
|
}
|
|
|
|
|
|
|
|
|
|
// _____ _ __
|
|
// |_ _| | | / _|
|
|
// | | _ __ | |_ ___ _ __| |_ __ _ ___ ___
|
|
// | | | '_ \| __/ _ \ '__| _/ _` |/ __/ _ \
|
|
// _| |_| | | | || __/ | | || (_| | (_| __/
|
|
// |_____|_| |_|\__\___|_| |_| \__,_|\___\___|
|
|
|
|
public void BeBoomed(float atk, int dir, Boomer boomer){
|
|
if(boomer.isThisCanBeReturned){
|
|
OnBeHit(MyPlayer.AtkMethod.反弹炸弹,dir);
|
|
wasInterupt = true;
|
|
if(CheckDead()) OnDead();
|
|
}
|
|
}
|
|
|
|
public Transform ObjTransform(){return transform;}
|
|
|
|
}
|