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 のスポーン処理を行っている。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
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();
            }
        }
    }
}

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 の処理を行っている。

スポンサーリンク
%d人のブロガーが「いいね」をつけました。