Stride(.NET製ゲームエンジン)でアセットをnugetで共有する

# はじめに

[Stride](https://www.stride3d.net)という.NET製ゲームエンジンがある。
特徴を簡単に言うと、

* ランタイムは.NETランタイム
    * F#で開発できるかどうかは未確認
* パッケージ共有はnuget
* 開発はVS推奨
* 開発環境はWindowsのみだが、異なるプラットフォーム向けのパッケージを作ることは可能
    * .NETランタイムの対応状況に依存する

等、.NETに全面的に乗ったエコシステムで開発が可能というところにある(ただし、開発環境は現時点でWindowsのみ可)。

で、モデルやマテリアル(素材)等もアセットとしてnugetパッケージで共有できるわけだが、公式マニュアルの該当ページだけだと参照がうまくできなかったので、自分なりに調べた方法を記載する。
なお、同一ソリューション内にあるということならば、アセットの参照はProjectReferenceだけで可能である。

なお、執筆時点のStrideのバージョンは4.1.0.1948である。

[Stride自体の導入、操作方法は公式マニュアルを参照すること](https://doc.stride3d.net/latest/jp/manual/)

# プロジェクトの作成

公開するパッケージを作るには、まず"Code Library"テンプレートから作成を行う。
これはStrideランチャーか、あるいはStrideエディタのプロジェクト追加から行うことができる。

ただし、注意してほしいのは、**新規作成した直後のリストアは必ず失敗する**ことだ。
これは、Code LibraryプロジェクトのTargetFrameworkが"uap"を含んでいるからで、Strideのライブラリ群は4.1.0.1948の時点で"uap"をサポートしていないことによる。
しかし、リストアには失敗するものの、プロジェクトの生成とslnへの追加自体は成功しているので、次のステップに進むことはできる。

## Strideランチャーなしでの作成

上記エラーを回避するために、Strideランチャー無しでのプロジェクト新規作成というのもできなくはない。
手順は以下。

1. ソリューションファイル(sln)を用意
2. VS等でnet6.0のC#クラスライブラリプロジェクトを作成
    * strideエディタの仕様上slnファイルが起点となるので、必ず対応するslnを作っておくこと
3. csprojに後述のようにしてStride関連パッケージの追加
4. sdpkgファイルを作る
    * sdpkg自体はyamlファイルとなっているが、仕様がどうなってるか不明なので、他のプロジェクトからひな形コピーした後で自分のプロジェクトに追加して、名前等必要なところを直す。
5. Assets、Resourcesディレクトリを作成する

```xml:csproj
  <ItemGroup>
    <PackageReference Include="Stride.Engine" Version="4.1.0.1948" PrivateAssets="contentfiles;analyzers" />

    <PackageReference Include="Stride.Video" Version="4.1.0.1948" PrivateAssets="contentfiles;analyzers" />
    <PackageReference Include="Stride.Physics" Version="4.1.0.1948" PrivateAssets="contentfiles;analyzers" />
    <PackageReference Include="Stride.Navigation" Version="4.1.0.1948" PrivateAssets="contentfiles;analyzers" />
    <PackageReference Include="Stride.Particles" Version="4.1.0.1948" PrivateAssets="contentfiles;analyzers" />
    <PackageReference Include="Stride.UI" Version="4.1.0.1948" PrivateAssets="contentfiles;analyzers" />
    <PackageReference Include="Stride.Core" Version="4.1.0.1948" PrivateAssets="contentfiles;analyzers" />

    <PackageReference Include="Stride.Core.Assets.CompilerApp" Version="4.1.0.1948" PrivateAssets="contentfiles;analyzers" IncludeAssets="build" />
  </ItemGroup>
```

# TargetFrameworkの修正

新規作成した後、まずするべきことはTargetFrameworkの修正となる。
特にプラットフォーム固有の要件が無ければ、VSあるいはVSCodeでTargetFrameworkを"net6.0"単独に直しておく。

# nugetパッケージへの追加

公開プロジェクトの方に必要なアセットを追加した後、アセットファイルをnugetパッケージに追加する必要がある。
そうしないと、作成したnugetパッケージを参照しても、Strideエディタがアセットを認識してくれない状態になる。

具体的にはどうすればいいかというと、csprojで以下のItemGroupを追加する必要がある。

```xml
<ItemGroup>
  <!-- sdpkgに関してはStride側で何らかの参照をしてると思われるが、実際どのような影響を与えているかは不明 -->
  <None Include="*.sdpkg" Pack="True" PackagePath="stride"/>
  <None Include="Assets/*.sd*" Pack="True" PackagePath="stride/Assets"/>
  <!-- 追加の画像ファイルや3Dモデルファイル等が必要な場合 -->
  <None Include="Resources/**/*" Pack="True" PackagePath="stride/Resources"/>
</ItemGroup>
```

ここでの肝は、**sdpkgファイルとAssetsフォルダ以下のファイルをnugetパッケージ内の"stride"に含める**という所となる。
テクスチャ等、何らかの外部ファイルを使うアセットの場合は、アセットファイル内に書かれている参照パスの通りにnugetパッケージ内の位置を合わせる必要がある(大抵の場合Resources)。

# nugetパッケージの参照

プロジェクトファイルの編集とアセットの作成を終えた後は、公開プロジェクトの方でnugetパッケージを作成することになる。
これは普通にVS右クリックメニューの「パック」か、あるいは`dotnet pack`コマンドでnupkgを作成すれば良い。
念のため、nupkgの拡張子をzipに変更してzipアーカイブとして読み込み、期待通りの配置になっているかを確認する。

後は、パッケージを使いたいプロジェクトの方で、通常のC#プロジェクトのように"PackageReference"に追加すればいいだけとなる(VS等で行う)。
ローカルディレクトリで使いたい場合は、nuget.configファイルの編集を忘れないようにしておこう。

注意点として、**表示が更新されない場合があるので、参照追加後にStrideエディタでビルドを行っておく**
この辺りの挙動は今後のバージョンで変更される可能性があるので注意。

追加してStrideエディタでビルドすると、"ソリューション"ビューの"外部のパッケージ"の配下にPackageReferenceに追加したパッケージが追加されているはず。
そこから"Assets"ツリーを開いて、"アセットビュー"に表示されたアセットを追加すれば、アセットとして使えるようになる。
![stride-slnview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103253/37065ff2-962a-57ee-32ba-834bbe764ab2.png)

注意点として、外部パッケージにあるアセットは読み込み専用で、編集ができない。
このため、参照追加したパッケージに含まれるアセットを、ちょっと設定を変えて使いたい場合等は不便かもしれない。
この辺りはもしかしたら今後のバージョンで何らかの変更が入るかもしれない。

# おわりに

実は[Strideは次の大型アップデート(4.2)を目前に控えている](https://www.stride3d.net/blog/community-meeting-october-2023/)ので、この記事で書かれたやり方というのはそこで陳腐化する可能性はなくはない。
そのような場合には、改めて記事の構成を大幅に変えるかもしれない。

Unityの移行先としてよく名前に挙がるgodotに比べるとこちらの知名度はいまいちなことは否めない。しかし.NETに馴染みのある人にとっては、良くも悪くも.NETに全振りなstrideも一考の価値はあるのではないかと思っている。