Making Modules/ja

From Procedural Objects
Jump to navigation Jump to search
    I18n.png  言語 En flag.jpg English Fr flag.png Français Es flag.png Español De flag.jpg Deutsch Nl flag.png Nederlands Ru flag.jpg Русский Ko flag.png 한국어 Zh flag.png 简体中文 Ja flag.png 日本語 Th flag.png ภาษาไทย


ここで作成したモジュール(MOD)は、モジュールの管理からオブジェクトに機能を追加できます。
Procedural Objectsには、オブジェクトに機能の追加・拡張が出来るように、カスタムモジュールタイプの作成が可能です。

このページでは、PO用のモジュールで提供可能なAPIについて詳しく説明します。
C# programmingModding 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を参照してください。