Toguchi-Design

ゲームをプレイしたり作ったりします。

【Unite 2017】DIYエフェクト実装: エンジニアレスでエフェクトを組み込める環境づくり


【Unite 2017 Tokyo】DIYエフェクト実装: エンジニアレスでエフェクトを組み込める環境づくり


こちらの講演を見たのでメモします。

エフェクト実装の問題点

・エフェクト再生はゲームロジックと深く結びついている
・ゲームの処理に合わせ、タイミング・位置・再生時間・移動法則など細かい指定が必要
・エフェクトをゲームに組み込むのにはほぼエンジニアが必須

例: 乖離性ミリオンアーサーVR

魔法陣の発生、衝撃波を飛ばす、衝突すると爆発する、など
パーティクルシステムをスクリプト内で宣言、実行
InspectorでPrefab内のGameObjectをアタッチ

Animationに合わせたタイミング調整の要望

AnimationEventを追加して対応
スクリプト側でイベントを受け取る処理を追加

タイミング調整②

剣のオーラを2段階に分けたい
AnimationEventを追加
またスクリプト側でイベントを受け取る処理を追加

エフェクト制作ツールの変更要望

ShurikenからBishamonへ変更
スクリプトの修正が必須
Prefabの更新も必要

ShurikenとBisamonを組み合わせる要望

エフェクト定義を2つに分ける必要がある
Prefabも複雑になる

つまり

このままだとアーティストの要望をエンジニアが実装するまでアーティストが待ち状態になる→繰り返し
細かい調整でもこのサイクルが何度も発生する
双方の時間のムダ

目標

アーティスト観点

好きな制作ツールで好きなエフェクトを自由に制作
特殊なコンポーネントの付加などエンジニア都合のめんどくさいことを極力させない
再生位置・再生タイミングなど、一般的な調整項目をアーティストだけで完結できるようにする
つまり、アーティストだけでだけで以下ができるようにする
・エフェクトの制作
・エフェクトをゲームに組み込み
・エフェクトをゲーム中で動いているのを確認し、調整

エンジニア観点

進行中のエフェクト組み込みスケジュールをなるべく遅れさせない
短期間開発、すぐに導入・試用できる規模
プロジェクトに依存させず、今後のプロジェクトにかんたんに導入させる

実際のシステム

EffectComponent

課題

複数のエフェクト制作ツールのカバー(スクリプト内の再生処理を共通に)

EffectComponentとは

制作ツール固有のコンポーネントに代わり、ロジックから参照されるAbstractクラス
エフェクト共通の機能やAPIをまとめる
固有の処理は拡張クラスを用意
ゲームロジックからはEffectComponentのみを参照

コード

【Unite 2017 Tokyo】DIYエフェクト実装: エンジニアレスでエフェクトを組み込める環境づくり - YouTube

ゲームロジックでは

制作ツール固有のコンポーネントではなく、EffectComponentを参照→スクリプトの処理はすべて同じになる

EffectComponentの自動付加

FffectComponentが機能するには全てのEffectのGameObjectに制作ツール用の拡張クラスが付加される必要がある
エフェクトの量が増えるとミスが増えるため手動はNG
エンジニア都合なのもある

実行時に自動的に付加する

エフェクトは必ずPrefabにしてもらう
読み込み時にEffectComponentを自動的にAddComponent 制作ツールの差異が気にならず、面倒な手間も省ける

エフェクト再生オプション

なるべくエンジニアに頼らず望みどおりの演出が作れるよう、いろいろな調整項目を実装
エフェクト共通機能であるため、FffectComponentに実装

再生位置

Transformを指定し、その一にエフェクトを再生
追加オプションも用意

Follow

エフェクト再生中、Transformに追従

PlayAtGround

指定した位置のy座標に関係なく、再生位置を地面に固定

自動Destroy, Deactivate

Preserveオプション

再生終了後にエフェクトをDestroyするか、使いまわせるようにInactiveにして保持しておくかのオプション
DestroyであろうとDeactivateであろうと、再生終了後の処理は自動になるため、手間が省ける

中間のまとめ

基本的な構成

EffectComponentベースクラスに共通の機能や再生オプションを実装
エフェクト制作ツールの種類に応じて拡張クラスを実装、エフェクトPrefab読み込み時に自動的に付加
ゲームロジックからはEffectComponentタイプのみを参照

エディターツール

EffectContainer

課題

