using UnityEngine; public class MyActor : Actor { protected float f_FindEnemyRange; protected Actor OwnerActor; public override void Set_Target(bool forcefind = false) { if (isTarget) { if (m_Target.m_IsLockTarget && !m_Target.IsDead()) return; if (IsRole(eRole.PC)) m_Target.Set_Outline(false); } m_Target = ActorInfo.Ins.Get_Nearest_EnemyActor_orNull(IsEnemy(), Get_position(), forcefind ? float.MaxValue : f_FindEnemyRange); if (isTarget) { if (IsRole(eRole.PC)) { m_Target.Set_Outline(true); //MonsterSimpleInfo.Ins.Set(m_Target); //PCInfo.Ins.Get_PetsWithDie(m_Enemy).ForEach(f => f.Add_FindEnemy(m_Target.m_Role, m_Target.Get_Group())); } else { // 모두 하나의 적만 노리지 않게 타겟 주위의 몹을 타겟 //var enemies = DSUtil.Get_Enemies(IsEnemy(), m_Target.Get_position(), 3f, Get_EnemyList()); //if (enemies != null && enemies.Count > 0) m_Target = enemies[Random.Range(0, enemies.Count)]; } } } public override void Change_Target(bool _ispc, Actor target, bool _ChangeTargetByHit = false) { base.Change_Target(_ispc, target, _ChangeTargetByHit); //if (target) MonsterSimpleInfo.Ins.Set(target); } protected override void Update() { if (IsDead()) return; m_attackCoolTime -= Time.deltaTime; if (m_HitTime > 0f) { m_HitTime -= Time.deltaTime; return; } if (IsStop || IsCC() || (GameUI.Ins && GameUI.Ins.IngameUI.Active_SelectSkillUI())) return; base.Update(); Check_Target(); if (isTarget) { if (m_Target.IsDead()) Del_Target(); else { if (IsNotPC() && Vector3.Distance(OwnerActor.Get_position(), Get_position()) > 7) { Del_Target(); return; } if (CurAnim < eAnim.Attack) { if (DSUtil.CheckNull(m_Magic)) m_NavMeshAgent.stoppingDistance = m_NavStopDistance + (float)m_Stat.Get_Stat(eStat.AttackRange_Up); else m_NavMeshAgent.stoppingDistance = m_Magic.m_SkillTableData.f_SkillRange; if (Vector3.Distance(Get_position(), m_Target.Get_position()) > m_NavMeshAgent.stoppingDistance + m_Target.Get_ScaleSizeDist()) Play_Run(); else if (!DSUtil.CheckNull(m_Magic)) Use_Skill(m_Magic.m_SkillTableData, false, m_Magic.m_uiIndex); //else if (CurAnim != eAnim.Attack && m_attackCoolTime > 0f) // Play_Idle(); else if (CurAnim != eAnim.Skill && CurAnim != eAnim.Dodge) Play_Attack(0, (float)m_Stat.Get_Stat(eStat.FinalAttackSpeed)); } } } else if (CurAnim != eAnim.Run && CurAnim < eAnim.Dodge) Play_Idle(); } protected virtual void Update_Move() { if (m_fAttackMoveTime > 0f) { m_fAttackMoveTime -= Time.deltaTime; m_NavMeshAgent.stoppingDistance = 0; if (Complete_Destination() || m_fAttackMoveTime <= 0f) { m_fAttackMoveTime = 0f; if (!DSUtil.CheckNull(act_MoveEnd)) { m_bCanDodge = false; Play_Run(); act_MoveEnd(true); act_MoveEnd(false); IsStop = false; act_MoveEnd = null; } else m_NavMeshAgent.angularSpeed = 300f; } } } protected void Follow_PC() { m_NavMeshAgent.stoppingDistance = 1f; Play_Run(); Set_Path(OwnerActor.Get_position()); if (Complete_Destination()) Play_Idle(); } bool IsNotPC() { return !IsRole(eRole.PC); } public override void Get_Damage(DamageInfo _dinfo) { base.Get_Damage(_dinfo); if (!isTarget || m_Target.IsDead()) { m_Target = _dinfo.Beater; } } public override void Play_Run() { base.Play_Run(); if (isTarget) Set_Path(m_Target.Get_position()); //if (isTarget) //{ // if (!Set_Path(m_Target.Get_position())) // { // 적이 내비메시 위에 없다고 판단됨 // m_Target.ReCal_NaveMesh(); // } //} } public override void Play_Attack(int _attack, float _as) { base.Play_Attack(_attack, _as); //if (isTarget) //{ // if (!Set_Path(m_Target.Get_position())) // 때리려는 타겟쪽으로 보게 함 // { // 적이 내비메시 위에 없다고 판단됨 // m_Target.ReCal_NaveMesh(); // } //} } public void Check_Target(bool forcefind = false) { if (forcefind || m_Auto) { if (!isTarget) Set_Target(forcefind); else { if (m_Target.IsDead() && !isPlaying(eAnim.Attack, eAnim.Attack2, eAnim.Attack3, eAnim.Attack4, eAnim.Skill)) Set_Target(forcefind); } } } public override void Play_Hit() { base.Play_Hit(); if (CurAnim == eAnim.Run) return; // 달릴 때도 무시 if (IsDead() || IsCC() || CurAnim >= eAnim.Attack) return; // 공격, 스킬 쓸 때는 피격 애님 무시 if (IsRole(eRole.Mob)) m_HitTime = 0.5f; var aniname = MyValue.Get_AnimName(eAnim.Hit); m_animation.speed = 1f; AnimationPlay(aniname); } public override void On_Regen(bool reincarnation = false, float healrate = 1f) { base.On_Regen(reincarnation, healrate); Set_Warp(LoadMapMgr.Ins.Get_ReincanationPos(MyValue.MyChoiceMapData)); } public override void Set_Stat_SelectSkill(SelectSkillTableData _sstd) { base.Set_Stat_SelectSkill(_sstd); // TODO 정인호 : 3가지 카드에서 선택하는 스킬과 관련된 스탯 설정 //switch (_sstd.Stat) //{ // case eStat.Attack: // case eStat.CriDmg: // if (IsRole(eRole.PC)) m_Stat.Set_Stat(true, _sstd.Stat, m_Stat.Get_Stat(_sstd.Stat) * _sstd.ValueBase); // break; // case eStat.HP: // case eStat.MP: // if (IsRole(eRole.PC)) m_Stat.Add_MaxHPMP(_sstd.Stat, _sstd.ValueBase); // break; // case eStat.MPRecover: // break; // case eStat.Defence_Melee: // case eStat.Defence_Range: // case eStat.Cri: // if (IsRole(eRole.PC)) m_Stat.Set_Stat(true, _sstd.Stat, _sstd.ValueBase); // break; // case eStat.AttackSpeed: // break; // case eStat.AttackCoolTime: // break; // case eStat.PetAttack: // if (IsRole(eRole.Pet)) m_Stat.Set_Stat(true, eStat.Attack, m_Stat.Get_Stat(eStat.Attack) * _sstd.ValueBase); // break; // case eStat.PetHP: // if (IsRole(eRole.Pet)) m_Stat.Add_MaxHPMP(eStat.HP, _sstd.ValueBase); // break; // case eStat.PetDefence_Melee: // if (IsRole(eRole.Pet)) m_Stat.Set_Stat(true, eStat.Defence_Melee, _sstd.ValueBase); // break; // case eStat.PetDefence_Range: // if (IsRole(eRole.Pet)) m_Stat.Set_Stat(true, eStat.Defence_Range, _sstd.ValueBase); // break; // case eStat.PetBerserkAttack: // if (IsRole(eRole.Pet) && IsBerserkPet()) m_Stat.Set_Stat(true, eStat.Attack, m_Stat.Get_Stat(eStat.Attack) * _sstd.ValueBase); // break; // case eStat.PetBerserkQuick: // break; // case eStat.PetBerserkTime: // break; //} } public override void Projectile(string s) { base.Projectile(s); if (ProjectileInfo.ProjectileInfoOn && !string.IsNullOrEmpty(s)) { var ccData = Get_CCData(eCC.MultiShot); var amount = 1 + (ccData.CCTime > 0f ? ccData.CCVal : 0); if (amount > 1) { float cal_angle = 80f; float angleStep = cal_angle / (amount - 1); // 전체 각도(120도)를 화살 개수로 나누기 for (int i = 0; i < amount; ++i) { var startpos = Get_CenterPositionFoward(); var lifeTime = table_effectlist.Ins.Get_Data(s).f_ProjectileLifeTime; ProjectileInfo.Ins.Shoot_Projectile(s, this, m_Target, 1f, startpos, lifeTime, 1, pb => { // -60 ~ 60 사이로 각도를 균등 분배 float angle = -(cal_angle * 0.5f) + (angleStep * i); // 시작 각도 -60에서 각 화살의 각도 계산 pb.transform.localEulerAngles = new Vector2(0f, pb.transform.localEulerAngles.y + angle); }); } } else { var startpos = Get_CenterPositionFoward(); var lifeTime = table_effectlist.Ins.Get_Data(s).f_ProjectileLifeTime; ProjectileInfo.Ins.Shoot_Projectile(s, this, m_Target, 1f, startpos, lifeTime); } } } }