jaijai’s blog

Cities Skylinesアセット作成に関するメモ・考察

サブメッシュ名にランダム値を加える

サブメッシュ名にランダム値を追加するスクリプトです。

サブメッシュ名に起因するアセットセーブ不良問題

この問題は車両アセットにおいて複数のサブメッシュを含むアセットを正しく保存できない現象を指します。これが起こると、保存したアセットが不正なアセットと認識されたり、正常に読み込まれたように見えて実は壊れているなど、インゲームで確認するまで問題が露見しないこともあり非常に厄介です。何かの拍子に正常に保存できることもあります。

幸いにもこの問題は解明され、複数の同名サブメッシュに起因することが明らかとなりました。

サブメッシュの名前

通常はサブメッシュ名はfbxのファイル名と同一になります。よって、すべてのサブメッシュを違うファイル名にしておけばこのスクリプトを使わずとも問題を回避できます。

サブメッシュ名を変更するにはm_subInfo.nameを変更します。Scene Explorerを使って手動で任意の名前に変更することもできます。

多量のサブメッシュを何度も使い回す場合はサブメッシュ名を変更するほうが楽なのでこのスクリプトの出番です。

サブメッシュ達の名前を変更する

このスクリプトでは生成したGUIDから連続する8文字を切り出しm_subInfo.nameの末尾に加えます。

例えば26FDE9ED06BC4D0F8773CB399E73EB6CというGUIDを生成したとすると6文字目から9ED06BC4を取り出します。取り出す位置はランダムです。この方法では完全にユニークな値になる保証はありませんが概ね問題ない範囲かと思います。

追加の機能として(Clone)も除去します。アセットをロードした場合に同名サブメッシュが存在する場合に追加される末尾の数字も除去します。

サブメッシュ名が変更されることは想定されていないと思うのでアセットセーブ直前に走らせることを推奨します。

int[] ignoreList = {0}; //{0, 2, 3};
var appendGUID = true;

var asset = ToolsModifierControl.toolController.m_editPrefabInfo as VehicleInfo;
var reg1 = new System.Text.RegularExpressions.Regex(@"\(.+\)$");
var reg2 = new System.Text.RegularExpressions.Regex(@"(.+)(\s\d$)");
var reg3 = new System.Text.RegularExpressions.Regex(@"\(Clone\)");

for (int i = 0; i < asset.m_subMeshes.Length; i++){
    if (ignoreList.Contains(i)) continue;
    var name = reg3.Replace(asset.m_subMeshes[i].m_subInfo.name, "");
    var id = Guid.NewGuid().ToString("N").Substring(UnityEngine.Random.Range(0, 23), 8).ToUpper();
    if (appendGUID) {
        asset.m_subMeshes[i].m_subInfo.name = reg2.Replace(reg1.Replace(name, ""), "$1") + "(" + id + ")";
    }else{
        asset.m_subMeshes[i].m_subInfo.name = name;
    }
}

1行目のリストには変更したくないサブメッシュのインデックス値を含めることができます。2行目をfalseにすると(Clone)消しだけのスクリプトになります。

このスクリプトで名前が変更されたサブメッシュ達はこんなかんじになります。 f:id:jaijai_lt:20201021021846p:plain