YAMADA TAISHI’s diary

ゲームについてとか私の日記とか。このブログのあらゆるコードは好きにどうぞ。利用規約があるものは記事内のGitHubのRepositoryのリンクで貼られていると思うので、そちらを参照ください。

Unityで超絶シンプルな頂点ペイントツールを雑につくったった

こんにちは、やまだたいし( やまだ たいし (@OrotiYamatano) / X )です。
雑に頂点ペイントツールを作ったので公開です。
せっかく作ったので公開しておこうかなと。

目次


経緯


現在オリジナルShaderを趣味で作っている。
そこで、頂点カラーを使って法線を設定しているのだが、Unity上で指定したくなった。
なので作った。

ペイントツールとしては若干使いづらい作りにはなっているが、まぁ使えなくはないし、
似たようなツールを作ろうとしている人に参考になるかと思って公開することにしました。

コード


使い方


↑上記コードをコピってきてEditorファイルに入れる。

Windowの中にメニューが有る

メニュー

チェックを入れた色が該当色のパラメーターが上書きされるようにしました。
基本的には全部にチェックを入れればいいです。

Alphaだけ1以上入力できますが、気にしないで。

で、塗りたいオブジェクトをシーンビューで選択し、
EnterEditModeをクリックするとメッシュコライダーがアタッチされて編集モードになります。

後は塗るだけ。

終わったら基本Exit Edit Modeで戻りましょう。

一応アンドゥにも対応してるので間違ってペイントしたらコントロールZで戻れます。

一応マテリアルの作り方も紹介しておく


ここにたどり着いた方には説明必要ないと思うが
マテリアルのバーテックスカラーを確認できるURPマテリアルの作り方を紹介しておく。

ShaderグラフをLitShaderGraphで作る。
適当な名前をつける

ノードでVertex Colorを選択する。

BaseColorに接続

ShaderはこれでOK

マテリアルを作る。
適当に名付ける

シェーダーグラフで作ったシェーダーを割り当てる。
私は雑にvartと名付けたのでこれ.(せめてvertにしよって突っ込まれそう)

これでおk。

まとめ


以上おわり。
やまだたいしでした。

【Unity】GameObjectがActiveの場合にSetActiveした時の負荷は?

こんにちは、やまだたいし( やまだ たいし (@OrotiYamatano) / X )です。
この間、仕事中にUnityでGameObjectがActiveの場合にSetActiveをしてしまうコードを書いてしまっていました。
そこで、プルリクにて負荷をできるだけ減らしたいので辞めて欲しいと言われました。
実際のところ負荷はどの程度なのか気になったので、今回は負荷検証をしていきたいと思います。

目次


前提


Unity2022.3.7f1にて検証
DeepProfileをつけた状態で
1万個キューブを作成しかかる時間を測定しました。

結論


まず、ぐだぐだと書くのもなんなのでまずは結論を書いておきます。
フラグを立てて自前で処理する場合は確かに自身に対する処理速度は早くなる可能性があるが
結局ifの処理を挟むということはチェックが必ず必要ということでもあるのでデメリットも有る。
とはいえ、ActiveToActiveはぶっちゃけ気にする程度の処理負荷は出ない。
というのが私の見解です。

具体的にどのような負荷検証をしたのか


以下のようなシーンを用意。

スポーンするキューブはこれ。

スポーンするオブジェクトにアタッチされたコンポーネントはこれ。

Canvasに以下のようなスクリプトをアタッチ

using System.Collections.Generic;
using UnityEngine;

public class ActivateScript : MonoBehaviour
{
    [SerializeField] private GameObject cube;

    private List<GameObject> objects = new ();
    
    // Start is called before the first frame update
    void Start()
    {
        for (int i = 0; i < 10000; i++)
        {
            objects.Add(Instantiate(cube));
        }
    }

    public void SetActivate()
    {
        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
        sw.Start();
        foreach (var item in objects)
        {
            item.SetActive(true);
        }
        sw.Stop();
        Debug.Log(sw.Elapsed);
    }

    public void SetDeactivate()
    {
        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
        sw.Start();
        foreach (var item in objects)
        {
            item.SetActive(false);
        }
        sw.Stop();
        Debug.Log(sw.Elapsed);
    }
}

スポーンするオブジェクトにはこのようなコードをアタッチ

using UnityEngine;

public class Test : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Debug.Log("Start");
    }

    private void OnEnable()
    {
        Debug.Log("OnEnable");
    }

    private void OnDisable()
    {
        Debug.Log("OnDisable");
    }

動作確認


まずは動作確認がてら、全オブジェクトをアクティブ、非アクティブを切り替えてみる。

まずはアクティブ状態化から非アクティブ化
OnEnableでのログも走るし、普通に負荷があると思われる。

まぁ1秒以上かかる

ちなみに1000ミリ秒1秒なので、60fpsで動作させるためには約16ms以内に終わらす必要がある。

非アクティブ状態からアクティブ化

こちらも結構な時間がかかる。

いざ検証。


Deep ProfileをOnにした状態で、エディタの検証をしてみる。

Active To Active

確かに負荷がかかる。
1万個のオブジェクトを切り替えて約6msだろうか。

(ちなみにOnEnableは走らなかった)

Diaciteve To Deactive

なぜかDivacitiveの方がかかる6ms~7ms

実際にDeepProflie上はどうなのかと見てみると0.4msとすごく少ない時間になっている。

