Unity チュートリアルのタワーディフェンステンプレートを触ってみる(33)
Unity チュートリアルのタワーディフェンステンプレートを触ってみる(32)では引き続き「タワーディフェンステンプレートのステージの設定編」を行った。今回はレベルデータを保持している LevelList の解説を行っていく。
1.タワーディフェンステンプレートのステージの設定編 – LevelList.cs
LevelList.cs について稚拙ながら解説
「LevelList.cs」は「Assets/Scripts/Core/Game/LevelList.cs」の指しておりスクリプトについては以下の通り。内容としてはレベルデータのリストを保持している。
[cce_csharp]using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Core.Game
{
/// <summary>
/// Scriptable object for Level configuration
/// </summary>
[CreateAssetMenu(fileName = "LevelList", menuName = "StarterKit/Create Level List", order = 1)]
public class LevelList : ScriptableObject, IList<LevelItem>,
IDictionary<string, LevelItem>,
ISerializationCallbackReceiver
{
public LevelItem[] levels;
/// <summary>
/// Cached dictionary of levels by their IDs
/// </summary>
IDictionary<string, LevelItem> m_LevelDictionary;
/// <summary>
/// Gets the number of levels
/// </summary>
public int Count
{
get { return levels.Length; }
}
/// <summary>
/// Level list is always read-only
/// </summary>
public bool IsReadOnly
{
get { return true; }
}
/// <summary>
/// Gets a level by index
/// </summary>
public LevelItem this[int i]
{
get { return levels[i]; }
}
/// <summary>
/// Gets a level by id
/// </summary>
public LevelItem this[string key]
{
get { return m_LevelDictionary[key]; }
}
/// <summary>
/// Gets a collection of all level keys
/// </summary>
public ICollection<string> Keys
{
get { return m_LevelDictionary.Keys; }
}
/// <summary>
/// Gets the index of a given level
/// </summary>
public int IndexOf(LevelItem item)
{
if (item == null)
{
return -1;
}
for (int i = 0; i < levels.Length; ++i)
{
if (levels[i] == item)
{
return i;
}
}
return -1;
}
/// <summary>
/// Gets whether this level exists in the list
/// </summary>
public bool Contains(LevelItem item)
{
return IndexOf(item) >= 0;
}
/// <summary>
/// Gets whether a level of the given id exists
/// </summary>
public bool ContainsKey(string key)
{
return m_LevelDictionary.ContainsKey(key);
}
/// <summary>
/// Try get a level with the given key
/// </summary>
public bool TryGetValue(string key, out LevelItem value)
{
return m_LevelDictionary.TryGetValue(key, out value);
}
/// <summary>
/// Gets the <see cref="LevelItem"/> associated with the given scene
/// </summary>
public LevelItem GetLevelByScene(string scene)
{
for (int i = 0; i < levels.Length; ++i)
{
LevelItem item = levels[i];
if (item != null &&
item.sceneName == scene)
{
return item;
}
}
return null;
}
// Explicit interface implementations
// Serialization listeners to create dictionary
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
m_LevelDictionary = levels.ToDictionary(l => l.id);
}
ICollection<LevelItem> IDictionary<string, LevelItem>.Values
{
get { return m_LevelDictionary.Values; }
}
LevelItem IList<LevelItem>.this[int i]
{
get { return levels[i]; }
set { throw new NotSupportedException("Level List is read only"); }
}
LevelItem IDictionary<string, LevelItem>.this[string key]
{
get { return m_LevelDictionary[key]; }
set { throw new NotSupportedException("Level List is read only"); }
}
void IList<LevelItem>.Insert(int index, LevelItem item)
{
throw new NotSupportedException("Level List is read only");
}
void IList<LevelItem>.RemoveAt(int index)
{
throw new NotSupportedException("Level List is read only");
}
void ICollection<LevelItem>.Add(LevelItem item)
{
throw new NotSupportedException("Level List is read only");
}
void ICollection<KeyValuePair<string, LevelItem>>.Add(KeyValuePair<string, LevelItem> item)
{
throw new NotSupportedException("Level List is read only");
}
void ICollection<KeyValuePair<string, LevelItem>>.Clear()
{
throw new NotSupportedException("Level List is read only");
}
bool ICollection<KeyValuePair<string, LevelItem>>.Contains(KeyValuePair<string, LevelItem> item)
{
return m_LevelDictionary.Contains(item);
}
void ICollection<KeyValuePair<string, LevelItem>>.CopyTo(KeyValuePair<string, LevelItem>[] array, int arrayIndex)
{
m_LevelDictionary.CopyTo(array, arrayIndex);
}
void ICollection<LevelItem>.Clear()
{
throw new NotSupportedException("Level List is read only");
}
void ICollection<LevelItem>.CopyTo(LevelItem[] array, int arrayIndex)
{
levels.CopyTo(array, arrayIndex);
}
bool ICollection<LevelItem>.Remove(LevelItem item)
{
throw new NotSupportedException("Level List is read only");
}
public IEnumerator<LevelItem> GetEnumerator()
{
return ((IList<LevelItem>) levels).GetEnumerator();
}
IEnumerator<KeyValuePair<string, LevelItem>> IEnumerable<KeyValuePair<string, LevelItem>>.GetEnumerator()
{
return m_LevelDictionary.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return levels.GetEnumerator();
}
void IDictionary<string, LevelItem>.Add(string key, LevelItem value)
{
throw new NotSupportedException("Level List is read only");
}
bool ICollection<KeyValuePair<string, LevelItem>>.Remove(KeyValuePair<string, LevelItem> item)
{
throw new NotSupportedException("Level List is read only");
}
bool IDictionary<string, LevelItem>.Remove(string key)
{
throw new NotSupportedException("Level List is read only");
}
}
}[/cce_csharp]
13行目 : 「public class LevelList : ScriptableObject, IList<LevelItem>, IDictionary<string, LevelItem>, ISerializationCallbackReceiver」は ScriptableObject を継承し、IList と IDictionary、ISerializationCallbackReceiver をインタフェースとしていることを指している。IList と IDictionary、ISerializationCallbackReceiver については DLL を呼び出すインタフェースのため、ここでは解説を省略させていただく。
112行目 : 「public LevelItem GetLevelByScene(string scene)」は LevelItem の配列から該当する Level の取得を行っている。
以降については既存の関数の呼び出しのみのため、解説はここまでとさせていただく。