Files
gold_dolphin/unity/Assets/Script/GameObject/Enemy/BossAI.cs
2026-06-20 19:35:25 +08:00

338 lines
8.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Manager;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class BossAI : CombaSystem
{
//基本信息类
public BossInfo _info;
Rigidbody2D rb;
//玩家信息,待优化
PlayerControler player;
CharacterCombat characterCombat;
private Transform currentTarget;
//玩家与敌人的距离方向
private float dis;
private Vector2 dir;
[Header("追击与攻击距离")]
public float cheseDistance = 3f;
public float attackDistance = 0.8f;
[SerializeField, Header("技能搭配")] private List<CombatAblilityBase> abilitys = new List<CombatAblilityBase>();
private CombatAblilityBase currentAblity;
//判断偏移
private List<Vector2> ablityOff;
//攻击段数
private int attackCount;
//计时器
public GameObject timer;
public bool isBegin = false;
List<CombatAblilityBase> tempAb = new List<CombatAblilityBase>();//可用技能组
int ran;//技能组索引
CameraVR cameraVR;
public bool isYuancheng=false;
protected override void Awake()
{
base.Awake();
_animator = GetComponentInChildren<Animator>();
rb = GetComponentInParent<Rigidbody2D>();
currentTarget = GameObject.FindWithTag("Player").transform;
_info = GetComponentInParent<BossInfo>();
foreach (var ab in abilitys)
{
ab.Init(this,_animator);
}
}
private void Update()
{
if (!_animator.CheckAnimationTag("summon")&&isBegin)
{
if (!isDie) //死亡或咆哮状态的时候不会进行攻击
{
MoveBoss();
}
}
}
private void FixedUpdate()
{
if (currentAblity != null)
{
currentAblity.UpdateAblity(currentTarget);
}
}
private void MoveBoss()
{
if (_animator.CheckAnimationTag("Wake"))
return;
if (_animator.CheckAnimationTag("hit") || _animator.CheckAnimationTag("Attack")||_animator.CheckAnimationTag("Attack_out"))
{
return;
}
if (currentTarget == null)
return;
LockTarget(currentTarget);
dis = Vector2.Distance(currentTarget.position, transform.position);
if (dis < cheseDistance)
{
rb.velocity = Vector2.zero;
//近战
if (dis < attackDistance)
{
//_animator.Play("attack-charge");
currentAblity = GetAblity(AblityClass.MelleeAttack);
if (currentAblity != null)
{
//SoundManager.Instance.PlayEffect(_audio, currentAblity.GetAbliltyVFX());
_animator.Play(currentAblity.GetAbliltyName());
currentAblity.UseAblity(currentAblity);
}
return;
}
//远程
else
{
currentAblity = GetAblity(AblityClass.YuanChenAttack);
if (currentAblity != null)
{
//SoundManager.Instance.PlayEffect(_audio, currentAblity.GetAbliltyVFX());
_animator.Play(currentAblity.GetAbliltyName());
currentAblity.UseAblity(currentAblity);
}
return;
}
}
else
{
if (!_info.isCanMove)
return;
_animator.Play("run");
rb.velocity = dir * _info._moveSpeed;
}
}
private void LockTarget(Transform target)
{
if (!_info.isLockTarget)
return;
dir = (target.position - transform.position).normalized;
if(_info.isFix)
{
Fix(dir);
}
}
private void Fix(Vector2 dir)
{
if (dir.x < 0)
{
transform.root.localScale = new Vector3(1, 1, 1);
}
if (dir.x > 0)
{
transform.root.localScale = new Vector3(-1, 1, 1);
}
}
public void Yuancheng()
{
isYuancheng = true;
}
public void OnCloseYuancheng()
{
isYuancheng = false;
}
public void TeleportEvent()
{
if (currentTarget == null) return;
transform.root.transform.position = currentTarget.transform.position;
}
/// <summary>
/// 近战攻击
/// </summary>
public override void MelleeAttackAnimEvent()
{
if (currentAblity != null)
{
AttackAreaPos = transform.position;
ablityOff = currentAblity.GetAbliltyOffest();
AttackAreaPos.x += ablityOff[attackCount].x;
AttackAreaPos.y += ablityOff[attackCount].y;
attackCount++;
if (attackCount >= ablityOff.Count)
{
attackCount = 0;
}
if (_info.isCanMove)
{
AttackAreaPos.x = this.transform.parent.localScale.x < 0 ? Mathf.Abs(offsetX) : -Mathf.Abs(offsetX);
}
}
else
{
base.MelleeAttackAnimEvent();
}
Collider2D[] hitColliders = Physics2D.OverlapBoxAll(AttackAreaPos, attackSize, 0, layerMasks[0]);
if(currentAblity!=null&&currentAblity.GetAbliltyVFX()!=null)
{
SoundManager.Instance.PlayEffect(_audio, currentAblity.GetAbliltyVFX());
}
foreach (Collider2D hitInfo in hitColliders)
{
player = hitInfo.GetComponent<PlayerControler>();
if (player != null && player.GetIsDodge())
{
Debug.Log("玩家无敌");
_animator.speed = 0;
StartCoroutine(ScalTime(1f));
return;
}
characterCombat = hitInfo.GetComponentInChildren<CharacterCombat>();
//if(characterCombat._animator.CheckAnimationTag("Roll"))
//{
// //无敌闪避
// _animator.speed = 0;
// StartCoroutine(ScalTime(1f));
// return;
//}
characterCombat.TakeDamage(attack);
Debug.Log("玩家受伤");
}
}
IEnumerator ScalTime(float timer)
{
yield return new WaitForSeconds(timer);
_animator.speed = 1;
}
public override void TakeDamage(string aniName, float attack)
{
if (isDie || _animator.CheckAnimationTag("summon")||_animator.CheckAnimationTag("Wake"))//咆哮不会被攻击
return;
Debug.Log("被玩家攻击" + _info.attackedCount);
_info.attackedCount++;//耐力次数增加
if (_info.attackedCount > _info.maxAttackedCount)
{
_info.attackedCount = 0;//重新计数
_animator.Play("summon");
if(_summerClip!=null)
{
SoundManager.Instance.PlayEffect(_audio,_summerClip);
}
//吼叫
//摄像机震动
cameraVR=UnityExpandFunction.GetCamera();
if (cameraVR != null)
{
cameraVR.ShakeCamera(1f, 5);
}
//回血
currentHp += 200;
if (currentHp >= maxHp)
currentHp = maxHp;
OnHit?.Invoke(currentHp);
return;
}
//受伤
currentHp -= attack;//血量减少
OnHit?.Invoke(currentHp);//执行受伤事件血量UI减少
if (currentHp <= 0)
{
isDie = true;
return;
}
if(_animator.CheckAnimationTag("Attack"))
{
return;
}
_animator.Play(aniName);
}
private CombatAblilityBase GetAblity(AblityClass ablity)
{
tempAb.Clear();
foreach (var ab in abilitys)
{
if (ab.GetAbliltyIsDone() && ab.GetAbliltyClass() == ablity)
{
tempAb.Add(ab);
}
}
if(tempAb.Count==0)
{
return null;
}
ran = UnityEngine.Random.Range(0,tempAb.Count);
if (tempAb[ran] != null)
return tempAb[ran];
return null;
}
public void SetBegin(bool b)
{
isBegin = b;
//开始
_animator.Play("sleeping");
UIManager.Instance.Show<UIEnterScene>().InitInfo(_info.bossHead, _info.bossName);
}
private void OnDrawGizmosSelected()
{
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(transform.position, cheseDistance);
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, attackDistance);
}
}