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.Instance.WaitSecondTodo(() => { AnimatorComponent.SetBool("isBoth", false); isAttack = true; bloodSlider.gameObject.SetActive(true); isShield = false; MonoSingleton.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()?.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()?.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.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.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); } }