181 lines
6.5 KiB
C#
181 lines
6.5 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using Random = UnityEngine.Random;
|
|
|
|
public class BossMobActor : MobActor
|
|
{
|
|
protected Dictionary<int, GameObject> dic_indicator = new Dictionary<int, GameObject>();
|
|
protected bool CanUseSkill1, CanUseSkill2;
|
|
protected float CoolTime_PassiveSkill, CoolTime_Skill1, CoolTime_Skill2;
|
|
protected int UseSkillIndex = 0;
|
|
|
|
public override void On_Regen(bool reincarnation = false, float healrate = 1)
|
|
{
|
|
base.On_Regen(reincarnation, healrate);
|
|
CanUseSkill1 = CanUseSkill2 = false;
|
|
CoolTime_PassiveSkill = 0;
|
|
}
|
|
|
|
protected override void Update()
|
|
{
|
|
base.Update();
|
|
if (IsDead()) return;
|
|
|
|
Check_PassiveSkill();
|
|
if (UseSkillIndex != 1 && CoolTime_Skill1 > 0f) CoolTime_Skill1 -= Time.deltaTime;
|
|
if (UseSkillIndex != 2 && CoolTime_Skill2 > 0f) CoolTime_Skill2 -= Time.deltaTime;
|
|
// 스킬 사용 결정
|
|
if (isTarget && UseSkillIndex == 0 && MobStatus != eMobStatus.Skill && !IsCC())
|
|
{
|
|
bool skill1Ready = CanUseSkill1 && CoolTime_Skill1 <= 0f;
|
|
bool skill2Ready = CanUseSkill2 && CoolTime_Skill2 <= 0f;
|
|
|
|
if (skill1Ready && skill2Ready)
|
|
UseSkillIndex = Random.Range(1, 3); // 1 또는 2 랜덤 선택
|
|
else if (skill1Ready)
|
|
UseSkillIndex = 1;
|
|
else if (skill2Ready)
|
|
UseSkillIndex = 2;
|
|
}
|
|
else
|
|
UseSkillIndex = 0;
|
|
|
|
if (IsStop) return;
|
|
}
|
|
|
|
protected virtual void Init(bool initSkill1CoolTime, bool initSkill2CoolTime)
|
|
{
|
|
Change_MobStatus(isTarget ? eMobStatus.Attack : eMobStatus.PatrolWait);
|
|
UseSkillIndex = 0;
|
|
}
|
|
void InActiveAllIndicator()
|
|
{
|
|
for (int i = 0; i < dic_indicator.Count; i++)
|
|
dic_indicator[i].SetActive(false);
|
|
}
|
|
|
|
public override void Del_Target(bool forcedel = false)
|
|
{
|
|
base.Del_Target(forcedel);
|
|
InActiveAllIndicator();
|
|
}
|
|
|
|
public override void Get_Damage(DamageInfo _dinfo)
|
|
{
|
|
base.Get_Damage(_dinfo);
|
|
if (!CanUseSkill1) CanUseSkill1 = (Get_HP() / Get_MaxHP()) <= 0.9;
|
|
if (!CanUseSkill2) CanUseSkill2 = (Get_HP() / Get_MaxHP()) <= 0.7;
|
|
|
|
// 테스트
|
|
CanUseSkill1 = true;
|
|
CanUseSkill2 = true;
|
|
}
|
|
|
|
protected override void Set_Die()
|
|
{
|
|
base.Set_Die();
|
|
Init(true, true);
|
|
}
|
|
|
|
protected override void On_NavMeshAgent()
|
|
{
|
|
base.On_NavMeshAgent();
|
|
Init(false, false);
|
|
}
|
|
|
|
protected virtual void Check_PassiveSkill()
|
|
{
|
|
if (CoolTime_PassiveSkill > 0f) CoolTime_PassiveSkill -= Time.deltaTime;
|
|
if (CoolTime_PassiveSkill <= 0f)
|
|
{
|
|
if (isTarget && m_Stat.Get_Stat(eStat.StartleBehind) > 0)
|
|
{
|
|
var skillData = table_skilllist.Ins.Get_Data_orNull(m_MonsterTableData.n_PassiveSkillID);
|
|
if (Vector3.Distance(Get_position(), m_Target.Get_position()) > skillData.f_ExtraValue1)
|
|
StartCoroutine(Co_StartleBehind(skillData));
|
|
}
|
|
}
|
|
}
|
|
IEnumerator Co_StartleBehind(SkillListTableData skillData)
|
|
{
|
|
CoolTime_PassiveSkill = skillData.f_ExtraValue4;
|
|
InGameInfo.Ins.Show_Effect("Effect_Teleport", Get_position());
|
|
AnimationPlay("startlebehind");
|
|
|
|
yield return new WaitForSeconds(0.5f);
|
|
|
|
m_Target.Stun(skillData.f_ExtraValue2, true);
|
|
Set_Warp(Get_TeleportPostion(m_Target, -skillData.f_ExtraValue3));
|
|
Change_MobStatus(eMobStatus.Attack);
|
|
}
|
|
|
|
protected virtual float Get_Skill1Dmg() { return 1f; }
|
|
protected virtual Vector3 Get_Skill1Pos() { return Get_CenterPositionFoward(); }
|
|
protected virtual void Set_Skill1Projectile(ProjectileBase pb) { }
|
|
protected virtual void BossProjectile2(string s)
|
|
{
|
|
if (ProjectileInfo.ProjectileInfoOn)
|
|
ProjectileInfo.Ins.Shoot_Projectile(m_MonsterTableData.s_Porjectile2, this, m_Target, Get_Skill1Dmg(), Get_Skill1Pos(),
|
|
m_MonsterTableData.f_ProjectileLifeTime2, pb => { Set_Skill1Projectile(pb); });
|
|
}
|
|
|
|
protected virtual float Get_Skill2Dmg() { return 1f; }
|
|
protected virtual Vector3 Get_Skill2Pos() { return Get_CenterPositionFoward(); }
|
|
protected virtual void Set_Skill2Projectile(ProjectileBase pb) { }
|
|
protected virtual void BossProjectile3(string s)
|
|
{
|
|
if (ProjectileInfo.ProjectileInfoOn)
|
|
ProjectileInfo.Ins.Shoot_Projectile(m_MonsterTableData.s_Porjectile3, this, m_Target, Get_Skill2Dmg(), Get_Skill2Pos(),
|
|
m_MonsterTableData.f_ProjectileLifeTime3, pb => { Set_Skill2Projectile(pb); });
|
|
}
|
|
|
|
protected void Load_Indicator(string prefab, int index)
|
|
{
|
|
if (dic_indicator.ContainsKey(index))
|
|
dic_indicator[index].SetActive(false);
|
|
else
|
|
IndicatorInfo.Ins.Make_Indicator(prefab, go => { dic_indicator.Add(index, go); go.SetActive(false); });
|
|
}
|
|
protected void Load_Projectile(string prefab, float skilldmg, Vector3 pos, float lifetime, ProjectileBase _pb, Action<ProjectileBase> act_pb)
|
|
{
|
|
if (DSUtil.CheckNull(_pb))
|
|
ProjectileInfo.Ins.Shoot_Projectile(prefab, this, m_Target, skilldmg, pos, lifetime,
|
|
pb => { act_pb(pb); pb.gameObject.SetActive(false); });
|
|
else
|
|
_pb.gameObject.SetActive(false);
|
|
}
|
|
|
|
protected void Run_byUseSkill(float range, float speed, Action<bool> moveend)
|
|
{
|
|
StartCoroutine(Co_Run_byUseSkill(range, speed, moveend));
|
|
}
|
|
IEnumerator Co_Run_byUseSkill(float range, float speed, Action<bool> moveend)
|
|
{
|
|
if (!DSUtil.CheckNull(m_Target))
|
|
{
|
|
Change_MobStatus(eMobStatus.Skill);
|
|
transform.LookAt(m_Target.transform);
|
|
AnimationPlay(MyValue.Get_AnimName(eAnim.Run));
|
|
m_NavMeshAgent.stoppingDistance = 0.1f;
|
|
|
|
var direction = (Get_position() - m_Target.Get_position()).normalized;
|
|
var targetPos = m_Target.Get_position() + direction * range;
|
|
Set_Path(Get_TeleportPostion(m_Target, range));
|
|
|
|
while (!Complete_Destination())
|
|
{
|
|
m_NavMeshAgent.speed = speed;
|
|
yield return null;
|
|
}
|
|
|
|
m_NavMeshAgent.stoppingDistance = m_NavStopDistance;
|
|
m_NavMeshAgent.speed = Get_MoveSpeed();
|
|
|
|
moveend(true);
|
|
}
|
|
else
|
|
moveend(false);
|
|
}
|
|
} |