どうやらDeepProflie起動中はStopwatchでは純粋な時間を測れるわけでは無いようだ。

(ちなみにOnDisableは走らなかった)

疑問1. エディタ上では遅いだけで、実機ビルドでは遅くないのでは説


他の方の記事を見たが、実機の速度は測られていない。
Unityはビルド時に最適化されGCが走らなくなる処理などがある。
例えばGetComponentなどがそうだ。

これもそうなのではないかという疑問が湧いてきた。

実際にDevelopmentBuildでProfile有りでの検証を行った。

すると

ActiveToActive

かなり速度が違う!!
やはり、実機のほうが処理時間が大幅に早い。

2msほどになった。
先程は6msだったので大きな差だ。

Diaciteve To Deactive

疑問2.activeSelfで事前チェックをすると早くなるのか?


            if (!item.activeSelf)
            {
                item.SetActive(true);
            }

などと書いてみてチェックをしてみた。

私の予想ではエディタ上では書いたほうが早いがデベロップメントビルドは変わらない説

なぜか遅くなった

どうやら調べてみると

object.wbarrier_conc()

という処理に時間がかかっている。

どうやらこの処理はメモリ監視の処理らしい。
DeepProfileをつけた状態ではメモリ監視の処理が余分に入ってこっちのほうが遅くなってしまうようだ。
DeepProfileを上ではソレ以外の明示的に処理が減っているように見えたので、少しは早くなっているかもしれないが、
そもそもactiveSelfにアクセスする前のインスタンスへのアクセス処理が見受けられた。
これならば自身でBoolフラグを作ったほうがGameObjectに対するアクセスをせずに済むので若干activeSelfをみるよりは早いかもしれない。

ちなみに実機の方で見てみたが、activeSelfなしと大した処理の差は見受けられなかった。

疑問3.10個子供を持つキューブを1000個作った場合は1万個キューブを切り替えるときとどっちが負荷があるのか


私の予測では命令処理は減るはずだから軽くなるはずだが……?

正解。

アクティブ化、非アクティブ化どちらもステートが変更済みの場合は命令処理が減るので早くなるようだ。

疑問4. 3D Objectではなく、2D上のObjectだとどうか?


Canvas上のオブジェクトは再描画処理が走ってしまうなどはあるのか?
気になった。

→特に無かった。

若干キューブと比べて処理速度は違ったが、誤差の範囲に思えた。

Canvas自体の方を切り替えても同じだった。(インスタンス化自体が重かったが……)

まとめ


最初の結論に戻るが
フラグを立てて自前で処理する場合は確かに自身に対する処理速度は早くなる可能性があるが
結局ifの処理を挟むということはチェックが必ず必要ということでもあるのでデメリットも有る。
とはいえ、ActiveToActiveはぶっちゃけ気にする程度の処理負荷は出ない。

1万個のオブジェクトを操作するなら気をつける必要性はあるかもしれないが、
そこまで行くとECSとJobSystemなどを使うことになるだろうと思うので
ぶっちゃけUnityではActiveToActiveは気になる処理負荷にはならないというのが私の結論となった。

【Unity】アセットFinalIKって結局何ができるの?

こんにちは、やまだたいし( やまだ たいし (@OrotiYamatano) / Twitter )です。
むかーしにFinalIKというアセットを買ったのですが、ずっと積んでいたので今回はアセット紹介です。

目次


そもそもFinalIKってどんな商品?


assetstore.unity.com

いい感じのIKです。
IKとはInverse kinematicsの略です。
無理やり日本語で表すと逆運動学です。
まぁ3Dモデリングにおいては3DCGキャラクターを動かすためのスケルトン構造を制御する方法の1つ程度の理解でOKです。

ジョイントの位置に対して自動的に角度とかを決定してくれるもの程度に理解しておいてもらえればと思います。

で、その中でUnityのFinalIKとはかつてUnity界隈では様々なVRのアセット戦争がありました。
それぞれの開発者が独自のIKを作りました。
ソレもそのはずでUnityでVRの開発が簡単でしたOculusのDK(デベロッパーキット)を買うとUnityのProライセンスが一緒についてくると言った時代もあったようです。
また、Kinectの開発も行いやすく、人のトラッキングVR、ARにおいて無くてはならないのがIKなのです。

VR黎明期、様々なIKがあったなか生き残ったのがFinalIKというわけです。
もちろん各用途に応じて近年は開発をしている会社も今は少なくないと思います。

とはいえ、このFinalIK、VRIK以外にも機能が入っています。
今回は簡単に一緒に中身を見ていきましょう。

全部で16種類の機能


基礎的なIKは数種類だとは思うのですが、
そこから実際の実装例としてDemoが13種類ほどあります。
(Demoがないコンポーネントもある)

1. Aim IK


AimIKソルバーは、CCDアルゴリズムの変更であり、階層の骨を回転させて、その階層の子Transformがターゲットを目指すようにするらしい……。

言葉じゃ分かりづらいのでgifです。

↓こういう銃のDEMOもあります

2. Biped IK


標準的な二足キャラクター向けのIKシステムで、Unityの組み込みキャラクターIKセットアップの動作を複製し、強化するように設計されています。
とあります。

よくわかりませんが、要はアニメーターで変なアニメーション例えば首の骨が折れたようなアニメーションが出来ないように補助してくれるもののようです。

