/// <summary> /// 유닛 죽음 /// </summary> public virtual void Die() { if (!string.IsNullOrEmpty(this.dieSoundKey)) { SoundManager.inst.PlaySound(this.dieSoundKey, 0.2f); } this.unitState = UnitState.Death; this.controller.OnDie(); this.conditionModule.Collect(); if (this.agent.enabled) { this.agent.enabled = false; } if (this.unitSide == UnitSide.Enemy) { // 퀘스트가 있다면 퀘스트 체크 QuestManager.inst.CheckQuest_Accum(QuestCheckKey.QuestKey_Hunt_ + this.unitKey, 1); // 코인 뿌림. 값은 그냥 랜덤줌. int count = Random.Range(3, 5); for (int i = 0; i < count; i++) { CoinObject coin = ObjectPoolManager.inst.Get <CoinObject>(PrefabPath.Coin); coin.transform.position = this.transform.position; coin.Init(Random.Range(30, 50)); coin.PlayAnimation(KUtils.SamplePosition_NavMesh(this.transform.position + new Vector3(Random.Range(-1.0f, 1.0f), 0, Random.Range(-1.0f, 1.0f)))); } // 스코어 누적 if (StageMaster.current != null) { if (this.isBoss) { StageMaster.current.scoreInfo.killBoss++; } else { StageMaster.current.scoreInfo.killMonster++; } } } // 죽으면 모든 콜라이더 끔 for (int i = 0; i < this.cols.Length; i++) { this.cols[i].enabled = false; } this.animCtrl.TriggerDie(); }
/// <summary> /// 작은 거미를 소환한다.(Called By Skill) /// 직접 호출금지. /// </summary> public void Summon() { Metalon mini = ObjectPoolManager.inst.Get <Metalon>(PrefabPath.Unit.MetalonMini); mini.transform.position = this.tail.transform.position; mini.unitSide = this.unitSide; (mini.controller as MetalonAIController).targetPosition = KUtils.SamplePosition_NavMesh(mini.transform.position + new Vector3(Random.Range(-1, 1.0f) * 10, 0, Random.Range(-1, 1.0f) * 10)); mini.Init(); SoundManager.inst.PlaySound(SoundKeys.EFFECT_CREATE_METALON_MINI, this.transform.position); }
/// <summary> /// index == 0 : 기본공격 /// index == 1 : SpellAttack(SpellAttack은 종류가 여러가지임) /// index == 2 : JumpAttack /// </summary> public override void OnStartAttackEvent(int index) { base.OnStartAttackEvent(index); switch (index) { case SKILL_IDX_ATTACK: // 기본 공격 { SkillUtility.SimpleRangeDamage(this, this.hone.position, 1.5f, this.unitSide, this.defaultDamage, PrefabPath.Particle.FireHit, SoundKeys.EFFECT_HIT_SOUND); SoundManager.inst.PlaySound(SoundKeys.EFFECT_PUNCH, this.hone.position); } break; case SKILL_IDX_BULLET_ATTACK: { if (this.spell == SpellAttackKind.Direct) // 360 샷 { this.skillModule.skills[SKILL_IDX_BULLET_ATTACK].Action(); } else if (this.spell == SpellAttackKind.Summon) // 소환 { this.skillModule.skills[SKILL_IDX_SUMMON].Action(); } else if (this.spell == SpellAttackKind.SpiderWeb) // 거미줄(일부로 하드코딩 했음) { for (int i = 0; i < 2; i++) { SpiderWeb web = ObjectPoolManager.inst.Get <SpiderWeb>(PrefabPath.SpiderWeb); web.transform.position = this.transform.position; web.Init(this, Vector2.one * (Random.Range(-1.0f, 1) + 3)); web.PlayAnimation(KUtils.SamplePosition_NavMesh(this.transform.position + new Vector3(Random.Range(-5, 5), 0, Random.Range(-5, 5)))); SoundManager.inst.PlaySound(SoundKeys.EFFECT_CREATE_SPIDER_WEB, this.transform.position); } } } break; case SKILL_IDX_JUMP_ATTACK: // 점프공격 { this.skillModule.skills[SKILL_IDX_JUMP_ATTACK].Action(); } break; } }
protected override void Hit(Unit hitUnit, Collider other) { base.Hit(hitUnit, other); // 히트지점으로부터 range내의 모든 유닛들을 가져온다. var units = KUtils.GetOverlapUnitsNonAlloc(this.transform.position, this.range); KUtils.DebugDrawSphere(this.transform.position, this.range); // 디버깅할때 범위 확인용! for (int i = 0; i < units.Count; i++) { //유닛끼리 서로 다른 진영일경우, 대미지를 준다 if (units[i].unitSide != this.owner.unitSide) { units[i].DealDamage(this.owner, Mathf.RoundToInt(Calculator.RandomDamage(damage))); } } Finish(); }
public override void Action() { base.Action(); // 범위 안에 있는 주변 유닛들을 모두 가져온다 var units = KUtils.GetOverlapUnitsNonAlloc(this.unit.transform.position, this.range); for (int i = 0; i < units.Count; i++) { //자기 자신이면 무시한다. if (units[i] == this.unit) { continue; } //유닛끼리 서로 다른 진영일경우, if (units[i].unitSide != this.unit.unitSide) { // 그리고 땅을 딛고 있을경우에만 대미지를 준다. if (units[i].isGrounded) { units[i].DealDamage(this.unit, Mathf.RoundToInt(Calculator.RandomDamage(damage))); units[i].conditionModule.AddCondition(new StunCondition(this.unit, 3)); } } } // 사운드 재생 SoundManager.inst.PlaySound(SoundKeys.EFFECT_JUMP_ATTACK, this.unit.transform.position); // 카메라 흔들기 PlayerCamera.current.ShakeCamera(0.5f, 0.2f); // 파티클 재생 ParticleSystem ps = ObjectPoolManager.inst.Get <ParticleSystem>(PrefabPath.Particle.JumpAttackEffect); ps.transform.position = this.unit.transform.position; ps.transform.rotation = this.unit.transform.rotation; ps.transform.localScale = Vector3.one; ps.Play(); }
/// <summary> /// 특정위치에 범위공격을 가한다. /// mySide : 공격하는 사람의 진영. 반대 side의 유닛에게 대미지를 준다. /// </summary> public static void SimpleRangeDamage(Unit attackedUnit, Vector3 position, float radius, UnitSide mySide, float damage, string hitEffectPath, string hitSoundPath) { var units = KUtils.GetOverlapUnitsNonAlloc(position, radius); KUtils.DebugDrawSphere(position, radius); for (int i = 0; i < units.Count; i++) { //자기 자신이면 무시한다. if (units[i] == attackedUnit) { continue; } //유닛끼리 서로 다른 진영일경우, 대미지를 준다 if (units[i].unitSide != mySide) { units[i].DealDamage(attackedUnit, Mathf.RoundToInt(Calculator.RandomDamage(damage))); /////////////////////////////////////////// // 이펙트 처리 bool useHitEffect = !string.IsNullOrEmpty(hitEffectPath); bool useHitSound = !string.IsNullOrEmpty(hitSoundPath); // 이펙트를 재생해야 한다면 if (useHitEffect || useHitSound) { Vector3 targetPoint; // 히트지점을 계산해야됨. // 발화점과, 히트 유닛간의 레이를 쏜다. Ray ray = new Ray(position, units[i].transform.position - position); RaycastHit hit; Debug.DrawRay(ray.origin, ray.direction, Color.red, 3); if (Physics.Raycast(ray, out hit, radius, Layers.Unit, QueryTriggerInteraction.Collide)) { // 레이로 검출이 된다면 검출된 지점에 히트이펙트 targetPoint = hit.point; } else { // 레이로 검출이 되지 않는다면 맞은 유닛에 그냥 표시 targetPoint = units[i].pivots.center.position; } // 이펙트가 필요하면 생성 if (useHitEffect) { ParticleSystem ps = ObjectPoolManager.inst.Get <ParticleSystem>(hitEffectPath); ps.transform.position = targetPoint; ps.transform.localRotation = Quaternion.identity; ps.transform.localScale = Vector3.one; ps.Play(); } // 사운드가 필요하면 재생 if (useHitSound) { SoundManager.inst.PlaySound(hitSoundPath, targetPoint); } } } } }