アーティストがUnity上で組み込みを行えるよう、カスタムエディターツールを用意

EffectContainerとは?

ゲームロジック上のオブジェクト単位で持つエフェクト再生定義群のコンポーネント
そのオブジェクト位関連するエフェクトをリストで定義し、エフェクトPrefab及びEffectContainer用の各種再生オプションをInspectorで定義
定義したエフェクトはゲーム実行時に読み込まれ、EffectComponentの自動付加が行われる

実際の使用例

【Unite 2017 Tokyo】DIYエフェクト実装: エンジニアレスでエフェクトを組み込める環境づくり - YouTube

ゲームロジックからは

ゲームロジックはEffectContainerの参照のみ持つ
各エフェクトへのアクセスはEffectContainerで設定したNameフィールドで参照
再生するエフェクトの設定、オプションはInspectorで済ませてあるためスクリプトはPlayEffectを呼ぶだけでOK

ゲーム実行時

定義したエフェクトが自動的にInstantiateされ、EffectComponentの自動付加も行われる
エフェクトの参照がEffectContainerにまとまっているので、Prefabもスッキリする

再生タイミングの調整

課題

エフェクトはスクリプトから再生している
実際はモーションを見ながら細かく再生タイミングを調整したい場合がほとんど

AnimationEventを使う

エフェクト再生専用のAnimationEventを定義し、アーティストがセット

設定

EffectAnimationEventという関数名で固定→エフェクト用のEventであるのがわかるようにする

String Parameter

Play[EffectName]
Stop[EffectName]
EffectNameはEffectContainerで定義したName

アーティストが任意のタイミングでEffectContainerに定義したエフェクトを再生・ストップできる
AnimationEventはAnimatorと同じオブジェクトにのみ通知されるため、EffectContainerへAnimationEventを流すコンポーネントは必要

アーティストだけで完結

EffectContainerでオブジェクトに使いたいエフェクトを定義
エフェクトPrefabや各種再生オプションをEffectContainerで設定
AnimationEventで再生タイミングを調整
以上だけでも、かなり詳細なエフェクト演出の調整をアーティストだけで完結できる
コミュニケーションコストが大幅に減る
短期間で作って導入できる

カスタムエディターについて

作りたくない・めんどくさいが、Inspectorのデフォルトでは限界があるため、ある程度複雑になるとカスタムエディターがほぼ必須

Tips

いつか必ず必要になり、今後も作り、メンテしていく
よく使う機能は抽象化して使いまわせるようにする
(例 Copy&Pasteできるリストなど)
AssetStoreのものを使ってもよい

最後に

フィードバックをもらう

ツールを作るのは双方の作業効率を上げるため
使いにくかったら意味が無いので、アーティストからフィードバックをもらう

アーティストは

使いにくい部分などがあったらエンジニアに言う

エンジニアは

ツールは自分で使い、改善案を考える
しかし、アーティストにとっての改善とは限らないので、実装する前に確認する
また、通知なしの大きなインターフェース改変はしない




Markdown記法を覚え始めました…
改行が面倒です…あとは結構いいです

【Unite 2017】ScriptableObjectについてメモ


【Unite 2017 Tokyo】ScriptableObjectを使ってプログラマーもアーティストも幸せになろう

この講演を見たので、メモします。

Scriptable Object

UnityEngine.Objectの派生クラス
UnityのシリアライズシステムではScriptableObjectを読み書きできる(メンバ変数)
Unityはこれから出てくる様々な参照を理解してトラッキングしてくれる
シンプルかつ単純なAPI

MonoBehaviourとの比較

MonoBehaviour

スクリプト
Unityからコールバックを受ける(OnCollisionEnterなど)
常にゲームオブジェクトにアタッチされる
AddComponentAPIを使う(動的)
Unityのシリアライズシステムとコンパチブル(保存できる)
シーン、プレハブに入る

Scriptable Object

スクリプト
Unityのシリアライズシステムとコンパチブル
Unityからのコールバックはほとんど受けない
Updateは呼び出されない(自動的には)
GameObjectへのアタッチはできない
常に独自の人生を歩む

ファイルについて

MonoBehaviour

セーブ→他のオブジェクトと一緒に保存される
MonoBehavior, GameObject, Transform
Prefabの一つのコンポーネントを変えるとファイル全体が変わる
↑シーンも

ScriptableObject

独自。バージョン管理には便利
コンフリクトを避けられる