まぁこれはUnity標準のAnimatiorIKも進化してきているので目立った機能には見えないですね。

3. CCD IK


よくわからないですが、紐みたいなIKですね?

DDCとはCyclic-Coordinate-Descent
階層構造の各関節を一つずつ動かし、目標に向かってエフェクタ(アームの先端部分)を動かす方法らしい。

ロボットとか動かすのに向いてそう

www.youtube.com

4. FABRIK


CCDIKと似ています。

どうやらFABRIKとCCDIKはどちらも多関節アームで
違いはBoneの計算方法が違うらしいです。

FABRIKの方が良さそう?

qiita.com

5. FABRIK Root


FABRIK をつなぐ機能みたいです。

6. Full Body Biped IK(FBBIK)


日本語訳すると全身二足歩行IKという名前……

ヒューマノイドキャラクターの全身をIKで制御するためのコンポーネントらしい。
ヒューマノイドをFKではなくIK制御するためのコンポーネント程度の理解で良さそう。

7. Limb IK


リムIK。
連結された2本の骨の先端位置が与えられた目標位置に到達するように、2本それぞれの骨の姿勢を同時に決定するIK処理。

8. Trigonometric IK


余弦の法則に基づいて 3 セグメントのボーン階層を解決する最も基本的な IK ソルバー。
超基礎的なIK処理が基礎的な挙動だからか、Demoすらない。

9. Interaction System


FullBodyBipedIKで作られていることを前提に、
インタラクション、もとい相互作用的に色々できる様になるコンポーネントらしいです。

主にドアノブを掴むとかボタンを押すとかものを持つとか。

10. Grounder


俗に言うFootIK。
犬とかロボとか人間とか関係なくできるっぽい。

11. Rotation Limits


回転制限をつけるものみたいです。
肘など関節が反対方向に曲がってしまう問題などの対処に使えそうです。

12.Baker


モーションキャプチャなどアニメーション クリップの内容を記録してくれる。

youtu.be

13. VRIK


VR アバターのアニメーション化専用の高速全身ソルバーです。

まぁ英語だけどこの記事見るのが早そう。

root-motion.com

14. Look At IK


任意のキャラクタまたは他のボーン階層で使用して、ボーンのセットを回転してターゲットに面することができる。
いわゆる任意のボーンをターゲットの方向に向かせるようにする機能。

キャラクターがカメラの方向に顔を傾けてたりしてくれるやつ。

15. Arm IK


VRIK の 4 関節二足歩行アーム ソルバーのラッパー コンポーネントらしい
腕の動き自体を制御するもの。
ドアノブを掴むとか。
Interaction Systemと似てる部分もあるがInteraction Systemは総括的なシステム。

16. LegIK


VRIK の 4 関節二足歩行ソルバーのラッパー コンポーネントらしい
FootIKといえばGrounderにも使われてそうだが、多分Grounderは設置判定に対する総括的な機能で、LegIKは足だけの機能。

おわり


意外と拡張性が高く、開発者として勉強になるアセットです。
ここでIKの作り方について理解できれば、今後別のゲームエンジンでも利用可能だと思うので一度参考に買ってみるのも有りなアセットだと思いました。

以上、やまだたいしでした。

【備忘録】(Unity)gitからPackageManagerへの追加方法

こんにちは、やまだたいし( やまだ たいし (@OrotiYamatano) / Twitter )です。
Unityへパッケージを追加する時、GitURLで追加することがあります。
度々書き方を忘れるので備忘録用に記事化します。

目次


GitURLによる追加する意義


パッケージは直接UnityPackageなどでも追加出来るが、Githubなどで運用されているものは、
gitから落とせるようにしておくことで、バージョン管理がしやすくなる。

Packagesで入れると要らないファイルが残ってしまったりすることもあるので、gitで管理したい所。

package.jsonに追加しない場合はココからの追加になる。

基本ルール


2つの指定は必須

  • GitのURLまたはSSHでの接続URLの指定
  • pakcage.jsonが格納してあるフォルダまでのパス指定

(もちろんpakcage.jsonがない場合や特殊なアセットはそのgitのReadmeにかかれていることが多いと思うのでソチラに従ってほしい)

GitのURLまたはSSHでの接続URLの指定

https://~~~.git

or

git@~~~.git

ちなみにUnityはhttps推奨

pakcage.jsonが格納してあるフォルダまでのパス指定

(gitのリポジトリ頭からの相対パス)

?path=/Assets/~~~

合わせるとこんな感じ

https://~~~.git?path=/Assets/~~~

プライベートリポジトリへのアクセス

(githubの場合)

https://your token:x-oauth-basic@github.com/

ブランチへのアクセス

https://~~~.git?path=/Assets~~~#my-branch

tagの指定

(ブランチと書き方は一緒)

https://~~~.git?path=/Assets~~~#my-branch

参考


docs.unity3d.com

まとめ


以上です。
unitypackage配布してるからってソレに頼り切りになって入れ替え時に
面倒だったので、極力git管理したものを使いたい。

StableDiffusion v2.1(Waifu Diffusion v1.5)を使ってみる

こんにちは、やまだたいし( やまだ たいし (@OrotiYamatano) / Twitter )です。
創作活動で自分で考えるのは色々難しいです。
特に私はプログラマーデザインに関しては疎い。
ので、AIに参考資料を作っていただくことにしました。

目次


StableDiffusionとは


