345 lines
11 KiB
C#
345 lines
11 KiB
C#
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using DG.Tweening;
|
||
using DragonLi.Core;
|
||
using DragonLi.Frame;
|
||
using UnityEngine;
|
||
|
||
public class MachineDragon : Enemy
|
||
{
|
||
public GameObject player;
|
||
public Transform[] enemyPos;
|
||
|
||
public GameObject bigXl; // 大招蓄力特效
|
||
public GameObject mzObj; // 瞄准特效
|
||
public GameObject damagableObj; // 受伤特效
|
||
|
||
public GameObject attack2Pre;
|
||
|
||
private bool _startAttack;
|
||
private bool _isAttacking;
|
||
private bool _isShow;
|
||
|
||
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 StopAttack()
|
||
{
|
||
base.StopAttack();
|
||
attackMode = 0;
|
||
components[0].Stop();
|
||
components[1].Stop();
|
||
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 Show()
|
||
{
|
||
base.Show();
|
||
isAttack = false;
|
||
isShield = true;
|
||
_isShow = true;
|
||
AnimatorComponent.SetFloat("speedf", 1);
|
||
GameInit.Ins.PlayAudio("2.24走动",transform,false);
|
||
float endValue = 10;
|
||
if (GameInit.Ins.gamePlace == GamePlace.HangZhouLongHuTianJie)
|
||
endValue = 20.5f;
|
||
if (GameInit.Ins.gamePlace == GamePlace.Yangzhou_Hanjiang_Tansuozhongxin)
|
||
endValue = -6.5f;
|
||
if(GameInit.Ins.gamePlace== GamePlace.Yangzhou_Hanjiang_TansuoZhongxin_wai||GameInit.Ins.gamePlace ==GamePlace.Zhejiang_Jinhua_KeJiGuan)
|
||
endValue = -1f;
|
||
if (GameInit.Ins.gamePlace == GamePlace.Guangzhou_Panyv_Zhanting)
|
||
endValue = 3f;
|
||
if (GameInit.Ins.gamePlace == GamePlace.Anhui_Wuhu_Guanwei)
|
||
endValue = 0f;
|
||
if (GameInit.Ins.gamePlace == GamePlace.ShanDong_Langfang_QingzhouTaihuacheng)
|
||
endValue = -26f;
|
||
if (GameInit.Ins.gamePlace == GamePlace.Yangzhou_Hanjiang_TansuoZhongxin_wai
|
||
|| GameInit.Ins.gamePlace ==GamePlace.Zhejiang_Jinhua_KeJiGuan
|
||
|| GameInit.Ins.gamePlace ==GamePlace.Anhui_Wuhu_Guanwei
|
||
|| GameInit.Ins.gamePlace ==GamePlace.ShanDong_Langfang_QingzhouTaihuacheng
|
||
)
|
||
{
|
||
transform.DOMoveX(endValue, 4).OnComplete(() =>
|
||
{
|
||
Both();
|
||
});
|
||
}
|
||
else if(GameInit.Ins.gamePlace == GamePlace.Shandong_Jining_Shangchang)
|
||
{
|
||
transform.DOMove(new Vector3(12.12f,transform.position.y,4.6f), 4).OnComplete(() =>
|
||
{
|
||
Both();
|
||
});
|
||
}
|
||
else
|
||
{
|
||
transform.DOMoveZ(endValue, 4).OnComplete(() =>
|
||
{
|
||
Both();
|
||
});
|
||
}
|
||
}
|
||
|
||
public void Both()
|
||
{
|
||
AnimatorComponent.SetFloat("speedf", 0);
|
||
AnimatorComponent.SetBool("isBoth", true);
|
||
GameInit.Ins.PlayAudio("2.29咆哮",transform,true);
|
||
GameInit.Ins.PlayAudio("1.12",GameInit.Ins.self.transform,true);
|
||
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
|
||
{
|
||
AnimatorComponent.SetBool("isBoth", false);
|
||
isAttack = true;
|
||
bloodSlider.gameObject.SetActive(true);
|
||
isShield = false;
|
||
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
|
||
{
|
||
_isShow = false;
|
||
}, 1f);
|
||
}, 1f);
|
||
}
|
||
|
||
public override void Attack()
|
||
{
|
||
base.Attack();
|
||
if (!_isAttacking)
|
||
{
|
||
attackMode = 1;
|
||
_isAttacking = true;
|
||
components[0].Play();
|
||
components[1].Play();
|
||
}
|
||
}
|
||
|
||
public override void OneAttackMode()
|
||
{
|
||
base.OneAttackMode();
|
||
if (!isDashing)
|
||
{
|
||
StartCoroutine(DashRoutine());
|
||
}
|
||
}
|
||
|
||
public float dashSpeed = 10f; // 冲刺速度
|
||
public float overshootDistance = 2f; // 超过玩家的距离
|
||
private float hitRadius = 2f; // 检测玩家的半径
|
||
private bool isDashing = false;
|
||
private bool hasHitPlayer = false;
|
||
|
||
// 修改后的 DashRoutine:先冲到 endPos,再返回 startPos
|
||
private IEnumerator DashRoutine()
|
||
{
|
||
isDashing = true;
|
||
attack2Pre.SetActive(true);
|
||
attackMode = 2;
|
||
|
||
// 记录起始位置
|
||
Vector3 startPos = transform.position;
|
||
Vector3 playerPos = player.transform.position.ReflectVectorXOZ();
|
||
Vector3 dashDirection = (playerPos - startPos).normalized;
|
||
Vector3 endPos = playerPos + dashDirection * overshootDistance;
|
||
GameInit.Ins.PlayAudio("2.30冲刺",transform,false);
|
||
// —— 第一阶段:从 startPos 冲向 endPos ——
|
||
hasHitPlayer = false;
|
||
while (Vector3.Distance(transform.position, endPos) > 0.1f)
|
||
{
|
||
transform.position = Vector3.MoveTowards(transform.position, endPos, dashSpeed * Time.deltaTime);
|
||
transform.forward = Vector3.Lerp(transform.forward, dashDirection, Time.deltaTime * 10f);
|
||
|
||
if (!hasHitPlayer)
|
||
{
|
||
// 这里用 attack2Pre 作为碰撞检测中心,也可以直接用 transform.position
|
||
Collider[] hits = Physics.OverlapSphere(attack2Pre.transform.position, hitRadius, LayerMask.GetMask("Player"));
|
||
foreach (var hit in hits)
|
||
{
|
||
if (hit.CompareTag("Player"))
|
||
{
|
||
Debug.LogError("第一阶段:撞到了玩家,造成了伤害");
|
||
hit.GetComponent<IDamagable>()?.ApplyDamage(3000, null, attack2Pre.transform);
|
||
hasHitPlayer = true;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
yield return null;
|
||
}
|
||
|
||
transform.position = endPos;
|
||
hasHitPlayer = false; // 重置,允许第二阶段再撞一次
|
||
|
||
// —— 第二阶段:从 endPos 冲回 startPos ——
|
||
Vector3 returnDirection = (startPos - endPos).normalized;
|
||
GameInit.Ins.PlayAudio("2.30冲刺",transform,true);
|
||
while (Vector3.Distance(transform.position, startPos) > 0.1f)
|
||
{
|
||
transform.position = Vector3.MoveTowards(transform.position, startPos, dashSpeed * Time.deltaTime);
|
||
transform.forward = Vector3.Lerp(transform.forward, returnDirection, Time.deltaTime * 10f);
|
||
|
||
if (!hasHitPlayer)
|
||
{
|
||
Collider[] hits = Physics.OverlapSphere(attack2Pre.transform.position, hitRadius, LayerMask.GetMask("Player"));
|
||
foreach (var hit in hits)
|
||
{
|
||
if (hit.CompareTag("Player"))
|
||
{
|
||
Debug.LogError("第二阶段:撞到了玩家,造成了伤害");
|
||
hit.GetComponent<IDamagable>()?.ApplyDamage(3000, null, attack2Pre.transform);
|
||
hasHitPlayer = true;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
yield return null;
|
||
}
|
||
|
||
// 确保精确回到起点
|
||
transform.position = startPos;
|
||
|
||
attackMode = 0;
|
||
isDashing = false;
|
||
userSillIng = false;
|
||
}
|
||
|
||
IEnumerator ToTarget( Transform target )
|
||
{
|
||
// 记录起始位置
|
||
Vector3 startPos = transform.position;
|
||
Vector3 playerPos = target.position.ReflectVectorXOZ();
|
||
Vector3 dashDirection = (playerPos - startPos).normalized;
|
||
Vector3 endPos = playerPos + dashDirection * overshootDistance;
|
||
while (Vector3.Distance(transform.position, endPos) > 0.1f)
|
||
{
|
||
transform.position = Vector3.MoveTowards(transform.position, endPos, dashSpeed * Time.deltaTime);
|
||
transform.forward = Vector3.Lerp(transform.forward, dashDirection, Time.deltaTime * 10f);
|
||
yield return null;
|
||
}
|
||
//到达目标点后执行的方法
|
||
}
|
||
|
||
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(6, curEnemyPos, Vector3.zero, false);
|
||
}
|
||
}, 2f);
|
||
}
|
||
|
||
public override void StartQteAttack()
|
||
{
|
||
components[^1].StatQteAttack();
|
||
attackMode = 4;
|
||
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
|
||
{
|
||
bigXl.SetActive(true);
|
||
mzObj.SetActive(true);
|
||
}, 2f);
|
||
}
|
||
|
||
public override void BossQteAttack()
|
||
{
|
||
base.BossQteAttack();
|
||
AnimatorComponent.SetBool("isCastEnd", true);
|
||
components[^1].QteAttack();
|
||
attackMode = 0;
|
||
bigXl.SetActive(false);
|
||
mzObj.SetActive(false);
|
||
}
|
||
|
||
public override void StopQteAttack()
|
||
{
|
||
base.StopQteAttack();
|
||
bigXl.SetActive(false);
|
||
mzObj.SetActive(false);
|
||
components[^1].StopQteAttack();
|
||
shieldObj.SetActive(false);
|
||
isShield = false;
|
||
attackMode = 0;
|
||
}
|
||
|
||
private float enemyTime=45f;
|
||
private float curEnemyTime;
|
||
public override void Update()
|
||
{
|
||
base.Update();
|
||
AnimatorComponent.SetInteger("attackMode", attackMode);
|
||
if (_isShow) return;
|
||
|
||
attack2Pre.SetActive(attackMode == 2);
|
||
if (isDashing) 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;
|
||
}
|
||
}
|
||
|
||
public override void Dead()
|
||
{
|
||
if(!isDead)
|
||
GameManager.Ins.CurLevelWin(transform.position.ReflectVectorXOZ());
|
||
base.Dead();
|
||
GameInit.Ins.PlayAudio("1.13",GameInit.Ins.self.transform,true);
|
||
}
|
||
}
|