MonoBehaviorで宣言

最大ライフをNPCで調整すると他の人が触れない
一つずつ個別にプログラムを書かないといけない
間違って誰かが変える可能性がある
コードでのコンテンツのチェックが必要

ScriptableObject

一つのオブジェクトにまとめる
MonoBehaviorで宣言していた変数をまとめる

メリット

値を別のところに切り分けられる
値のアップデートが直ぐにできる
シーン、プレハブのロードが早くなる

UnityではScene,Prefabの中のものや紐づけされているものを全てシリアライズしている
重複データのチェック、圧縮はない
それをロードするときにはそのプロパティ全てをロードする

全部を単一のScriptableObjectにつっこめばそれを一度だけシリアライズすることでまとめて参照される

作成する方法

動的

ScriptableObject.CreateInstance();

セーブする

AssetDatabase.CreateAsset();
AssetDatabase.AddObjectToFile();
[CreateAssetMenu]

コールバック

OnEnable
ScriptableObjectがロード、インスタンス化されたら呼ばれる
ScriptableObject.CreateInstance();
OnDestroy…Destroyされたあと
OnDisable…Destroyされるとき

ScriptableObject

Texture, AudioClipなどと同じ
他のアセットのと同じように存在する

アンロードされるとき

明示的にアンロードするとき
GCによって

UnityはC++のエンジン
C#スクリプトレイヤーが乗っている

ScriptableObjectの使い方

データコンテナとして使う

JSON, XMLのようなフォーマットよりもScriptableObjectのほうがはやい

列挙(Enum)として使う

普通比較に使う
同じScriptableObjectを参照しているかを調べる

【Unite 2017】シェーダの講演を見たのでメモ

こちらの講演を見たので、メモします。

【Unite 2017 Tokyo】シェーダープログラミング入門!カスタムシェーダー、作るで!


シェーダーの定義
GPU上で実行されるインストラクション(プログラム)の集合

CPUを喰わないようにする
GPUの最適化


レンダリングパイプライン
Vertex Shading(形、大きさ)
フラグメント…最終的に画面のピクセルになるであろうもの
Pixel Shading(色を変える)

シェーダの種類
Vertex Shader
Fragment Shader
Surface Shader(Unityの中のライティングモデルを考慮)
More…


Vertex Shader
Input
複数の頂点の位置、法線、色
Output
新しい位置、その他

Fragment Shader
Input
ピクセルになるFragment
Output
ピクセルの色、アルファ値

Surface Shader


Shaderの書き方
言語
CG, ShaderLab

CG
C言語と似ている
精度が何種類かある -> float, half, fixedで使い分け
float, float2, float3 etc.
Swizzling 情報のアクセスの仕方
Color.rgb, color.rg, color.xyz, color.yx


Tags RenderType 透明にしたいなど
CGPROGRAM 実際のプログラム
#pragma vertex vert
#pragma fragment frag
各シェーダの関数の定義

v2f構造体 
vertex to fragment
float4 pos 頂点の位置情報
vert
UnityObjectToClipPos … 3Dの頂点を2Dに変換する
fragment
全てのピクセルを赤に
half4 frag(v2f i) : color{ return half4( 1,0,0,1);
}

vert, fragに全ての頂点、ピクセル全てが送られる→大量のデータが送られる
必ずしも明示的にプログラムを呼び出す必要がない→定義しただけでUnityが関数を呼び出してくれる

shader2
vert メッシュ自体の拡大縮小
float4 vert = v.vertex * 0.75 →大きさが0.75倍


Shader03
メッシュの書き方を知っておいたほうがいい
新しいMeshの生成
頂点を入れる
頂点に色を付与できる
trianglesの順番を指定
v2f 頂点位置、色
各頂点の色から補完色を生成

Properties…エディタとシェーダ間でデータを送る
→変数をPassの中で定義

Shader06
C#からShaderのPropertiesをいじれる

Shader07
テクスチャの話
UV テクスチャから色をモデルに適用
UV value テクスチャの中でメッシュの頂点に相当するポイントを指定
vert 位置、UV
frag そのUVポイントにあるテクスチャ

Shader08
ピクセルの色の描画だけを設定→ライティングは関係ない
Surface Shader ライティングを使いたい場合
#pragma surface surf Lambert
struct Input
{ float2 uv_MainTexture;
}