今回利用するAIは StableDiffusion です。
StableDiffusionとはディープラーニングで画像を生成出来るものです。
2022年に公開されました。
ディープラーニングなので生成される画像の品質は学習データに大きく影響をうけます。

ちなみに私、エンジニア的にはディープラーニングをAIとは呼んで欲しくは無いのですが、
世間一般的にAIと呼ばれ始めているので、もはや諦めてます。

(そもそもAIとはArtificial Intelligence'(人工知能)の略で、人間と同じように思考し考え自ら発達していくもののことでディープラーニングは厳密にはそう呼べない。
しかし、世間一般的にディープラーニングやゲームAIもAIと呼ばれるようになってしまい本来の言葉の意味合いさえ変わってきているのが現状)

v1~
github.com

v2~
github.com

最近はフォトショプと組み合わせて色々つくる人もいるみたいですね……。

商用利用可能なのか?


現時点では微妙。
ライセンス( CreativeML Open RAIL-M )的には可能ですが、
学習データはウェブ上から得られる様々なデータがデフォルトでは利用されます。
日本の法律では、その学習データの版元がNGといえば現状の法律的ではNGとなってしまう可能性が大きいです。
現時点で判決がおりたという話は私個人は聞きませんが、参考画像を生成する程度にしておいたほうが良いでしょう。
今回はアニメキャラを生成したいので学習データはWaifu Diffusion v1.5を利用します。
(こちらも版権画像が含まれているようなので扱いに注意)

Waifu Diffusionとは?


Stable Diffusion用の学習データです。
Hugging Face(自然言語処理を対象にした大規模なオープンソースコミュニティー)で公開されています↓
huggingface.co

waifuはいわゆる俺の嫁!的な感じで、
waifu diffusionはオタク向けに特化した学習データになります。
ゲームキャラやイラスト、美女モデル、マンガ、アニメなどのデータになります。

今回利用するデータ


・Stable Diffusion v2.1(Stable Diffusion web UI (AUTOMATIC1111)版)
・Waifu Diffusion v1.5 Bata
(Waifu Diffusion v1.5 Bataは旧Stable Diffusion v1系データをStable Diffusion v2版に変更しただけのデータで Bata2は実写系も含めた大量のデータが含まれる)

Bata2は実写系データが多くリアルな物が表示されすぎるので、
イラストによっては Waifu Diffusion v1.5 Bata を使ったほうが良いかもしれない。
wd-1-5-beta2-extra は偏りのあるよりアーティスティックなデータを集めたもの個人的には絵柄が偏るのでオススメしない。

ちなみにStable Diffusion v1とStable Diffusion v2の違いは、深度情報を擬似生成するかどうかです。
2は深度情報を生成するのでより精度の高い画像生成ができるようになります。
(イラスト系を作成する上で深度情報はあまり役に立たない部分が多いので微妙ではありますが腕が3本とかは減るみたいです)

v2版でGUIのものはStable Diffusion web UI (AUTOMATIC1111)版を色々変更したら利用できたり
Gradio版があったりします。

今回はコチラを利用していきます。
https://github.com/qunash/stable-diffusion-2-gui
使えませんでした。(パスが変わってて動かない)

今回はコチラを利用します。
github.com

インストール


まず、 Python 3.10.6をインストール。

www.python.org

↓こんな感じでPathを通すのにチェックを忘れずに。

そしてgitをインストール。 ↓
git-scm.com

んで、いい感じのフォルダで
右クリックしてgit bashを開く。

git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git

を実行

PythonのPathを通すためにWindows再起動。
(最近はWindows再起動必要ないんすね)
webui-user.bat というbatファイルが入っているので叩く。

なにやら、色々インストールされるので待つ。
err Pythonとかなんとか表示されてたらPathが通ってないので入れ直してみるといいかも。

Ranning on local URL: http://~~

って表示されたら、ローカルサーバーが立ち上がってるはずなので、該当のURLを開いてみる。

多分デフォルト http://localhost:7860 かな?

うまく開けたらOK

コレではまだv2ではないのでアップデートする。

↓のsafetensorsとyamlファイルをダウンロード。
huggingface.co

そして先程落としたgithubのファイルの↓フォルダに2つを格納

stable-diffusion-webui\models\Stable-diffusion

後、VAEフォルダのデータも同じような手順で置き換える。
(訓練データセットらしい、あんまり凄い影響があった感じはしない)

webui-user.batテキストエディタで開いて

set COMMANDLINE_ARGS= の行を
set COMMANDLINE_ARGS=--xformers --listen --disable-safe-unpickle --allow-code --autolaunch --no-half
に変更(文字コード変えないように注意)。

そしたら、再度 webui-user.bat を叩けばv2.1にアップデートされるはずだ。

後はWaifu Diffusion v1.5を使う方法だが、↓より
wd15-beta1-fp32.safetensors
wd15-beta1-fp32.yaml
をダウンロードして stable-diffusion-webui\models\Stable-diffusion へ格納すればOK (safetensors がckpt代わり。セキュリティ関連でckptはあんまり推奨されないらしい。
fp32やfp16はfloatの精度の意味。fp16しか動かないPCもあるが多分32で大丈夫だと思う。動かなかったら16入れてみて)

後、Waifu Diffusion用のVAEフォルダのデータも同じような手順で置き換える。

huggingface.co

