【CSLModding】AnimUV Paramsを学習しました

CSLMOD

様々な技巧が必要になるアセット制作。「モデリング」「テクスチャリング」「UV展開」「インポート」という4つの手続きが上手くできればそれはそれは立派なプロップを制作することができるようになります。既に4つの手続きがクソ壮大にしてクソ面倒なので、これらを学習して実践、公開した時点でスーパー素晴らしいに違いありません。

しかしシティーズ上で機能するアセット、例えば道路であるとか、線路、信号、ビル、公園、市民などを実装するためには、さらに「Citiesの仕様」を理解せねばなりません。仕様があれば必ず制約もあります。作れないものに時間を割くのは余りにもったいないことですからね。ネットワークにはどのようなことができて、どのようなことができないのか。どのような機能が求められて、その機能は本当に実装できるのか。開発するよりも前に仕様を理解していることが望ましいでしょう。

そして、Citiesの仕様を理解したうえで、さらに高度なアセットを作る手続きがあります。それはアセットの仕様を一部書き換える「スクリプトの実行」です。Modtoolsというコンソール展開が可能なツールを用いてCities.exe、つまりシステムに直接スクリプトを流し込みます。これによりパロメーターを一部を書き換えることができます。一歩間違えればシステムを破壊しかねませんが、うまく活用すればそれはそれはグレートなアセットを作り上げることができます。

「モデリング」「テクスチャリング」「UV展開」「インポート」「仕様と制約」「スクリプト」。これら6つの手続きを踏むことで、シティーズでの挙動まで制御された高度なアセットが制作できるようになります。

今回はスクリプトを流し込んで調整するパロメーターの1つである「AnimUV Params」について、今回制作したアセットと共に解説していきます。なるべく分かりやすい説明に努めますが、仕様の項ではAnimUVについてディープに解説しますので、お好みで読んでいただければと思います。

また信号を作りました

以前から信号機プロップをいくつか公開している筆者ですが、また信号機を制作しました。

一灯点滅式の信号機です。

Steam Workshop::【JPTL】Japanese Blinking Signal

しかしこの信号機は、既にワークショップにあるアイテムに酷似しています。そう、これは前回記事/JPTL Koito信号機と同様に、既存のアセットをfix版として公開したアセットなのです。

背景

シティーズの歴史も長いので、前回改修したJPTL Koitoのように、アセット自体は素晴らしいものでもアセットを取り巻くMOD環境などの変化によって使えなくなってしまったアセットも多々あるのです。

今回改修した一灯点滅式信号機は、ako_ako氏によって公開されたプロップパックであり、現在も公開されています。しかしこれもアセットを取り巻く環境の変化によって、使いづらいアセットとなってしまっています。その主な原因は、一灯点滅式信号機の動作に必要な「AnimUV Params」というMODがが古びてしまったことです。

モデルや作者様に非がないアセットを再び使えるようにしたいと思い、Fixを決意しました。

「AnimUV Params」について

AnimUVがあれば、ゲーム内時間の経過とともに、色や柄を一定周期で変化させることができます。

先の時代においては、AnimUVパロメーターの付与には「AnimUV Params」というMODが必要だとされてきましたが、パロメーターを付与する対象がPropに限って、AnimUV Params Modがなくとも動作させられるスクリプトが発見されました。

ところが、スクリプト発見前にAnimUV Params Modがある状態で開発された旧来のPropについては、AnimUV Params Modがないと挙動しないのです。

そして、AnimUV Params Modの作者である Ronyx69氏がMOD開発から引退されてから数年、現在はAnimUV Params Modに不具合があると報告されています。これに伴い、旧来のAnimUVを使ったアセットを使いづらいよねという流れになります。

修正内容について

話の流れで分かるとは思いますが、一灯点滅式信号機は、スクリプト発見以前に開発された、AnimUV Paramsが前提MODとして必要なアセットです。従って、モデルの複製と、意図通りのスクリプトを流してインポートが実行できればFixできそうです。

複製した一部テクスチャやUVについては、AnimUVの挙動上整合性のない部分を修正し、インポートでは新しく発見されたスクリプトを改変したものを流し込み、修正は完了しました(流し込んだスクリプトに関する情報は仕様の項で詳しく解説します)。

応用

AnimUVの仕様を理解した筆者は、このように点滅させられるなら、と思い立ちこちらもAnimUVを使ったアセットを制作しました。

Steam Workshop::【JPTL】Japanese Blinking Traffic Light

押しボタン式信号で見られる、3灯の点滅式信号機です。これも仕様の項にて実際に流したスクリプトを公開しておきます。

その他、同じくAnimUV Params Modを前提MODとするako_akoさんのブリンカーライトについても、今後修正予定ですので、しばしお待ちくださいませ。

仕様

『「AnimUV Params」について』の項で、AnimUV Params を「ゲーム内時間の経過とともに、色や柄を一定周期で変化させることができる」と説明しましたが、この説明では少し乱暴です。仕組みから端的に表すならば「展開したUVを時間経過とともにスクロールさせるパロメーター」と言えます。

メッシュとテクスチャとの関係は、折る前後の折り紙のようなもので、平面(テクスチャ)で表した色や柄などの情報を立体(メッシュ)のどの面に割り当てるのか規定しています。この割り当てのことをUV、UVの規定作業のことをUV展開と言います。

ここで規定したUVの場所をスクロールさせていくのがAnimUVパロメーターという訳です。

AnimUV Params Mod の作者である Ronyx69氏のサイト「CSL Modding」にはCSLアセット制作に関する様々な資料が体系的に準備されていて、その中にはAnimUVに関する資料も残されています。AnimUV Params Modが必要なくなった、改良後のAnimUV Params 用のスクリプトがこちら。