surf(Input, IN, inout SurfaceOutput o)
{
プロパティをOutput valueとして返す
o.Albedo = tex2D(_MainTexture, IN.uv_MainTexture).rgb;
}


Shader09
頂点の位置のアニメーション
surface + vertex
#pragma surface surf Lambert vertex:vert
頂点の位置のデータの変換

Shader10
テクスチャをモデルに適用するにはUVを使うが、それをアニメーションすることもできる
UVスクロール
void surf(Input IN, inout SurfaceOutput o)
{
float2 uv = float2(IN.uv_MainTexture.x + _Time.y * 0.2, IN.uv_MainTexture.y);
}

Shader13
よりゲーム的な見た目
しましまを上に動かす
TextureのUVのアニメーション
透明度の調整

サンプルコード
https://github.com/ArturoNereu/ShaderProgramming_101

Unite 2017のPost Processing Stackの講演の映像を見たので自分用メモ【Unity】

先日のUnite 2017の講演映像が公開されていましたので、見始めました。

はじめにUnityの高橋氏のPost Processing Stackについての講演を見たので、自分用に要点をメモします。

 

おすすめ設定
Rendering Path = Deferred
HDR = ON
Color Space = Linear

 

Temporal Anti Aliasing
Jitter
Spread ランダムに色を探索する数
 = 1

Blending
Stationary 静止しているピクセルのブレンドする割合
= 0.8 ~ 0.9
Motion 動いているピクセルのブレンドする割合
= 0.8 ~ 0.9

Sharpen 輪郭線強調フィルター
= 0.1 ~ 0.2

 

Ambient Occulusion くぼみ部分を影にする
Intensity 深さ
Radius くぼみのサーチ半径 なるべく小さく
Sample Count 1ピクセルあたりのサンプル数。 高くするほど画質は上がるが負荷も高い
Downsampling 処理を半分の解像度で行う。 軽くなる
AOはなるべく軽く!
Ambient Only AOの影響をアンビエント光のみに限定する。Deffered, HDR使用時のみ使える

 

Screen Space Reflection ... Deffered限定
画面上にないものは映らない
→ごまかす ぼかす、ノーマルマップで散らかす
かなり負荷が高い
Reflectoin Quality(解像度), Iteration Count(最大サンプル数) でパフォーマンスアップ
Step Size 粗さ(サンプル感覚)
Max Distance
Fade Distance サンプル数をフェードする
Width Modifier ないはずのものを消す

 

