338 lines
8.4 KiB
C#
338 lines
8.4 KiB
C#
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&¤tAblity.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);
|
||
}
|
||
}
|