Unity チュートリアルのタワーディフェンステンプレートを触ってみる(44)
Unity チュートリアルのタワーディフェンステンプレートを触ってみる(43)では Agent の Wave を登録する Wave の継承関係にある TimedBehaviour について解説を行った。。今回は Agent の Wave を登録する Wave について解説を行っていく。
1.タワーディフェンステンプレートのステージの設定編 – Wave.cs
Wave.cs について稚拙ながら解説
「Wave.cs」は「Assets/Scripts/TowerDefense/Level/Wave.cs」の指しておりスクリプトについては以下の通り。内容としては Wave のスポーン処理を行っている。
[cce_csharp]using System;
using System.Collections.Generic;
using Core.Extensions;
using Core.Utilities;
using TowerDefense.Agents;
using TowerDefense.Agents.Data;
using TowerDefense.Nodes;
using UnityEngine;
namespace TowerDefense.Level
{
/// <summary>
/// A Wave is a TimedBehaviour, that uses the RepeatingTimer to spawn enemies
/// </summary>
public class Wave : TimedBehaviour
{
/// <summary>
/// A list of instructions on how to spawn enemies
/// </summary>
public List<SpawnInstruction> spawnInstructions;
/// <summary>
/// The index of the current enemy to spawn
/// </summary>
protected int m_CurrentIndex;
/// <summary>
/// The RepeatingTimer used to spawn enemies
/// </summary>
protected RepeatingTimer m_SpawnTimer;
/// <summary>
/// The event that is fired when a Wave is completed
/// </summary>
public event Action waveCompleted;
public virtual float progress
{
get { return (float) (m_CurrentIndex) / spawnInstructions.Count; }
}
/// <summary>
/// Initializes the Wave
/// </summary>
public virtual void Init()
{
// If the wave is empty then warn the level designer and fire complete event
if (spawnInstructions.Count == 0)
{
Debug.LogWarning("[LEVEL] Empty Wave");
SafelyBroadcastWaveCompletedEvent();
return;
}
m_SpawnTimer = new RepeatingTimer(spawnInstructions[0].delayToSpawn, SpawnCurrent);
StartTimer(m_SpawnTimer);
}
/// <summary>
/// Handles spawning the current agent and sets up the next agent for spawning
/// </summary>
protected virtual void SpawnCurrent()
{
Spawn();
if (!TrySetupNextSpawn())
{
SafelyBroadcastWaveCompletedEvent();
// this is required so wave progress is still accurate
m_CurrentIndex = spawnInstructions.Count;
StopTimer(m_SpawnTimer);
}
}
/// <summary>
/// Spawns the current agent
/// </summary>
protected void Spawn()
{
SpawnInstruction spawnInstruction = spawnInstructions[m_CurrentIndex];
SpawnAgent(spawnInstruction.agentConfiguration, spawnInstruction.startingNode);
}
/// <summary>
/// Tries to setup the next spawn
/// </summary>
/// <returns>true if there is another spawn instruction, false if not</returns>
protected bool TrySetupNextSpawn()
{
bool hasNext = spawnInstructions.Next(ref m_CurrentIndex);
if (hasNext)
{
SpawnInstruction nextSpawnInstruction = spawnInstructions[m_CurrentIndex];
if (nextSpawnInstruction.delayToSpawn <= 0f)
{
SpawnCurrent();
}
else
{
m_SpawnTimer.SetTime(nextSpawnInstruction.delayToSpawn);
}
}
return hasNext;
}
/// <summary>
/// Spawns the agent
/// </summary>
/// <param name="agentConfig">The agent to spawn</param>
/// <param name="node">The starting node that the agent uses</param>
protected virtual void SpawnAgent(AgentConfiguration agentConfig, Node node)
{
Vector3 spawnPosition = node.GetRandomPointInNodeArea();
var poolable = Poolable.TryGetPoolable<Poolable>(agentConfig.agentPrefab.gameObject);
if (poolable == null)
{
return;
}
var agentInstance = poolable.GetComponent<Agent>();
agentInstance.transform.position = spawnPosition;
agentInstance.Initialize();
agentInstance.SetNode(node);
agentInstance.transform.rotation = node.transform.rotation;
}
/// <summary>
/// Launch the waveCompleted event
/// </summary>
protected void SafelyBroadcastWaveCompletedEvent()
{
if (waveCompleted != null)
{
waveCompleted();
}
}
}
}[/cce_csharp]
45行目 : 「public virtual void Init()」は初期化処理を行っている。内容としてはスポーンするリストに設定がなければ警告メッセージを表示後、SafelyBroadcastWaveCompletedEvent 処理を行っている。設定があれば Timer を作成し、TimedBehaviour の StartTimer 処理を行っている。
TimedBehaviour については、前回解説させていただいたのでこちらを参照してほしい。
62行目 : 「protected virtual void SpawnCurrent()」は Agent の生成と次の Agent の生成準備を行っている。内容としては Spawn 処理後、TrySetupNextSpawn が成功していなければ、SafelyBroadcastWaveCompletedEvent 処理を行い、TimedBehaviour の StopTimer 処理を行っている。
77行目 : 「protected void Spawn()」は Agent の生成処理を行っている。内容としてはスポーンリストからスポーンさせる Agent を選択し、SpawnAgent の処理を行っている。
87行目 : 「protected bool TrySetupNextSpawn()」は次の Agent の生成準備を行っている。内容としてはグローバル変数の m_CurrentIndex の次がスポーンリストにあれば、スポーン時間の設定を行っている。
111行目 : 「protected virtual void SpawnAgent(AgentConfiguration agentConfig, Node node)」は Agent の生成処理を行っている。引数の AgentConfiguration があれば Poolable から Agent を取得し、Agent の初期値を設定している。
130行目 : 「protected void SafelyBroadcastWaveCompletedEvent()」は Agent のリストが設定されていなかった処理を行っている。内容としては外部から登録された waveCompleted の処理を行っている。