そして再度 webui-user.bat を叩いてweb画面を開き直すと waifu-diffusion v1.5が動く!!!

Q.落ちる


1024*1024の解像度の画像を作ろうとするとGPUメモリが足りなくて落ちることがある。

詳細は公式のコマンドラインについての記述を読んで頂きたいが、
GPUメモリが4GB以上あるなら
webui-user.bat のファイルの set COMMANDLINE_ARGS= 設定行に --medvram を加えて貰えば動くはず。

Google Colabでやらない理由


Waifu Diffusion v1.5を使おうとすると課金が必要だから!!
(厳密に言うとクラウドストレージが足りないから。
もしかしたらローカルにもマウント出来るかも知れないけど探す方法が面倒だった)

ちなみにGoogle ColabとはGoogle ColaboratoryというGoogleが提供するGPU などのコンピューティング リソースに料金なしでアクセスしながら、特別な設定なしで利用できるホスト型の Jupyter Notebook サービスらしい。

research.google.com

・Jupyter Notebook
ドキュメントを作成・共有するためのウェブアプリケーションMarkdownとか作成ができる。
また、カーネルに接続できるため、Webブラウザ上でプログラミングができる。
対話型実行環境として利用可能。

プロンプト


基本的に2D美少女絵を出力させたい場合、Waifu Diffusion v1.5は以下のようなプロンプトを入れると精度が上がるらしいです。

ポジティブ:

wdgoodprompt, (symmetric), (exceptional, best aesthetic, new, newest, best quality, masterpiece, extremely detailed, anime:1.2)

ネガティブ:

lowres, ((bad anatomy)), ((bad hands)), text, missing finger, extra digits, fewer digits, blurry, ((mutated hands and fingers)), (poorly drawn face), ((mutation)), ((deformed face)), (ugly), ((bad proportions)), ((extra limbs)), extra face, (double head), (extra head), ((extra feet)), monster, logo, cropped, worst quality, jpeg, humpbacked, long body, long neck, ((jpeg artifacts)), deleted, old, oldest, ((censored)), ((bad aesthetic)), (mosaic censoring, bar censor, blur censor), NSFW, wdbadprompt

プロンプトの例は公式でも紹介されている
cafeai.notion.site

出来た


まとめ


気分で入れたが中々思ったような画像が表示されない。
試行錯誤するのが面白いと感じられる。
例えばとても大きい女性を表示させたい場合、英語では giantess などというらしい。
しかし、なぜか赤と青の衣装をまとっている場合が多い。
それはガンダムを学習してきてしまうためだ。
なので、ネガティブプロンプトにガンダムを入れたりなどすると精度が上がったりする。
またangleを表すことばが入っている場合、センシティブな絵が増えるのも特徴的だ。
きっと特殊な構図を描く人は性癖を全面に出してしまうのだろう。

ゲーム"プログラマー"でもエフェクトが作りたい

こんにちは、やまだたいし( やまだ たいし (@OrotiYamatano) / Twitter )です。
私はゲームプログラマーですが、ゲームを作る上でエフェクトを作りたいと思うことが多々あります。
なぜかというと、演出などを組み込んでいく中、エフェクトがあることで印象が大きく変わることを実感するからです。
しかし、基本的にプログラマーはデザイナーのエフェクトを組み込むだけ。
もう少し自分で作れれば魅力的に出来るのではないかと思ったから今回プログラマー目線で作成してみることにしました。

目次


そもそもここでいうエフェクトとは……?


今回は2Dエフェクトではなく3D VFXで尚且つ、ゲームで使えるものを表します。
ゲームで使えるものなので、ハイポリゴンのシネマティックなエフェクトは含めません。
できればスマホでも使えるような低負荷な物が作れると良いなと思っています。
スマホ向けであれば今はUnityが一番強い&Unityを普段遣いしているのでUnity想定で語ります。

普通エフェクトはどう作るのか?


ゲームのエフェクトは通常Houdini + After Effects + ゲームエンジンのパーティクル機能などで作ります。

3Dメッシュを作りそこにテクスチャを張ってアニメーションさせ、大量に出すことで基本的には成立します。

ツールはそれぞれ
・Houdiniは3Dメッシュの作成
After Effects(以下AE)はメッシュに貼り付けるアニメーションテクスチャやパーティクルエフェクトテクスチャの作成(Houdini上で完結することもある)
ゲームエンジンのバーティクル機能はそれらの表示や挙動の制御
に使います

またこれらを全部やってくれるミドルウェアツールなどもあります。
PopconrnFXやSPARK GEAR、BISHAMON、Effekseerなどなど……。

ツールが高い


ツールが高いです。
学生なら安く使える場合もありますが、私は社会人……
商用として使うならHoudiniはインディライセンスでも年間約3万円
AEは28,776円/年です。

高いッ……!

ミドルウェアツールはどうでしょうか、
PopconrnFX→月約3,594円
SPARK GEAR→法人向けなので個人で買える価格ではないです……。100万
BISHAMON→パーソナルライセンス¥60,000買い切りなのは良心的だが安くはない
Effekseer→無料……!だが、チョットローポリすぎでエフェクトのセンスが古いかも……?工夫次第でなんとかなる?

Effekseer以外は高いッ……!

代替ツール


Houdini の代替ツールはBlenderです。
しかし、Houdiniのようにプロシージャルにモデリングするのは難しいです。
対応するアドオンなどもあるのですが、Blenderが処理負荷に耐えきれずにすぐに落ちてしまうので同じようには使えません。

