Making Modules/ja
Jump to navigation
Jump to search
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
---|
ここで作成したモジュール(MOD)は、モジュールの管理からオブジェクトに機能を追加できます。
Procedural Objectsには、オブジェクトに機能の追加・拡張が出来るように、カスタムモジュールタイプの作成が可能です。
このページでは、PO用のモジュールで提供可能なAPIについて詳しく説明します。
C# programmingとModding for Cities:Skylinesを理解していることが前提条件となります。
カスタムPOモジュールタイプは、2つの主要なコンポーネントで構成されています。
- POModuleType : カスタムモジュールタイプに関する、一般的なインスタンスの情報を提供します。(名前・マップ上の最大数など)
- POModuleを継承したカスタムクラスで、モジュールの動作を提供します。
ソースコードの例
POModuleTypeの作成[edit | edit source]
カスタムPOモジュールタイプのコア部分は、Cities:Skylinesで開発する標準的なMODとほとんど変わりません。
- プロジェクトの参照には、ProceduralObjectsを必ず追加してください。
- また、.NETはバージョン 3.5を使用すると、Reflection問題を防ぐことができます。
- これによりモジュールへの一般的な設定で、OnSettingsUI(UIHelperBase helper)を実装することも可能です。(解説は省略)
以下の例では、「BirdFlocksModule」のモジュールタイプを起動しています。
using UnityEngine;
using ICities;
using ProceduralObjects;
namespace BirdFlocksPOModule
{
public class BirdFlocksPOMod : LoadingExtensionBase, IUserMod
{
// 標準的なC:S MODの初期化
public string Name { get { return "Bird Flocks Module"; } }
public string Description { get { return "Bird flocks module for Procedural Objects"; } }
private POModuleType moduleType;
public override void OnCreated(ILoading loading)
{
base.OnCreated(loading);
if (moduleType == null)
{
moduleType = new POModuleType()
{
Name = Name,
Author = "Simon Royer",
help_URL = "http://wwww.mywebsite.com/birdflockshelp", // help_URL : ヘルプボタンがクリックされたときに開くURLを指定(オプション)
TypeID = "BirdFlocksModule", // TypeID : 名前部分に相当してユニークなIDにします。アップデートしても同じIDを維持する必要があります。
ModuleType = typeof(BirdFlocksModule), // ModuleType : POModuleクラスが、ModuleTypeの動作クラスとして定義されます。
// もちろん、POModuleを継承したBirdFlocksModuleクラスも作る必要があります。(以下参照)
maxModulesOnMap = 100, // 0に設定すると、モジュールの設置制限はありません。
keepOpenWhenLeaveObj = false // 親オブジェクトから編集モードの終了時に、モジュールのタブを開いた状態にしたい場合は、trueに設定します。
};
}
if (!ProceduralObjectsMod.ModuleTypes.Contains(moduleType))
ProceduralObjectsMod.ModuleTypes.Add(moduleType); // POModuleTypeをProcedural Objectsでサポートされるタイプのリストに追加します。
}
public override void OnReleased()
{
base.OnReleased();
if (moduleType == null)
return;
if (ProceduralObjectsMod.ModuleTypes.Contains(moduleType))
ProceduralObjectsMod.ModuleTypes.Remove(moduleType);
}
}
}
POModuleから継承したカスタムクラス[edit | edit source]
モジュールタイプの動作は、POModuleクラスを継承したカスタムクラスの内部で定義されます。
namespace BirdFlocksPOModule
{
public class BirdFlocksModule : POModule
{
// POModuleは、カスタム変数やメソッドを持つことができます。
// Procedural Objectsは、[Serializable]を使用しません。保存するには、GetData()とLoadData()を実装します。
public List<BirdAgent> birds;
public int BirdsCount;
public Mesh birdMesh;
public Material birdMaterial;
private bool switchBackCalculation;
private float cohesion = 5f, avoidance = 2f, alignment = 3f, speed = 2f, visionDist = 35f, reactivity = .7f;
public override void OnModuleCreated(ProceduralObjectsLogic logic)
{
base.OnModuleCreated(logic);
// カスタマイズ・ウィンドウのサイズを初期化します。位置は余り関係ありません。
window = new Rect(0, 0, 325, 175);
// ここで色々なことを行っています。
// この方法では、変数の初期化宣言(例えば、cohesion = 5fなど)を含めてはいけません。
// なぜなら、このメソッドはロード後にも再び呼ばれるので、ロードされたデータが壊れます。
// 代わりに、デフォルト値を上記のように設定する必要があります。
}
public override void UpdateModule(ProceduralObjectsLogic logic, bool simulationPaused, bool layerVisible)
{
// UpdateModule()は、モジュールが有効になるとUpdate()の中で実行されます。
for (int i = 0; i < birds.Count; i++)
{
var bird = birds[i];
bird.Render(birdMesh, birdMaterial); // レンダリングの呼び出しは、UpdateModule()内に配置する必要があります。
if (!simulationPaused)
bird.CalculateMovement(birds, cohesion, avoidance, alignment, speed, visionDist, reactivity);
}
}
public override void DrawCustomizationWindow(int id)
{
// DrawCustomizationWindow(id)の呼び出しは、基本的なウィンドウ機能を提供します。(閉じるボタン、ウィンドウのドラッグ機能など)
base.DrawCustomizationWindow(id);
GUI. .... // ここでは、UnityEngineGUIクラスを使ってUIを描画しています。
// 拡張されたUI要素(セパレータなど)については、ProceduralObjects.UI.GUIUtilsクラスを参照してください。
}
public override void GetData(Dictionary<string, string> data, bool forSaveGame)
{
// GetData()は、保存先の場所を指定します。 データ形式は識別の文字列と、「キー/値」のセットで保存されます。
// データの保存方法(セーブゲームに保存、またはエクスポート用にモジュールを保存)に応じて異なる変数を保存する必要がある場合は、
// forSaveGame変数を読んで各ケースを識別してください。
data.Add("birdsCount", BirdsCount.ToString());
data.Add("cohesion", cohesion.ToString());
data.Add("avoidance", avoidance.ToString());
data.Add("alignment", alignment.ToString());
data.Add("speed", speed.ToString());
data.Add("visionDist", visionDist.ToString());
data.Add("reactivity", reactivity.ToString());
}
public override void LoadData(Dictionary<string, string> data, bool fromSaveGame)
{
// LoadData()は、ロード処理が発生する場所です。 前述したデータ形式は識別の文字列と、「キー/値」のセットでロードされます。
// ロード処理の目的(セーブゲームに保存、またはエクスポート用にモジュールを保存)に応じて異なる変数をロードする場合は、
// fromSaveGame変数を読み取って各ケースを識別します。
// 下記の例ではfloat解析のみ行っていますが、独自の解析プロセスも実装可能です。
// そして、if構文を使用して変数の有無を常に確認してください。
// 注意点: これらの変数のデフォルト値はOnModuleCreated()やその他のメソッドではなく、クラスの先頭で宣言する必要があります。
if (data.ContainsKey("birdsCount"))
BirdsCount = int.Parse(data["birdsCount"]);
if (data.ContainsKey("cohesion"))
cohesion = float.Parse(data["cohesion"]);
if (data.ContainsKey("avoidance"))
avoidance = float.Parse(data["avoidance"]);
if (data.ContainsKey("alignment"))
alignment = float.Parse(data["alignment"]);
if (data.ContainsKey("speed"))
speed = float.Parse(data["speed"]);
if (data.ContainsKey("visionDist"))
visionDist = float.Parse(data["visionDist"]);
if (data.ContainsKey("reactivity"))
reactivity = float.Parse(data["reactivity"]);
}
}
}
継承されるメンバー[edit | edit source]
POModuleの継承クラスは、以下のメンバーをPOModuleから継承します。
- ProceduralObject parentObject : モジュールが実装されている親オブジェクト
- bool enabled : モジュールの有効化の状態
- bool showWindow : モジュールのカスタマイズ・ウィンドウの状態
- Rect window : ウィンドウの矩形を指定します。上記のようにOnModuleCreated()で初期化
- POModuleType ModuleType : MODに設定されている、ModuleTypeのインスタンス(上記参照)
実装可能なメソッド[edit | edit source]
POModuleクラスは以下のメソッドを実装できます。全てを実装する必要はないので、必要なものを選んでください。
- void OnModuleCreated(ProceduralObjectsLogic logic)
- コピー・ペーストや作成・ロードなど、ゲーム内でモジュール作成時に呼び出されます。
- このメソッドはモジュールのクローン作成時に必要になる可能性があるため、有効なフィールドを考慮する必要があります。
- ロードで使用する場合のLoadData()は、OnModuleCreated()の前に呼び出されます。
- void OnModuleRemoved(ProceduralObjectsLogic logic)
- 親オブジェクトの削除やモジュールの削除時に呼び出されます。
- void OnModuleEnabled(ProceduralObjectsLogic logic)
- モジュールが有効化した場合に呼び出されます。
- モジュールの管理タブから、モジュールタイプ全体を有効化した場合は呼び出されません。
- void OnModuleDisabled(ProceduralObjectsLogic logic)
- モジュールが無効化された場合に呼び出されます。
- モジュールの管理タブから、モジュールタイプ全体を無効化にした場合は呼び出されません。
- void OnModuleWindowOpen(ProceduralObjectsLogic logic)
- モジュールウィンドウが開いたときに呼び出されます。
- void OnModuleWindowClose(ProceduralObjectsLogic logic)
- モジュールウィンドウが閉じたときに呼び出されます。
- void OnParentPositionSet(ProceduralObjectsLogic logic, Vector3 oldPosition, Vector3 newPosition)
- 親オブジェクトの位置が変更したときに呼び出されます。
- void OnParentRotationSet(ProceduralObjectsLogic logic, Quaternion oldRotation, Quaternion newRotation)
- 親オブジェクトの回転が変更したときに呼び出されます。
- void OnApplyModelChange(Vertex[] vertices)
- 親オブジェクトのモデルへ、変更が適用されたときに呼び出されます。
- void UpdateModule(ProceduralObjectsLogic logic, bool simulationPaused, bool layerVisible)
- モジュールが有効な場合に限り、Update()でフレームごとに呼び出されます。
- ここでレンダーの呼び出しが行われます。
- void LoadData(Dictionary<string, string> data)
- 提供されたデータセットでモジュールを初期化します。
- このメソッドは、OnModuleCreated()より前に呼び出されます。
- void GetData(Dictionary<string, string> data)
- GetData()のdata.Add(string,string)の呼び出しを使用して、LoadData()のロード時に、Key/Valueのデータをペアにして使用します。
- void DrawCustomizationWindow(int id)
- モジュールのウィンドウ描画機能です。(UnityEngine.GUIメソッドを使用)
- Rect windowのフィールドを使用します。
- 上記の例のように、OnModuleCreated()でwindowのサイズを定義します。
- base.DrawCustomizationWindow(id)の呼び出しは、基本的なウィンドウの機能を提供します。(閉じるボタン、ウィンドウのドラッグ機能など)
- POModule Clone()
- クローンの作成やコピー&ペースト時に使用されます。
- 実装されていない場合は、object.MemberwiseClone()を使用します。
- より詳細なコピーが必要な場合は、deeper copy is requiredを参照してください。