Depth Of Field ボケのシュミレーション
Focus Distance 焦点をあわせる距離
Aperture 絞り(F値
Focal Length 焦点距離
Field of View 画角
Kernel Size ボケの半径に対するリミッター値 高くするとボケが大きくなるが処理は重い

 

Motion Blur モーションブラー
露光中の動きに寄るブレのシュミレーション
Shutter Angle 大きくするとブラーが大きくなる
Sample Count 何度サンプルを行うか。 負荷が高くなるのでなるべく小さく

 

Eye Adaptation 目の明順応/暗順応
画面の明るさを適切な量に自動調節する(オート露出)
Compute Shader必須
Luminosity range ヒストグラムの最大範囲
Auto exposure 調整する範囲
Histogram filtering ヒストグラムの中で平均値を集計する範囲
Adaptation Type 明るさを補完するスピード

 

Bloom 光の散乱
光ってる感じを表現
物理をシュミレートしてないのでリアルではない。白っぽくなる
Intensity 明るさ
Threshold 反応する明るさ
Soft Knee Thresholdのカーブを滑らかにする
Radius 光の半径 常に最大値、Intensityで範囲調整をおすすめ
Anti Flicker 小さなピクセルがブルームに反応しなくなる(フリッカー防止)
Dirt レンズの汚れを表現

 

Color Blending 明るさ、色調の調整
Tonemapping 明るさの調整、ダイナミックレンジの圧縮
ColorGrading 色の調整、味付け
Tonemapper ダイナミックレンジの圧縮 HDRをなめらかに(白飛びをいいかんじに和らげる)
Neutral ゲームでよく使われる
Filmic コントラストが強い
ColorGranding
ColorWheel Linerがおすすめ
Liner 左がシャドウ、真ん中がミッドゾーン、右がハイライト
各領域の明るさ、色を調整
どれだけ使っても負荷はほぼ同じ!実行中に焼き直すのはきつい

User LUT ユーザーパレット
フォトショのカラコレを入れる

 

Chromatic Abrerration 色収差。レンズの色ズレをシュミレート
レンズの味わいを出す

 

Grain フィルムのザラザラ感を出す
Intensity ザラザラの強さ
Luminance Contribution ザラザラのコントラスト
Size ザラザラのサイズ
Colored 色を付けるかどうか

 

Vignette 画像の周辺を暗く、カメラ感を出す
Intensity 黒ずみの大きさ
Smoothness 黒ずみのぼやかし度
Roundness 四角っぽさ
モバイルでも余裕

 

Dither マッハバンド(しましま)を消す
ノイズを乗せる
パフォーマンスも余裕

 

問題点
Animatorでアニメーションできない
スクリプト経由でアニメーション
(変更が破壊的になる)→解決用のスクリプトがGitにある

シェーダーバリアントが大量に生成される
シェーダーがたくさん作られる(初回のビルドに時間がかかる)
ビルドサイズが数MB程度増える
→事前に組み合わせを決めておけば減らせる

 

 

Gitの新バージョンのv2ではUE4のようなボリューム形式になっているようですね。

気になります!

UnityでJSONをファイルとして書き出す/読み込むメモ

UnityでJSONを書き出し/読み込みする関数を作ったのでメモします。

///<summary>
///dataからjsonを作成してpathに書き出す
///</summary>
public static void WriteJson<T>(string path, T data)
{
    if (Directory.Exists(Path.GetDirectoryName(path)))
    {
        string json = JsonUtility.ToJson(data);

        BinaryFormatter bf = new BinaryFormatter();
        FileStream file = File.Create(path);
        bf.Serialize(file, json);
        file.Close();

        Debug.Log("writed");
    }
    else
    {
        Directory.CreateDirectory(Path.GetDirectoryName(path));
        WriteJson<T>(path, data);
    }

}

///<summary>
///pathに保存されているjsonを読み込みdataに格納
///</summary>
public static void ReadJson<T>(string path, out T data)
{
    BinaryFormatter bf = new BinaryFormatter();
    FileStream file = File.Open(path, FileMode.Open);

    string json = (string)bf.Deserialize(file);
    file.Close();
    data = JsonUtility.FromJson<T>(json);
}

ゼルダの伝説 ブレス オブ ザ ワイルド

はじめに

ゲームの感想については、はじめはせっかくなので今までプレイしてきたゲームを遡って記事を書いていきたいと思います。

 

プレイしたゲームの感想、第一作目は『ゼルダの伝説 ブレス オブ ザ ワイルド』。

E3でDLCのトレーラーが出ました。


ゼルダの伝説 ブレス オブ ザ ワイルド エキスパンション・パス トレーラー [E3 2017]

 

感想

この作品は、オープンワールドゲームに求められるハードルを高くした作品だと思います。

オープンワールドアサシンクリードシリーズ、GTA5、MGSV、Fallout4など複数のゲームをプレイしていますが、今作のゼルダはその流れを少しずつ汲みつつもそれを進化させています。

ライミング、パラセールでのどこにでもいける冒険感、物理エンジン・化学エンジン(?)をベースにしたゲームデザインは圧巻です。

特に化学エンジン が実装されていることにより、プレイヤーができると思ったこと全てができる、というカンペキな状況を作り出しています。

正直言って神ゲーです。

戦闘は死にゲー的な雰囲気がありつつもライトでとっつきやすい感じにまとまってて、これもまたいい感じです。

というか、お使い感がない。ヤバい。

 

 

考察

この作品で、これからのオープンワールドゲームには特に

・インタラクション

・フォトリアルとは別方面のアプローチ

が求められていくのではないかと思います。

いやはや、さすが任天堂

このブログについて

このブログは、ゲームクリエイター志望の学生である私が主に

 

・プレイしたゲームの感想・考察

・ゲーム制作における技術ネタ

 

を記録するために作成したブログです。

ゲームについての感想等には個人の見解が多数含まれますので、温かい目で見ていただければと思います。

 

また、このブログを通じて実際にゲーム業界で働いている方々や同じくゲームクリエイターを目指している学生の方々とコミュニケーションをとっていければと思っています。

少しでも私や私の作品に興味を持ってくださった方はコメント欄やTwitter等にメッセージお待ちしています。

 

工学系の学生の稚拙な文章ですが、これからよろしくお願いいたします。

 

とぐち

とぐち@ゲーム制作 (@toguchi_dev) | Twitter