似たようなエフェクトだけど若干違うエフェクトを作るときにはHoudiniでの作成は重宝します。
Blenderで作る場合はいちいち作る必要があるので大変ですが代替出来なくはないという感じです。

AEの代替ツールは無いです。
しかし、基本的にエフェクトというのはShaderで作成可能な場合が多いです。
というのもエフェクトの表現はノイズベースの表現が多いからです。
我々はプログラマーですのでShaderの書き方を覚えてみるのは良いかも知れません。
UnityならばShaderGraphがありノイズ生成のプログラムも簡単です。

Shaderで書ければ表現出来ますが私個人としてはできればAEは欲しいです。
というのもノイズ生成の処理は正直Shaderとしては軽い処理ではありません。
ですので、どちらかというと連番テクスチャ、テクスチャでのアニメーションで処理してしまえるならソチラが理想ではあります……。

Effekseerを使ってみる


EffekseerはBISHAMONに影響を受けたツール。
OSSで無料で使用可能だ。

effekseer.github.io

私も少し触ってみたが、ぶっちゃけUnityのパーティクルシステム機能に毛が生えた程度に感じた。
3Dモデルも殆ど自前で用意するしかなくちょっと微妙に感じた。
使い込めばちゃんと使えそうだが、正直、サンプルが古いゲームのようでダサいものが多い。

UnityのVFXGraphを使ったほうが良いかもしれない。

NovaShaderを使ってみる


実はサイバーエージェントがUnity用にエフェクトに特化したShaderを公開している。
その名はNovaShader。

developers.cyberagent.co.jp

Unityのパーティクルシステムに特化したシェーダー。
ちょっとしたものならこれで良いかもしれない。

何はともあれ作ってみる……。


とりあえず、色々ツールを調べた所でまずは作ってみることにする。
正直、作ってみないとわからないことが多すぎる。
今回はまずは剣撃エフェクト(Sword Slash Effect)を作成することに。

1.3Dモデルの用意


3Dを用意する。
我々はプログラマーである。
3Dモデラーではない。
頑張って1時間使って3Dモデル作るのもいいとは思うが、
時給換算すると1000円を超える。

3Dエフェクトのモデルはかなり汎用性があり、使い回しが効く。
今回はコチラの3Dモデルを購入させて戴くことにした。

booth.pm

2.テクスチャの用意


多分今回はShaderを使うので必要ない……はず。

3.実際に作ってみる


今回はVFX Graphを触ってみようと思う。
URPで2021.3.15f1を利用する。

まず、VFXGraphをパッケージマネージャーより入れる。

Assetウィンドウより右クリック、Create→Visual Effect→Visual Effect Graph

そうすると新しくエフェクトが作れられる。

ついでに、シェーダーグラフを使えるように設定もイジっておく。
Edit→Prefarences→VisualEffect→Improved Shader Graph Generation

4.なんかいい感じに


正直、現状どれを見ればいいと言うような、まとまった資料はあまりないようです。
私が参考にした資料を貼っておこうと思います。
(細かく解説しようかと思いましたが、チョット面倒でした)

UnityJapanとかの動画
learning.unity3d.jp

Unityのエフェクトの作り方を紹介しているYoutubeチャンネル
www.youtube.com

公式のプリファレンス
docs.unity3d.com

公式サンプル
blog.unity.com

↓炎のShaderはコチラを参考にしました(ちょい無駄処理があるので修正しましたが……)
www.youtube.com

正直UnityJapanの高橋 啓治郎さんの動画さえ見てれば簡単なものは作れる。
後はShaderGraphと同じ感覚で作れる部分が多い。
(動画はみるのに時間がかかるのが玉に瑕か……?)

ちなみに私が作ったエフェクト↓

もっと苦戦するかと思っていましたが意外とすんなり組むことが出来ました。
(強いて言うならCurvesを編集するときにEnterを押すと直で値が入力できると知らなくて途中まで苦戦していたぐらい)
VFX Graphは意外とプログラマーライクでプログラマーShuriken(パーティクルエフェクト)よりコチラのほうが作りやすいかも知れません。

まとめ


ゲームでエフェクトを作るのは大変ですが、最近はゲームエンジン側の機能も充実化しているのを肌で感じることが出来ました。
正直Effekseerも触ったことがあったのですが、今ならVFX Graphを直接触ったほうが早いかも知れません。
UnityにかぎらずUEでもNiagaraというものが使えます。
今後はVFXツールを使わなくて済むようになってきそうですね。
また、UnityではSubGraphというものがあり処理を流用できます。
テンプレートなGraphを揃えておけば今後のゲーム制作に役立つかも知れませんね。

以上、やまだたいしでした。

「オブジェクト指向はしっくりこない」とは言わせない

こんにちは、やまだたいし( やまだ たいし (@OrotiYamatano) / Twitter )です。
今回は設計についてちょっと書いておこうと思ったので、記事化することにしました。

目次


今回のお話の結論


オブジェクト指向は悪じゃないし、
オブジェクト指向でつくるなら、開発段階やチームの状況に応じて適した形に変えてきましょうよって話。

オブジェクト指向がふさわしくないという議論


ゲーム業界界隈では度々オブジェクト指向はふさわしくないという議論が持ち上がる。

soysoftware.sakura.ne.jp