何が書いてあるか読むのもうんざりという方のためにめっちゃ噛み砕いて説明します。

ここには流せる2つのスクリプトについて記述があり、今回流したのは後半にある高度なスクリプトです。こちらにフォーカスしてみます。

変数:txに 1f を代入
※1フレームで平行方向にスクロールする距離。tx = 1fなら、画像を1周するため、変化なし。
変数:tyに 1f を代入
※1フレームで垂直方向にスクロールする距離。ty = 1fなら、画像を1周するため、変化なし。
変数:framesに 30f を代入
※1サイクルを何フレームとするか。frames = 30fなら、UVを初期位置から30回スクロールする。
変数:cyclesに 60f を代入
※サイクルは1分間に何回起こすのか。cycles = 60fなら、1秒でサイクルが丁度1周する。

{
変数: asset は PropInfo と同義でなんたらかんたらと保存するやで
変数: shader は AnimUV って名前のシェーダーをファイルを探して割り当てるで
既知の変数: asset.m_material の shader も shader と同じように割り当てるで
変数: vec には tx,ty,frames,cyclesという4つのデータを持たせるで
既知の変数: asset.m_material の SetVector に vec となんたらかんたらを代入するで
変数: vectorProps は どうたらこうたらっていう文字列にするねん
vectorPropsの6文字目はどうたらこうたらにするで
}

筆高度なスクリプトの後半部分、スクリプトの肝の部分の仕組みは筆者には分かりかねますが、とにかく大事なのが tx, ty, frames, cycles という4つのパロメーターの指定です。日本語で書き下しましたので、上のパロメーターを実行すると、特段のスクロールが発生しないことはお分かりでしょうか。1分間に60サイクル、1サイクル29回スクロールなので、30fpsの挙動をしていますが、移動した結果同じ場所に戻ってくる挙動になっているからですね。

実際に一灯点滅式信号機に流したスクリプトがこちら。

var tx = 1f; // X coordinate transform amount, 1f = full width of image
var ty = -200/512f; // Y coordinate transform amount, 1f = full height of image
var frames = 2f; // Amount of transforms per cycle. Amount of animation frames.
var cycles = 50f; // Animation cycles per minute.

var asset = ToolsModifierControl.toolController.m_editPrefabInfo as PropInfo;
var shader = Shader.Find("Custom/Props/Prop/AnimUV");
asset.m_material.shader = shader;
shader = Shader.Find("Custom/Props/Prop/Default");
asset.m_lodMaterial.shader = shader;
var vec = new Vector4(tx, ty, frames, cycles);
asset.m_material.SetVector("_RollParams0", vec);
var vectorProps = Type.GetType("ColossalFramework.Packaging.ShaderUtil, ColossalManaged").GetField("vectorProps").GetValue(null) as string[];
vectorProps[5] = "_RollParams0";

1分間に50サイクル、1サイクルに1回だけスクロールするので、1分間に100回だけ、元のUVと200ピクセルだけずれたUVを交互に表示する挙動をさせています。これにより、一灯点滅式信号の点灯と消灯を表現しているのです。

同様に、3灯の点滅式信号機に流したスクリプトがこちら。

var tx = 1f; // X coordinate transform amount, 1f = full width of image
var ty = -103/256f; // Y coordinate transform amount, 1f = full height of image
var frames = 2f; // Amount of transforms per cycle. Amount of animation frames.
var cycles = 50f; // Animation cycles per minute.
var lod_ty = -1/2f; // lod animUV params

var asset = ToolsModifierControl.toolController.m_editPrefabInfo as PropInfo;
var shader = Shader.Find("Custom/Props/Prop/AnimUV");
var shader_lod = Shader.Find("Custom/Props/Prop/AnimUV");
asset.m_material.shader = shader;
asset.m_lodMaterial.shader = shader_lod;
var vec = new Vector4(tx, ty, frames, cycles);
var vec_lod = new Vector4(tx, lod_ty, frames, cycles);
asset.m_material.SetVector("_RollParams0", vec);
asset.m_lodMaterial.SetVector("_RollParams0", vec_lod);
var vectorProps = Type.GetType("ColossalFramework.Packaging.ShaderUtil, ColossalManaged").GetField("vectorProps").GetValue(null) as string[];
vectorProps[5] = "_RollParams0";

どちらのスクリプトにも共通して、tx, ty の移動量には、テクスチャ全体のピクセル数の中において、何ピクセルだけ挙動するか、そのまま数字を記述しています。こうした方が分かりやすくて正確です。

また、こちらには LODに対してもAnimUV Paramsを適用しており、実は遠目からでも信号が点滅するようにモデルを仕込んでいたりします。その際には、強調した部分の通り、LODマテリアルへ各個移動量(lod_ty)やシェーダー(shader_lod)を定義・代入し忘れないようにしましょう。

C#を理解しろとは言いませんが、仕組みが分かればシティーズに実装できるアセットの幅も広がり、あなたにしか作れないアセットが生まれるかもしれません。

終わりに

いかがだったでしょうか。筆者がある程度仕組みを理解した状態で初めてまともに使えたスクリプト。そしてAnimUV Params。動的なアセットを作るために理解しなければならない要素の1つです。

ま、この記事を読んでいる人の中にアセットを作れる人がどれだけいるかという話ではありますが。

一般市長方は、筆者がAnimUV Paramsが使えるようになったという理解でおkです。

以上、筆者自身の備忘録を兼ねた報告でした。御参考までに。

コメント

タイトルとURLをコピーしました