322 lines
9.3 KiB
C#
322 lines
9.3 KiB
C#
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using DG.Tweening;
|
|
using DragonLi.Core;
|
|
using DragonLi.Frame;
|
|
using UnityEngine;
|
|
|
|
public class Leviathan : Enemy
|
|
{
|
|
public float oneAttackInterval;
|
|
public GameObject player;
|
|
public Transform[] enemyPos;
|
|
|
|
public GameObject bigXl;//大招蓄力特效
|
|
public GameObject mzObj;//瞄准特效
|
|
public GameObject damagableObj;//受伤特效
|
|
|
|
private bool _startAttack;
|
|
private bool _isAttacking;
|
|
|
|
public int attackMode;
|
|
public override void Init()
|
|
{
|
|
base.Init();
|
|
|
|
bigXl.SetActive(false);
|
|
mzObj.SetActive(false);
|
|
damagableObj.SetActive(false);
|
|
player = GameManager.Ins.player;
|
|
foreach (var item in components)
|
|
{
|
|
item.Stop();
|
|
}
|
|
components[^1].boxCollider.enabled = false;
|
|
bloodSlider.gameObject.SetActive(false);
|
|
enemyState = EnemyState.Show;
|
|
attackMode = 0;
|
|
}
|
|
|
|
public override void Show()
|
|
{
|
|
base.Show();
|
|
isAttack = false;
|
|
isShield = true;
|
|
_isShow = true;
|
|
AnimatorComponent.SetFloat("speedf",1);
|
|
if (GameInit.Ins.gamePlace == GamePlace.HangZhouLongHuTianJie)
|
|
{
|
|
transform.DOMoveX(24f, 4).OnComplete(() =>
|
|
{
|
|
Both();
|
|
});
|
|
}
|
|
else if(GameInit.Ins.gamePlace==GamePlace.LiaoningAnShan)
|
|
{
|
|
Both();
|
|
}
|
|
else if(GameInit.Ins.gamePlace==GamePlace.Yangzhou_Hanjiang_Tansuozhongxin)
|
|
{
|
|
transform.DOMoveZ(-8f, 2).OnComplete(() =>
|
|
{
|
|
Both();
|
|
});
|
|
}
|
|
else if(GameInit.Ins.gamePlace==GamePlace.Guangzhou_Panyv_Zhanting)
|
|
{
|
|
transform.DOMoveX(17.5f, 2).OnComplete(() =>
|
|
{
|
|
Both();
|
|
});
|
|
}
|
|
else if(GameInit.Ins.gamePlace==GamePlace.Anhui_Wuhu_Guanwei)
|
|
{
|
|
transform.DOMoveZ(-8.5f, 2).OnComplete(() =>
|
|
{
|
|
Both();
|
|
});
|
|
}
|
|
else if(GameInit.Ins.gamePlace==GamePlace.Zhejiang_Jinhua_KeJiGuan)
|
|
{
|
|
transform.DOMoveZ(18f, 2).OnComplete(() =>
|
|
{
|
|
Both();
|
|
});
|
|
}
|
|
else
|
|
{
|
|
transform.DOMoveZ(-15f, 2).OnComplete(() =>
|
|
{
|
|
Both();
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
public void Both()
|
|
{
|
|
AnimatorComponent.SetFloat("speedf",0);
|
|
AnimatorComponent.SetBool("isBoth",true);
|
|
GameInit.Ins.PlayAudio("2.23漂浮",transform,false);
|
|
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
|
|
{
|
|
AnimatorComponent.SetBool("isBoth",false);
|
|
isAttack = true;
|
|
bloodSlider.gameObject.SetActive(true);
|
|
isShield = false;
|
|
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
|
|
{
|
|
_isShow = false;
|
|
},6f);
|
|
},1f);
|
|
}
|
|
public override void Attack()
|
|
{
|
|
base.Attack();
|
|
if (!_isAttacking)
|
|
{
|
|
_isAttacking = true;
|
|
StartCoroutine(ShotAttack());
|
|
}
|
|
}
|
|
|
|
public override void OneAttackMode()
|
|
{
|
|
base.OneAttackMode();
|
|
StartCoroutine(OneShotAttack());
|
|
}
|
|
|
|
public override void Show2()
|
|
{
|
|
base.Show2();
|
|
StopAllCoroutines();
|
|
attackMode = 3;
|
|
}
|
|
|
|
public override void TwoAttackMode()
|
|
{
|
|
base.TwoAttackMode();
|
|
ShowEnemy();
|
|
}
|
|
|
|
public void ShowEnemy()
|
|
{
|
|
for (int i = 0; i < enemyPos.Length; i++)
|
|
{
|
|
Vector3 curEnemyPos=new Vector3(enemyPos[i].position.x,0,enemyPos[i].position.z);
|
|
GameManager.Ins.CreateCallEnemyEffect(curEnemyPos);
|
|
}
|
|
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
|
|
{
|
|
for (int i = 0; i < enemyPos.Length; i++)
|
|
{
|
|
Vector3 curEnemyPos=new Vector3(enemyPos[i].position.x,0,enemyPos[i].position.z);
|
|
GameManager.Ins.CreateEnemy(4,curEnemyPos,Vector3.zero,false);
|
|
}
|
|
},2f);
|
|
}
|
|
|
|
public override void StartQteAttack()
|
|
{
|
|
bigXl.SetActive(true);
|
|
mzObj.SetActive(true);
|
|
components[^1].StatQteAttack();
|
|
attackMode = 4;
|
|
// shieldObj.SetActive(true);
|
|
// isShield = true;
|
|
}
|
|
|
|
public GameObject qteAttackPre;
|
|
public override void BossQteAttack()
|
|
{
|
|
base.BossQteAttack();
|
|
//StartCoroutine(components[^1].FireQteMissiles());
|
|
StartCoroutine(LwtQteAttack());
|
|
}
|
|
|
|
IEnumerator LwtQteAttack()
|
|
{
|
|
qteAttackPre.SetActive(true);
|
|
AnimatorComponent.SetBool("isCastEnd",true);
|
|
userSillIng = true;
|
|
GameInit.Ins.PlayAudio("2.21激光",transform,false);
|
|
yield return new WaitForSeconds(1f);
|
|
GameInit.Ins.self.ApplyDamage(GameInit.Ins.self.maxHp/2f,null,transform);
|
|
yield return new WaitForSeconds(2.5f);
|
|
qteAttackPre.SetActive(false);
|
|
userSillIng = false;
|
|
}
|
|
|
|
public override void StopQteAttack()
|
|
{
|
|
base.StopQteAttack();
|
|
AnimatorComponent.SetBool("isCastEnd",false);
|
|
bigXl.SetActive(false);
|
|
mzObj.SetActive(false);
|
|
StopCoroutine(components[^1].FireQteMissiles());
|
|
components[^1].StopQteAttack();
|
|
shieldObj.SetActive(false);
|
|
isShield = false;
|
|
attackMode = 0;
|
|
}
|
|
|
|
[Header("抛物线参数")]
|
|
public float sideOffset = 4f; // 玩家左右目标点的水平偏移
|
|
protected IEnumerator OneShotAttack()
|
|
{
|
|
attackMode = 2;
|
|
|
|
yield return new WaitForSeconds(2f);
|
|
// 获取玩家当前位置
|
|
Vector3 center = player.transform.position;
|
|
Vector3 left = center - GameManager.Ins.player.transform.right * sideOffset;
|
|
Vector3 right = center + GameManager.Ins.player.transform.right * sideOffset;
|
|
|
|
Vector3[] targets = { center, left, right };
|
|
for (int i = 0; i < targets.Length; i++)
|
|
{
|
|
components[i+4].FireThreeMissiles(components[i].showPos.position, targets[i]);
|
|
}
|
|
yield return new WaitForSeconds(1f);
|
|
userSillIng = false;
|
|
}
|
|
|
|
[Header("配置参数")]
|
|
public float shotRadius = 5f; // 落点半径
|
|
public float shotInterval = 1f; // 每轮中两次发射的间隔
|
|
public float roundInterval = 3f; // 两轮之间的间隔
|
|
private IEnumerator ShotAttack()
|
|
{
|
|
while (_isAttacking)
|
|
{
|
|
// 获取玩家当前位置
|
|
Vector3 center = player.transform.position;
|
|
attackMode = 1;
|
|
// 两轮射击
|
|
for (int round = 0; round < 2; round++)
|
|
{
|
|
// 为本轮生成四个不重合的随机目标点
|
|
List<Vector3> targets = GenerateTargetPoints(center, shotRadius, 4);
|
|
|
|
// 遍历每个发射点
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
components[i].ShootMissile(components[i].showPos.position, targets[i]);
|
|
}
|
|
|
|
yield return new WaitForSeconds(shotInterval);
|
|
}
|
|
attackMode = 0;
|
|
yield return new WaitForSeconds(roundInterval);
|
|
}
|
|
}
|
|
|
|
// 生成 count 个均匀分布、且带一定随机偏移的不重合圆周点
|
|
private List<Vector3> GenerateTargetPoints(Vector3 center, float radius, int count)
|
|
{
|
|
List<Vector3> pts = new List<Vector3>(count);
|
|
float step = 360f / count;
|
|
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
// 在每个扇区内随机一个角度
|
|
float angle = i * step + Random.Range(-step * 0.3f, step * 0.3f);
|
|
float rad = angle * Mathf.Deg2Rad;
|
|
Vector3 offset = new Vector3(Mathf.Cos(rad), 0, Mathf.Sin(rad)) * radius;
|
|
pts.Add(center + offset);
|
|
}
|
|
return pts;
|
|
}
|
|
|
|
public override void StopAttack()
|
|
{
|
|
base.StopAttack();
|
|
attackMode = 0;
|
|
StopAllCoroutines();
|
|
_isAttacking = false;
|
|
}
|
|
|
|
public override void ChangeHp(float value, object info, Transform _sender)
|
|
{
|
|
base.ChangeHp(value, info, _sender);
|
|
damagableObj.SetActive(health/maxHealth<=0.5f);
|
|
}
|
|
|
|
public override void Dead()
|
|
{
|
|
if(!isDead)
|
|
GameManager.Ins.CurLevelWin();
|
|
base.Dead();
|
|
}
|
|
|
|
private bool _isShow;
|
|
private float enemyTime=45f;
|
|
private float curEnemyTime;
|
|
public override void Update()
|
|
{
|
|
base.Update();
|
|
AnimatorComponent.SetInteger("attackMode", attackMode);
|
|
if (_isShow) return;
|
|
|
|
// 平滑朝向玩家
|
|
Vector3 targetDir = GameManager.Ins.player.transform.position - transform.position;
|
|
targetDir.y = 0f;
|
|
|
|
if (targetDir != Vector3.zero)
|
|
{
|
|
Quaternion targetRotation = Quaternion.LookRotation(targetDir);
|
|
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 2f);
|
|
}
|
|
|
|
curEnemyTime-=Time.deltaTime;
|
|
if (curEnemyTime <= 0)
|
|
{
|
|
if(GameManager.Ins.GetCurEnemyListCount()<=8)
|
|
ShowEnemy();
|
|
curEnemyTime = enemyTime;
|
|
}
|
|
}
|
|
|
|
}
|