オブジェクト指向は昔に作られ古くなってきたプログラミングパラダイムだということは否定しないが、必ずしも悪くないと私は考える。

確かにゲームのプログラムは業務システムと違う部分が多く、
世の中の設計パターンがあわないことが多い。
しかし、考え方は多く適用出来る部分はある。

技術書を通して学ぶべきは方法論ではなく、考え方であると言いたい。

オブジェクト指向についての議論


最近、DDDやオブジェクト指向、クリーンアーキテクチャに違和感を覚えるというのを見かけることが多い。

hachibeechan.hateblo.jp

hadashia.hatenablog.com

nowokay.hatenablog.com

これらのブログについて私が言いたいのは、半分はそうだし、
もう半分はそうじゃないと言いたい。

まずはゲームにおいてDDDを全部採用するのは間違いであると言いたい。
もちろん、ゲーム界隈はこれまで設計の概念が薄く、先に進んでいるWeb業界を真似てみようという動きはすべて間違いとは言わない。

弊ブログでもMVPについて取り上げている。

orotiyamatano.hatenablog.com

しかし、全部を真似するのは間違いであると言いたい。
特にDDDを参考にするのは間違っている。

DDDの認識


DDDを知るのにあたって私はエヴァンス本を読むことをオススメしている。
エヴァンス本翻訳が分かりづらいが、それでもである。
具体的にどのように適用するかはドメイン駆動設計入門などで十分なのだが、
DDDを学ぶ上でエヴァンスさんの思想に当たる部分が抜けているのが気になる。

設計の本を書くミノ駆動さんも誤解されるような書き方をしてしまっている。

↑これに関して言えば、この方↓のツイートが正解といえる。

そもそもエヴァンスさんは業務系アプリケーションをつくるのにあたって、
世界各地でハチャメチャに設計されているのをなんとかしたいという意図で、
DDDというものを編み出し本にしたのだ2004年に。
しかも、結構自信がなさそうに書いているポイントがあったりする。
自信が無いんだなと思って読めば重要ではないと一蹴出来るポイントもあるが、他の解説本はそういった言葉じりは削除されてしまっていることもある。

そもそもドメイン駆動開発はドメインの専門家からの入力に従ってドメインに一致するようにソフトウェアをモデル化することに焦点を当てることだ。

ミノ駆動さんのクラス図はちょっとズレている。
DDDとは業務知識とか実際にある工程などをドメイン化して落とし込むもの。
なのでラーメンの製造工程だったり、ラーメン屋の接客対応などといったものからはドメイン化出来るが、
ラーメンの構成要素をドメインオブジェクト化するのは何か違う気がする。
コンポーネント指向ではありそうだけど。

オブジェクトとしてドメイン化するにしても
例えば一般の会社では
ボールペンは消耗品や備品の一つようにモデリングできるが、
文房具屋ではボールペンは商品の一つのようにモデリングできる。
同じ物体でも、このように扱う専門家によってどのようにモデル化されるかが変わるので、ユビキタス言語策定が必要になったりする。

(これだけがDDDではないが)このような話がDDDである。

それをゲームに適用しようとする方々がいたりする。
私は疑念を抱かざるを得ない。

もしDDDをやりたいと言う人がいるならば「ほう……聞かせてみてくれ」っていうと思う。

そもそもゲームの内容をDDDとして設計するのは文脈として変だからだ。
設計する上でゲームは業務システムでもないし元となる業務フローなんかもないのでモデリング出来ない。
無理にDDDに当てはめようとすると破綻すると思われる。
ゲームでDDDをするとなれば、なにかその人が思うドメイン概念の抽象化作業、モデリング方法が存在することになるはず、
一体全体どう落とし込むつもりなのか聞いてみたくなると思う。
私には正しく落とし込む方法は思い浮かばない。

しかし、DDDはゲームに相応しくないと考える反面、
ドメインを定義するという考え方自体は非常に参考になるとは思う。
ドメインとは違うがゲームにおいて責務の単位はどれに該当するかと試行錯誤することは必ずしも間違いとは言えない。

他設計手法についても……


他設計手法についても同様のことがいえる。
WebのようなViewからのレスポンスがキメられた値だったら話は別だが、
ゲームの場合は見えているもの自体がオブジェクト本体であるので、ViewとModelは切り離すことが出来ない。
また静的な挙動ではなく、ゲームは常にシステム内の時間が遷移し、ほとんどが静的なオブジェクトで構成されているWebやシステム系アプリケーションとは話が違う。

クリーンアーキテクチャ本の話の厄介さはソコが起因してくる。
クリーンアーキテクチャ本は後半はゲームに適用できない設計や手法の話になるが、
前半においてはかなり適用できる部分が多い。

業務開発手法をゲームに適用しようとするのは簡単に言うと、デザインパターンがなぜそのようなデザインパターンになったのか知らずに闇雲にパターンを適用しようとするのと同じだ。

オブジェクト指向がふさわしくないという議論


オブジェクト指向がふさわしくないという議論、これに反対していこうと思う。

soysoftware.sakura.ne.jp

nowokay.hatenablog.com

何度もいうが、オブジェクト指向自体が古くなってきたプログラミングパラダイムだということは否定しないし、新たなプログラミングパラダイムが出てきて相応しいのがあるのかも知れない。
だが、少なくとも現状オブジェクト指向が駄目だから手続き型に戻ろうというのは可笑しな話であると言いたい。

