Making Modules/zh
Jump to navigation
Jump to search
语言 | English | Français | Español | Deutsch | Nederlands | Русский | 한국어 | 简体中文 | 日本語 | ภาษาไทย |
---|
警 告 | AD 2023.02.13 此页面尚未与最新版本(1.7.8)同步。本模组已有新的变化并且此页面的一些信息可能已过时。 |
---|
PO 对象可以附加 模块。Procedural Objects 允许创建 定制模块类型(custom module type)以扩展 PO 的功能。本文详述 Procedural Objects 提供的 API。默认您已了解 C#编程基础 和 Cities: Skylines开发。
定制PO模块类型(custom PO module type)由2个主要部分组成:
- 1个 POModuleType 实例,规定“定制模块类型”的常规信息(名称,地图中的最大数量,等等)。
- 1个继承于 POModule 的定制类,规定模块的行为。
源代码示例:
创建一个 POModuleType[edit | edit source]
一个“定制PO模块类型”的核心是一个标准的 Cities: Skylines 模组。确认在工程引用(project references)中添加 ProceduralObjects。使用 .NET 3.5 版本或能预防 Reflection 问题。
同样允许 OnSettingsUI(UIHelperBase helper) 被实现(implement)以作模块常规设置(下方未显示)。
下方示例定义了一个“鸟群模块(BirdFlocksModule)”类型。
using UnityEngine;
using ICities;
using ProceduralObjects;
namespace BirdFlocksPOModule
{
public class BirdFlocksPOMod : LoadingExtensionBase, IUserMod
{
// 标准 C:S 模组设置
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", // 当“帮助”按钮被点击时打开的 URL(可选)
TypeID = "BirdFlocksModule", // 这是类型的唯一标识符id。它应该在模块的工坊版本更新过程中始终保持不变
ModuleType = typeof(BirdFlocksModule), // 定义作为模块的行为类的 POModule 类
// 显然您必须创建一个继承于 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 可以含有定制变量和方法
// ProceduralObjects 不使用 [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);
// do stuff here...在这里做事...
// 此方法不应该包含变量初始化(例如“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); // Render 调用必须位于 UpdateModule() 内
if (!simulationPaused)
bird.CalculateMovement(birds, cohesion, avoidance, alignment, speed, visionDist, reactivity);
}
}
public override void DrawCustomizationWindow(int id)
{
// base.DrawCustomizationWindow(id) 调用提供了基本窗口功能(关闭按钮,拖拽窗口……)
base.DrawCustomizationWindow(id);
GUI. .... // 在此使用 UnityEngine.GUI 类绘制 UI
// 扩展 UI 元素(分割线,等等)参见 ProceduralObjects.UI.GUIUtils 类
}
public override void GetData(Dictionary<string, string> data, bool forSaveGame)
{
// GetData() 调用于保存时。数据以如下方添加的 string 键/值对的形式保存。
// 若您需要根据保存目的(为游戏存档还是导出魔物而保存模块)保存不同变量,读取 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() 调用于加载时。数据以如下方读取的 string 键/值对的集合的形式加载。
// 若您需要根据加载目的(从游戏存档还是导出魔物中加载模块)加载不同变量,读取 forSaveGame 变量以区分这些情况。
// 本例仅使用 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 : 模块所附加于的父对象(parent object)
- bool enabled : 模块启用状态
- bool showWindow : 模块自定义窗口状态
- Rect window : 窗口矩形。如上所示在 OnModuleCreated() 内初始化
- POModuleType ModuleType : 已在模组中创建的 ModuleType 实例(见上方)
可实现方法[edit | edit source]
POModule 类可以实现以下方法。并非全部需要实现,选择您需要的。
- void OnModuleCreated(ProceduralObjectsLogic logic)
- 调用于游戏内模块创建时,无论是通过复制/粘贴、创建还是加载。此方法应考虑已启用域(enabled field),以备克隆模块之需。当加载存档而使用时,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()(每帧)(仅在模块启用时)。此处为 Render 调用的位置。
- void LoadData(Dictionary<string, string> data)
- 用提供的数据集(data set)初始化模块。此方法在 OnModuleCreated() 之前被调用。
- void GetData(Dictionary<string, string> data)
- 当加载 LoadData() 时用 GetData() 内的 data.Add(string,string) 调用作为“键/值数据对”(Key/Value data pairs)。
- void DrawCustomizationWindow(int id)
- 模块窗口绘制功能(使用 UnityEngine.GUI 方法)。使用 Rect window 域。如上示例所示在 OnModuleCreated() 内定义窗口大小。base.DrawCustomizationWindow(id) 调用提供了基本窗口功能(关闭按钮,拖拽窗口……)。
- POModule Clone()
- 在克隆或复制/粘贴时使用。如果不实现此方法将使用 object.MemberwiseClone()。请提供实现,如果需要 深复制。