/// <summary> /// 몬스터를 생성한다. /// </summary> /// <typeparam name="T">생성할 몬스터 타입</typeparam> /// <param name="spawnPoint">생서할 위치</param> /// <param name="pattern">베지어 곡선에 넣을 패턴</param> /// <param name="destination">베지어 곡선에 넣을 도착지점</param> /// <returns>생성한 오브젝트</returns> public T SpawnEnemy <T>(StartPoint spawnPoint, WayPoints.ShapeTypeTable pattern, Transform destination) where T : GameObject, new() { T enemy = GameObject.Instantiate <T>(); BezierCurveMove moveType = enemy.GetComponent <BezierCurveMove>(); if (moveType != null) { moveType.WayPoints = WayPoints.Instance.GetWayPoint(GetLocation(spawnPoint), pattern); moveType.Destination = destination; } return(enemy); }
/// <summary> /// slot에 설정된 적 유닛의 로직을 설정한다. /// 각 컴포넌트에 이벤트를 추가한다. /// </summary> /// <param name="slot">설정할 슬롯</param> /// <param name="score">죽으면 추가할 점수</param> private void SetupEnemy(Slot slot, int score) { BezierCurveMove move = slot.gameObject.GetComponent <BezierCurveMove>(); HealthSystem health = slot.gameObject.GetComponent <HealthSystem>(); DamageSystem damageSystem = slot.gameObject.GetComponent <DamageSystem>(); //damageSystem.EventGiveDamage += () => health.GetDamage(2); // 한번만 작동하게 하는 이벤트 삽입 // 자기 자신에게 데미지 주기 Action selfDamage = null; selfDamage = () => { damageSystem.EventGiveDamage -= selfDamage; health.GetDamage(2); }; damageSystem.EventGiveDamage += selfDamage; // 죽으면 애니메이션 재생하게 하기 health.EventOnDead += () => { slot.gameObject.collider.Enabled = false; move.Enabled = false; AnimationSprite animation = slot.gameObject.GetComponent <AnimationSprite>(); animation.ImageCurrentIndex = 0; animation.ImageChangeInterval = 0.1f; animation.ImageList.Clear(); animation.ImageList.Add(Resources.enemy_die_01); animation.ImageList.Add(Resources.enemy_die_02); animation.ImageList.Add(Resources.enemy_die_03); animation.ImageList.Add(Resources.enemy_die_04); animation.ImageList.Add(Resources.enemy_die_05); // 재생 다하면 오브젝트 삭제 animation.EventPrintedAllImage += () => GameObject.Destroy(slot.gameObject, 0); animation.EventPrintedAllImage += () => slot.gameObject = null; }; // 점수 증가 health.EventOnDead += () => GameManager.Instance.IncreaseScore(score); health.EventOnDead += () => aliveUnits.Remove(slot.gameObject); // 보스몬스터일경우 남은 HP가 1이면 애니메이션 스프라이트 변경 if (slot.gameObject as Enemy03 != null) { health.EventGetDamage += (leftHP) => { if (leftHP == 1) { AnimationSprite animationSprite = slot.gameObject.GetComponent <AnimationSprite>(); if (animationSprite != null) { animationSprite.ImageList.Clear(); animationSprite.ImageList.Add(Resources.Enemy_03_03_01); animationSprite.ImageList.Add(Resources.Enemy_03_03_01); } } else if (leftHP == 2) { AnimationSprite animationSprite = slot.gameObject.GetComponent <AnimationSprite>(); if (animationSprite != null) { animationSprite.ImageList.Clear(); animationSprite.ImageList.Add(Resources.Enemy_03_02_01); animationSprite.ImageList.Add(Resources.Enemy_03_02_01); } } }; } }
/// <summary> /// 공격을 실행한다. /// 공격을 실행할 갯수를 정하고 /// 공격 형태를 랜덤으로 정하여 이동경로를 정해준다. /// </summary> public async void Attack() { int maxAttackUnit = 2; if (GameManager.Instance.CurrentStage < random.Next(100)) { maxAttackUnit += random.Next(1, 3); } if (maxAttackUnit > aliveUnits.Count) { maxAttackUnit = aliveUnits.Count; } int addAttackUnitCount = 0; for (int i = 0; i < aliveUnits.Count; i++) { bool alreadyAttacking = false; foreach (var item in attackingUnits) { if (aliveUnits[i] == item) { alreadyAttacking = true; } } if (alreadyAttacking == false && addAttackUnitCount < maxAttackUnit) { addAttackUnitCount++; attackingUnits.Add(aliveUnits[i]); BezierCurveMove move = aliveUnits[i].GetComponent <BezierCurveMove>(); WayPoints.ShapeTypeTable attackType = WayPoints.ShapeTypeTable.kSwingLeftDown; StartPoint reattackPosition = StartPoint.LeftTop; switch (random.Next(2)) { case 0: attackType = WayPoints.ShapeTypeTable.kSwingLeftDown; break; case 1: attackType = WayPoints.ShapeTypeTable.kSwingRightDown; break; } switch (random.Next(2)) { case 0: reattackPosition = StartPoint.LeftTop; break; case 1: reattackPosition = StartPoint.RightTop; break; } move.WayPoints = WayPoints.Instance.GetWayPoint(aliveUnits[i].transform.position, attackType); move.CurrentProgress = 0; move.Destination = null; Action handler = null; handler = () => { move.EventMoveDone -= handler; move.WayPoints = WayPoints.Instance.GetWayPoint(Spawner.Instance.GetLocation(reattackPosition), attackType); move.CurrentProgress = 0; move.EventMoveDone += () => move.CurrentProgress = 0; }; move.EventMoveDone += handler; await Task.Delay(500); } } AttackReady = true; }