そもそも上2つの記事であげられている部分で議論の論点になる部分は抽象化、レイアリングされすぎたクラス設計が嫌だということなんだと思う。

正直私は言いたい。

クラス統合しろ!!!!
レイアリングが間違っているんだ。

そんなことをしても良いのか?と思う人がいるかもしれない。
だが、槍玉に上げられるクリーンアーキテクチャ本にはしっかり丁寧にどうすべきか書いてある。

ちゃんと読め!!!

クリーンアーキテクチャではなんと言われているのか


そのクリーンアーキテクチャ本ではどのように触れられているのかというと
凝集性というワードが重要になってくる。
簡単に言うといろんな実装がクラスにまたがってしまい、読みづらいコードは凝集性が低いといえるし、クラス内に手続き的にギュッと集まったコードは凝集性が高いと言える。

皆、何故か図が好きなようなので本から抜粋して下に貼っておく。
(クリーンアーキテクチャが槍玉に上がるとき円の図がよく貼られるよねw)

これらを一言で説明すると、こうだ。

● 再利用・リリース等価の原則(REP)
再利用性を高めるためにクラスまとめろ
● 閉鎖性共通の原則(CCP)
保守性を高めるためにクラスまとめろ
● 全再利用の原則(CRP
関係ないクラスと繋がり持つな。分割して再利用性高めろ(インターフェース切るのもここ)

上のブログでは↓のように述べられているが、それはCRP寄り/REP寄りになってしまっているということだ。

オブジェクト同士の連携でプログラムを組むと、コードが飛びまくって追いにくくなります。そして単一責務の原則により、小さいクラスが大量に生成されて、追いにくさがさらにあがっていきます。

超簡単に言うとクラス分けし過ぎ。

ホンマにそれ責務単位なの?
私は責務というのは、DDDが言うようなドメインとかじゃなく、
個人的にはクラスの変更の単位に依存すると考えていて、
一つの機能変更で多くのクラスを見る必要や変更の必要があるならまとめてしまったほうが良いと考える。

凝集性が低いと開発中、さまざまなコードを見に行く必要があり開発し辛い。

クリーンアーキテクチャ本では更に
抽象度が高くなる方向に依存すべき だが、コンポーネントの安定度や抽象度はきちんと区別できるものではない(p.167 要約)」というような感じで書かれているが太字部分が読まれすぎていて「コンポーネントの安定度や抽象度はきちんと区別できるものではない」 という部分がしっかり読まれていないような気がする。

しかも、クリーンアーキテクチャではこれの解決策が回答されている。
抽象度と安定度を数値化し、それを元に直せという。

私はゲームプログラマーなのでUnityに例えさせてもらう。

例えば
Unityのワンクラスで完結させるような実装は
ゲームオブジェクトなど他を参照しまくるが外部への依存は0なのでI = 0 / (20 + 0) のような式になってInstabilityが0
UnityのコンポーネントクラスはInterfaceで実装は基本無い?はずなのでA = 0 / 20 みたいな式になってabstraction(?)が0
結果

0 抽象度(abstraction?):,0安定度(Instability)

で苦痛ゾーンになる。
まぁ再利用性に欠けるって言うこと。

こんなアドバイスをくれつつも、こう↓とも記している。

この三角形のなかで開発チームの現在の懸念事項に見合った落としどころ を 見つける。 それだけではなく、時がたてばチームの懸念事項が変わるということも心得ている。 たとえば、 開発の初期段階なら再利用・リリース 等価 の 原則(REP)よりも閉鎖性共通の原則(CCP) のほうがずっと重要になる。 再利用性よりも、 開発しやすさのほうが重要だからだ。

極端に言えば、Unity1Weekなど作ることだけに重みを置くプロダクトはクラス数少なくてもあんま問題ないってわけですね。

コンシューマーのような作りきり案件ではCCP重視でいいけど、スマホのような運用案件ではREPは重視した方がいい。
(とはいえ、コンシューマーであっても機能を次のゲームに活かすことはあるとは思うで、CCPだけ重視は辛いと思う)

私はオブジェクト指向のSOLID原則や抽象化が神格化され過ぎた結果、凝集性の低いコードがはびこり、オブジェクト指向はしっくりこないと言われるのが増えているのではないかと推測する。

つまり何が言いたいのか


現状オブジェクト指向でつくるなら、開発段階やチームの状況に応じて適した形に変えていけば問題ないと思います。

開発段階であれば、CCPもとい保守性を高めるためにクラスまとめることは悪じゃありません。
とはいえ、開発中も保守が発生します。
プロダクトが完成に近づくにつれ徐々に凝集性→保守性にシフトした作りに柔軟に変えていけることこそが重要です。

つまり、「オブジェクト指向が悪」って言うのはちょっと違って、
「クラスを変更し実装変更することが出来ないプロジェクトが悪」です。

かくいう私も理想からは遠く悩んでばかりですが、余裕ある実装が出来るように皆さん頑張って共々一緒に理想の設計を追い求めて行ければなと思います。

まとめ


・業務アプリケーションとゲームは違う
・設計パターン本や設計本は手法じゃなく思想を学んで欲しい
オブジェクト指向の抽象化に囚われすぎないで欲しい
オブジェクト指向でつくるなら、開発段階やチームの状況に応じて適した形に変えてきましょう

以上、やまだたいしでした。