1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

タワーデフェンスゲーム Unity 敵の機能 6/10 2回目以降の敵オブジェクト生成時に最初の移動地点を初期地点にする

Last updated at Posted at 2023-04-24

概要

前回の続きです

今回は2Wave以降敵が最終地点に行くバグを修正します。
改善前
before.gif

改善後

after.gif

次へ

開発環境

IDE:Rider
Unity:2020.3.42(LTS)
OS:Windows10

UnityEdtior上の設定

前回と変化なし

実装のポイント

バグの原因は、Enemyクラスの変数_currentWaypointIndexの値が初期化されていないことです。

対処方法としては、
Enemyクラス側で_currentWaypointIndexを初期化する関数を作り
SpawnerクラスでEnemyを生成する際に、_currentWaypointIndexを初期化する関数を実行しまう。

コード

Enemy.cs
using System;
using UnityEngine;

public class Enemy : MonoBehaviour
{
    public static Action OnEndReached;
    
    [SerializeField] private float moveSpeed = 3f;
    public Waypoint Waypoint { get; set; }
    public Vector3 CurrentPointPosition => Waypoint.GetWaypointPosition(_currentWaypointIndex);
    private int _currentWaypointIndex;
    
    private void Start()
    {
        _currentWaypointIndex = 0;
    }

    private void Update()
    {
        Move();
        if (CurrentPointPositionReached())
        {
            UpdateCurrentPointIndex();
        }
    }

    private void Move()
    {
        Vector3 currentPosition = Waypoint.GetWaypointPosition(_currentWaypointIndex);
        transform.position = Vector3.MoveTowards(transform.position, currentPosition, moveSpeed * Time.deltaTime);
    }
    
    private bool CurrentPointPositionReached()
    {
        return Vector3.Distance(transform.position, CurrentPointPosition) < 0.1f;
    }

    private void UpdateCurrentPointIndex()
    {
        int lastWaypointIndex = Waypoint.Points.Length - 1;
        if (_currentWaypointIndex < lastWaypointIndex)
        {
            _currentWaypointIndex++;
        }
        else
        {
            ReturnEnemyToPool();
            
        }
    }

    
    private void ReturnEnemyToPool()
    { 
        OnEndReached?.Invoke();
        ObjectPooler.ReturnToPool(gameObject);
    }

+    public void ResetEnemy()
+    {
+        _currentWaypointIndex = 0;
+    }
}
Spawner.cs
using System;
using System.Collections;
using UnityEngine;


    public class Spawner : MonoBehaviour
    {
        [SerializeField]  private  int enemyCount = 10;
        // Btw = Between
        [SerializeField] private float delayBtwSpawns;
        [SerializeField] private float delayBtwWaves = 1f;

        private int _enemiesRemaining;
        
        private int _enemiesSpawned;
        private float _spawnTimer;
        private ObjectPooler _objectPooler;
        private Waypoint _waypoint;

        private void Start()
        {
            _objectPooler = GetComponent<ObjectPooler>();
            _waypoint = GetComponent<Waypoint>();
            
            _enemiesRemaining = enemyCount;
        }

        private void Update()
        {
            _spawnTimer -= Time.deltaTime;
            if (_spawnTimer < 0)
            {
                _spawnTimer = delayBtwSpawns;
                if (_enemiesSpawned < enemyCount)
                {
                    SpawnEnemy();
                    _enemiesSpawned++;
                }
            }
        }
        
        // ReSharper disable Unity.PerformanceAnalysis
        private void SpawnEnemy()
        {
            GameObject newInstance = _objectPooler.GetInstanceFromPool();
            Enemy enemy = newInstance.GetComponent<Enemy>();
            enemy.Waypoint = _waypoint;
            enemy.transform.localPosition = transform.position;
+            enemy.ResetEnemy();
            newInstance.SetActive(true);
        }

        private IEnumerator NextWave()
        {
            yield return new WaitForSeconds(delayBtwWaves);
            _enemiesRemaining = enemyCount;
            _spawnTimer = 0f;
            _enemiesSpawned = 0;

        }
        
        private void RecordEnemyEndReached()
        {
            _enemiesRemaining--;
            if (_enemiesRemaining <= 0)
            {
                StartCoroutine(NextWave());
            }
        }
        private void OnEnable()
        {
            Enemy.OnEndReached += RecordEnemyEndReached;
        }

        private void OnDisable()
        {
            Enemy.OnEndReached -= RecordEnemyEndReached;
        }
    }

参考

Section4 16

githubコミット分

章まとめ

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?