ガレージ暮らしのトライタム

プログラムやツールの解説や技術を公開する場所

ここがすごいね。アズールレーン大鳳のLive2D

はじめに

ツイッターを眺めてたらTLに流れてきた大鳳のLive2D。

色々と高い技術が垣間見えたので記事にしました。
お胸様の揺れ方も質量を感じる大変素晴らしい出来なのですがそれ以外で3点ほど。

素晴らしいと思った場所

指パーツの切り替え

肩から腕を振っているタイミングで切り替えることで違和感なく指が切り替わります。
最初はこの状態。
f:id:traitam:20180914230317p:plain

そこからある程度切り替え後の形に近づけて
f:id:traitam:20180914230328p:plain

1フレームで切り替える。
f:id:traitam:20180914230336p:plain

指の切り替えについては一般的ですが変化のかけ方がすごく自然でフレーム単位で見ないと分からないレベルです。

前腕の影の切り替え

これも見てて驚いたのですが前腕は一切切り替えずに、影の不透明度で表現を行っているという点です。
動画最初の方では明らかに前腕に影が無いのに。
f:id:traitam:20180914230646p:plain

後半ではこの通り前腕下半分に影が出来ています。
f:id:traitam:20180914230713p:plain

作りの想定としてはベースとなる「ベタ塗り+アルファ」を基準に、「影パーツ」を作成し不透明度で表現を行っていると思われます。
そしてこれを大振りで腕を動かしている最中に不透明度を上げることで、より違和感のない表現に仕上がっています。
下手に前腕全部を切り替えるより、「腕のシルエットはそのまま」に腕の表現が行えるので違和感が減っています。この辺り下手に前腕全てをパーツ切り替えで表現を行うと、いくら素早い動きの中での切り替えでも切り替えのフェードイン・アウトが見えてしまうものです。
それを解消した今回の方法は特筆すべき項目です。

レコードの回転

そしてこれ。
Live2Dでは地味に難しい「パースの効いた回転表現」。表現方法についてはお手数ですが以下のTogetterをご覧ください。
togetter.com

Animatorでパーツを変形させることで回転デフォ―マだけで表現が行えますが、リアルタイムで再生させようとすると一苦労です。
リアルタイムで行う場合、Togetterの通りだとワープデフォ―マと回転デフォ―マでの力技になってしまいます。それか別の手法が既に編み出されていれば、その手法なのかもしれません。
しかし意外と難しい表現であるパースの効いた回転表現を入れているあたり、開発側の高い表現力が見て取れます。

おわりに

…なんだか最近Live2Dの商業レベルが一気に高くなっているような気がします。
ちょっと前までは、「前後表現のためだけに存在する線パーツ」ことはおろか、「輪郭・ベタ塗りと影パーツを分ける」とかも無かったような気がします。
線パーツについてはLive2DEuclidが出たあたりから表現を見るようになったと感じています。

Live2D界隈が盛り上がるのは大変良い事ですが、なんだか自分の技術が追い付かず置いて行かれてる感じがして悲しさを覚えます…。
あとSDKも愛して。


それでは皆さまよき創作ライフを。

【Live2DSDK】CubismSDK for UnityのUserEventで複数メソッドを呼ぶ

はじめに

公式チュートリアルではmotion3.jsonを扱う時、1つのメソッドを利用しているが複数のメソッドを使いたい時はどうすればいいかという記事です。
motion3.jsonに設定されたユーザデータを取得 | Live2D Manuals & Tutorials

最後のDebug.Logの出力までの大体の流れは同じです。
走らせたいメソッドの用意(新規スクリプト)、CubismMotion3Json.csの加筆の後にモデル+イベントのついたモーションをUnityへインポートします。
一度公式チュートリアルを試し、流れを把握してから本記事で改良を行うことをお勧めします。

用意するスクリプト

新規スクリプト

Unityで新規スクリプトを作成します。
以下はサンプルコードです。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MultiUserEvent: MonoBehaviour
{
    public void Listener(AnimationEvent animationEvent)
    {
        var currentState = GetComponent<Animator>().GetCurrentAnimatorStateInfo(0);

        Debug.Log("Time : " + (currentState.length / currentState.speed) + "\n" +
            "Value : " + animationEvent.functionName);
    }

    public void Listener02(AnimationEvent animationEvent)
    {
        var currentState = GetComponent<Animator>().GetCurrentAnimatorStateInfo(0);

        Debug.Log("Time : " + (currentState.length / currentState.speed) + "\n" +
            "Value : " + animationEvent.functionName);
    }
}

CubismMotion3Json.csの編集

CubismMotion3Jsonではインポート時にモーションがイベントを持っていれば対応することが出来る記述があります。
公式チュートリアルを参考にすると1つのメソッドを扱う時は以下のコードで問題ありません。

      var animationEvent = new AnimationEvent
      {
          time = UserData[i].Time,
          functionName = "Listener",    // 追加した行
          stringParameter = UserData[i].Value,
      };

ただこれでは1つのメソッドしか呼ぶことが出来ないのでいくつもUserEventがあり、いくつもメソッドをそれぞれに呼びたい場合は対応が難しくなります。
端的に言えばnewするタイミングでifやswitchで分岐させれば対応するメソッドをいくつも使う事ができます。
今回はモーションに付けられるEventの文章から条件分岐を行っています。

2つメソッドを使いたい場合

ifかswitchで行うほかに三項演算子で記述できます。ここではifと三項演算子のサンプルコードを示します。
ifの場合は以下のように、

 if (UserData[i].Value == "event01")
 {
     var animationEvent = new AnimationEvent
     {
         time = UserData[i].Time,
         functionName = "Listener",    // 追加した行
         stringParameter = UserData[i].Value,
     };
     animationEvents.Add(animationEvent);
 }
 else
 {
     var animationEvent = new AnimationEvent
     {
         time = UserData[i].Time,
         functionName = "Listener02",    // 追加した行
         stringParameter = UserData[i].Value,
     };
     animationEvents.Add(animationEvent);
 }

三項演算子の方は、以下のコードのようになります。

var animationEvent = new AnimationEvent
{
    time = UserData[i].Time,
    functionName = (UserData[i].Value == "event01") ? "Listener" : "Listener02",
    stringParameter = UserData[i].Value,
};

Valueで取っているのはCubismEditorでモーション作成時に入れた文章になっています。
f:id:traitam:20180912190900p:plain

他にも記述が必要な場合は、splitなどで一度分岐処理用の文字列を抽出してから行うと良いのかもしれません。
メソッド2つだけであれば三項演算子の方がスッキリするのでお勧めです。

3つ以上メソッドを使いたい場合

こちらもifかswitchで分岐を行うと良いです。

ただnewのタイミングで3つ以上分岐が並んでいたりswitchが列挙されていると冗長になってしまいます。メソッドとして切り出し、判別用stringを引数として判別するのが良いと思われます。
コールバック用メソッド名もベタ打ちではなく配列に格納したりするとコードをスッキリしそうですね。
それでもコードの汚さを無視しても良いのなら、同じ記述たくさんでもいいと思います。ifたくさんとかswitchまみれとか。出来ればよいのです。…っていうと色んな人から怒られそう

その他必要な作業

今回は2つのイベント用メソッドを用意しての確認です。
CubismEditorで2つ以上イベントが登録されているモーションを用意します。1つには“event01”と記述します。
その後モーションをUnityへインポートします。スクリプトを作成した後にインポートしないとイベントが登録されないので注意が必要です。
既にいれてしまった場合はモデルフォルダ右クリック->ReImportを押してインポートしなおしましょう。

動作確認

特に問題が無ければ以下のように2つのメソッドが呼ばれたことが確認できると思います。
f:id:traitam:20180912192228p:plain

思わぬ動作になった場合は文字列のタイピングミスやCubismMotion3Jsonの加筆後にモデルやモーションを再インポートしたか確認してください。


では、皆さまよき創作ライフを。

【Live2D】モデル制作時におけるバタつきの原因と対策

概要

これはLive2Dモデルの制作時に起きる「バタつき」についての原因と対策についての記事です。
バタつきは各パーツを動かした時に動かす幅が異なると発生します。
対策としてグリッドやスクショから動かす幅の確認をすることで修正が容易になります。
またパラメータをゆっくり動かして、周辺のパーツより先に動けば「動かす幅を少なく」、後に動けば「動かす幅を多く」することで修正が可能です。

バタつきとは

各パーツを動かす際に発生する違和感を指します。
特にこれは顔を動かす角度XYで顕著に発生すると思っています。

下のGIFが例になります。右目だけ動かすと滑って移動しているように見えます。
f:id:traitam:20180911172443g:plain

今回は顕著な例ですが、実際になると「なーんか動かしたときに違和感を感じる」くらいの問題になります。
完成だけを目指すのであれば無視しても良いのですが、品質向上に努めるのであれば避けては通れない問題です。

原因

違和感のある例として挙げたGIFでは右目だけ、左目や前髪と比べて横に動かす幅が長いです。
左目と緑線を用いて比較をすると以下画像のようになります。
f:id:traitam:20180911173733p:plain

右目は左目の数倍多く動かしていることが分かると思います。

原因となるその他の要素

今回は見受けられない要素ですが、1つのパーツだけ上下に動いているという場合もあります。
「体の回転Xについても~」から以下の例で分かりやすく解説がありますので、そちらをご覧ください。
dream.live2d.com

対策

対策としては「動かす幅を周辺と同じくらいにする」なのですが、動かす幅が多いのか少ないのかというのは分かりにくいです。
これについてはいくつか方法があります。

エディターのグリッド機能を使う

Live2DCubismEditorにはグリッド機能があり、赤枠内のアイコンを押すことでグリッドが表示できます。
f:id:traitam:20180911174516p:plain

これを用いて各々がどれくらい動いているか判別できます。

エディターのスクリーンショットから比較する

グリッド機能同様、エディターからスクリーンショットを撮ってどれだけ動いたかを確認できます。
f:id:traitam:20180911174757p:plain

半透明で重なっているため細かく見ようとすると大変ですが、グリッドと違って明確な分かりやすさがあると思います。

パラメータを動かして判別する

バタつきは動かす幅が違うため発生するので、パラメータで動かすと違和感が感じ取れます。
ただそれだけでは動かす幅を多くすればいいのか、少なくすればいいのか分からないので以下のルールに基づいて違和感を具体化します。

  1. 比較する2つのパーツを選びます(今回では右目と前髪)
  2. 違和感の原因となるパーツを選びます(今回は右目)
  3. パラメータを「少しずつ動かし」右目が先に移動すれば「動かす幅が多い」です。前髪が先に移動すれば「動かす幅が少ない」です。
  4. 動かす幅が多かった場合は少なく、逆であれば多くします。

この方法は先2つより正確性に欠けますが、グリッド見たりスクショ撮ったりするのが面倒な方は良いかもです。

対策後

今回は右目の動かす幅を少なくすることで対処ができる問題です。
そして修正したものが以下GIFになります。
f:id:traitam:20180911175719g:plain

以下画像の青線のように、動かす幅を左目と近くしました。
f:id:traitam:20180911175903p:plain

これで違和感は、「ある程度」解消されました。
違和感修正の程度に関しては個人差としか言えないと思うので今回はこれくらいでOKとします。

おわりに

パラメータ作成時、バタつきによる違和感があったらパーツ間で動かす幅が統一されているか確認してみてください。
問題が解消されるかもしれません。

では、皆さまよき創作ライフを。

iPhone5の簡易修復

iPhone5を廃棄すると別の方が仰られたので、譲って頂きました。
ただ、スマホ上部のタッチパネルが浮き上がっておりガムテープで無理やり止められている状況だったので、それを修復しました。
この記事はそのメモ書きのようなものです。


予想された問題

タッチパネルが浮き上がる問題では、最初にバッテリーが膨らみが原因で起きると想定されます。
そのため分解用に以下のキットを購入しました

DIGIFORCE LPB-DIGI5 互換バッテリー 説明書・工具付 PSEマーク表示
Amazon CAPTCHA


想定していた問題と違った

分解に関する記事は沢山あるので割愛します。
f:id:traitam:20180808205348j:plain
f:id:traitam:20180808205513j:plain

画像のようにどんどんと分解していきます。
赤枠内はメインボードとタッチパネルを繋ぐフラットケーブルなので外さないように、壊さないように気を付けながら作業します。

が、想定していた「バッテリーの膨らみ」が全くなかったので別の問題でパネルが浮き上がったみたいです。

落下衝撃による歪みが原因だった

前の持ち主はそういえば落としてパネルが浮き上がったと言ってました。
どうやら、iPhoneが歪みその結果、接着剤が負けて浮き上がったようです。
また、接着剤も経年劣化で粘着力が落ちていたようです。
そのため、新規に接着剤で接着しました。


対策

自宅に手ごろな粘着テープが無かったので以下の接着剤を使用しました。

セメダイン 瞬間接着剤3000ゼリー状速硬化 P3g CA-154
https://www.amazon.co.jp/%E3%82%BB%E3%83%A1%E3%83%80%E3%82%A4%E3%83%B3-%E7%9E%AC%E9%96%93%E6%8E%A5%E7%9D%80%E5%89%A4-3000-%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA/dp/B0751GGK7L

塗る前に汚れを取ります。その後に接着剤を塗る流れです。
接着剤は、一度爪楊枝に付けてから塗るようにしました。
塗る場所は、左上部はガラスパネルとくっ付いているアルミフレーム。右上部は筐体側にある接着部分です。

これで接着を待った後、組み立てればOKです。
もちろん歪みは直して無いので左右中央は少し浮いてます。
ただ、ガムテープに巻かれているよりかは幾分もマシになりました。

ガムテープで巻かれいた部分は、接着剤の残りがくっ付いていたので除光液で取りました。


残っている問題・やってしまった失敗

破損していたタッチパネルの修復

落下による破損で歪みだけでなく一部タッチパネルが効かなくなっていました。
これは直していません。別にそこまでコストかけても…。

本体の歪み

歪みも同様に直していません。
直す場合も内部のパーツをすべて取り外し、歪みを補正する必要が出てくるのでコストが…。

液晶内部にゴミが混入

ガラスパネルとフレームがくっ付いていないタイミングで掃除をしたので、そのゴミが内部に入り込んでしまったようです。
ただ、背景が暗いと全然見えないし、操作にも問題無いのでOKとします。

f:id:traitam:20180808210941j:plain


おわりに

こうして無事にiPhone5が復活しました。SIMは入ってないのでWi-fi専用機です。
今回みたいな簡単な機器の修理は楽しいですね。蘇ってくれる楽しさを味わえます。

VTuber向けLive2Dモデルについての思案

発端

このモデルが大変素晴らしく、また可能性を考えるきっかけになりました。

先のモデルの何に感銘を受けたか

まずはテンプレートになりつつある正面絵では無い事。
Live2Dモデルでは手始めに正面絵を作成することが多いです。
公式チュートリアルしかり、既存のモデル状況しかり。
実際、特定のポーズや状態を表すと汎用性に欠けるため正面モデルが無難なのかもしれません。

けれども先のモデルは汎用性を備えつつ正面モデルではない、ユニークに仕上がっています。
加えてFaceRigでのアニメーションやパーツ切り替えを駆使してより高品質になっています。
そして何より、角度Xのパラメータで2つの顔を動かすという発想が、あるようで無かった発想で驚きました。
すごい。

ほかにどのようなユニークモデルが作れるか?

では、先のモデルを参考にどのようなモデルが作れるか考えてみたいと思います。

操り人形型

f:id:traitam:20180804192517p:plain

糸によって吊られている人形が演じる実況。
正面モデルを踏襲しつつ、動きを人形にすることで独特な雰囲気が作れると思います。
ダークカラーの服を着れば怪しくも出来るし、パステルカラーのロリータを着ればふんわりした印象に。
糸の動かし方と、人形っぽい動きを入れることができれば、正面モデルを作ったことがある方なら作成可能かもです。
…というか操り人形は別にロリータモチーフじゃなくてもいい気が

ソファでくつろぎ美少女(斜め向き)

f:id:traitam:20180804192526p:plain

基本的には正面を見ないで画面見ていますよという印象を与えるモデル。
時折こちらを向いてドヤったり笑ったり、隣で美少女がゲームをしているという印象を与えるかもしれないモデルです。
顔の角度Xは0~30に作成して、0のデフォルトを斜めにすることで実現が可能だと思います。
またパーツの有無で以下のようにシチュエーションも変えられます。
  「これ?今日はコンタクトじゃなくてメガネしてるんだよ~」とか
  「今日はすぐ外出なので身支度整えるんだ~」とか
  「今日はOFF!飲み物お菓子携えてゲーム三昧!」などなど

2つ目は衣装変更なのでモデル制作のコストが上がりますが、眼鏡付けたり、横に飲み物お菓子を置く位ならパーツの有無で低コストで変化を付けられます。

これは
【セミナー】なぜ彼女たちは“こんなにも魅力的で可愛いのか…?” 開発者が語る『アイドルマスター』におけるイラスト制作の工程とは | Social Game Info
という記事内で言われている「1mの近さで見ている感覚」をイメージして構想が練られています。
特にVTuber界隈では「ガチ恋」という言葉もあるくらい、モデルに併せてその中の人に恋をしてしまう現象もあります。
ここでは、1mの近さで見ている感覚、というのが肝です。

斜め向きではなく真横~正面というモデルが作れるのならより良いのですが難易度がかなり高いです。
行った事ある方、挑戦してみたい方はいいかもです。
もし実現できれば、左右の動きが「前のめり/仰け反り」の動きになります。そうすることで顔だけでなく体を使って感情を表現できます。

その他モデルについて

正直「顔が正面、もしくは浅い角度で斜めを向いているモデル」であれば実況用などで使えると思っています。
特に「1mの近さで見ている感覚」はアイドルマスターの魅力で証明されているため、魅力的なモデル作成で有用と考えられます。
普通の正面モデルを作るのに飽きた方は、是非に。見てみたいです(他力本願)

それではみなさん、楽しい創作ライフを!

Cubism3SDKUnity内に含まれるサンプルの簡易説明

Cubism3SDKUnityにはR8時点で9つのサンプルが同梱されています。
シーンを再生すればすぐにフィードバックがあるサンプルから、コードを変更する必要のあるサンプルがあったりと色々なので簡素に内容をまとめようかな。という記事です。

Cubism3SDKUnityに同梱されているサンプル(バージョンR8時点)

f:id:traitam:20180728155953p:plain

R8時点では上記画像のように9つサンプルが同梱されています。
すぐに何をやってるのか分かりやすいのがAnimation、AsyncBenchmark、LookAt、Raycastingの4つだと思います。
この4つはシーンを開いて再生すれば、何をすればよいのか、何が行われているのか端的に分かりやすいと思います。

ほかの5つはソースコードを変更したり、エディタ上で変更を行うことで変化が得られる、Unityを触っている人向けのものになっています。
おそらく、全くUnityを触ったことが無く、かつCubism3SDK初挑戦だと、この5つのサンプルを弄っても“何のためのサンプルなの?”と首を傾げる可能性があります。

“とりあえず動くものを見てみたい”という方は、先に挙げた4つのサンプルのいずれかを閲覧すると良いかもしれません。
以下は各サンプルの概要です。

Animation

f:id:traitam:20180728155806p:plain

シーンを再生するとキャラクター(こはるちゃん)がアニメーションしてくれます。
可愛いですね。

AsyncBenchmark

f:id:traitam:20180728160627p:plain

ボタンを操作することでベンチマークを行うことが出来ます。
また、HierachyにあるSpawnerをクリックし、[ModelSpawner]->[Model Prefab]を変更することで表示するモデルを変更することが出来ます。

ほんの少し追加解説

Asyncと銘打たれている通り、Asyncで非同期処理を行って表示しています。
Unityで広く使われているコルーチンではメインスレッドを活用して非同期処理を実現していますが、Asyncの方は実際にスレッドを分けて処理しています。

Editor

このフォルダに説明テキストとImportCustomization.csの2つのみとなっています。
ImportCustomizationはモデルをインポートした際、モデルに独自変更を行う機能が書かれています。いわばモデルインポートにおける拡張機能のサンプルです。
使用の際は33行目の、コメントを外します。
f:id:traitam:20180728161541p:plain

コメントを外した後にモデルをインポートするとモデルが緑がかってインポートされるようになります。
右のモデルはコメントを外した後に、モデルをインポートした例です。(自動的にモデルはインポートされないので手動で行う必要があります)
f:id:traitam:20180728162126p:plain

もし、ロードタイミングが分かりにくい場合は36行目の下にDebug.Logで読み込まれたことを確認すると良いと思います。
注意:コメントを外した部分は確認が終われば、再度コメントアウトするようにしましょう。以降のモデルインポートで全てのモデルが緑色になります。

LookAt

f:id:traitam:20180728162504p:plain

キャラクターがLive2Dのロゴを見つめ続けるサンプルシーンです。
実際にこのように実装したい場合は以下の公式記事をご覧ください。
視線追従の設定 | Live2D Manuals & Tutorials

Masking

MaskTextureは原則共有されているから、もし独自に作りたい場合はMaskTexturePreviewから変更を行うと独自の変更が出来るよ。
…というサンプルシーンなのですが、イマイチ変更が上手く行きませんでした。

すいません、よく分からないので変化が見れる画像もありません。

Models

Maskingで使われているモデルと、サンプルシーン全般に使われているモデルが含まれています。
特にサンプルシーンも特別追加されたスクリプトなどは、ありません。

MultipleModels

f:id:traitam:20180728163126p:plain
f:id:traitam:20180728163130p:plain
複数モデルが存在するときにモデルの描画順についてのサンプルシーンとなっています。

基本状態ではキャラクターが前になっていますが、HierarchyのClippingを選択し
[Cubism Render Controller]->[Sorting]->[Order In Layer]の数値を変更することで描画順を変更することが出来ます。
例としてはCrippingモデルの方を“2”にすることで前面に来るようになります。
キャラクター(Koharu)と同じ数値である“1”を選択すると2つが混ざったような見た目になります。これは期待されない処理なのでそうならないように気を付けましょう。

PerspectiveCamera

f:id:traitam:20180728164052p:plain
f:id:traitam:20180728164049p:plain
Live2DではCamera設定はorthographic(Unity 2Dモードの標準設定)で活用されることが原則となっています。
しかしperspective(3Dモードの標準設定)で活用したい人に向けたサンプルになっています。

Live2Dモデルをperspective上で正しく描画させるには[Cubism Render Controller]->[Sorting]->[Mode]を[Back To Front Order]に変更する必要があります。
このサンプルシーンで[Back To Front Z]に変更すると描画が乱れることが確認できると思います。
ちなみにカメラ設定は[Camera]->[Projection]から確認することができます。

RayCasting

f:id:traitam:20180728164209p:plain

マウスでクリックした時に、マウス上にあったものを一覧で表示するサンプルです。
専門的に言うと、マウスクリック時にレイを射出し、レイにヒットしたDrawablesの一覧を表示するサンプルです。

おわりに

これでR8時点で含まれているサンプルの紹介は終わりです。
サンプルの詳細をもっと知りたい、という方は公式SDKチュートリアルへアクセスすれば大体は乗っていると思います。
TOP | Live2D Manuals & Tutorials

半分はUnity経験者向けのサンプルなので、割とハードルが高いサンプルですがこの記事がヒントになると嬉しいです。
それではみなさん、楽しい創作ライフを!

UnityのLive2DCubism3SDKでUserEvnetをインポートする時の注意点

motion3.jsonに設定されたユーザデータを取得 | Live2D Manuals & Tutorials

上記リンクのある通り、公式のSDKチュートリアルの通り行えば基本的には問題ありません。
ただ、「厳密に」上記の順番で行わないと問題が起きます。
今回はモーションにユーザーイベントを登録して検証をしています。

目次

どのような問題が起きるのか

f:id:traitam:20180725223051p:plain

順番を間違えると画像のようにイベントが登録されていないとエラーを吐かれます。

なぜこのような問題が起きるのか

Eventのハンドルもモデルをインポートした段階で登録されます。
そのため「Live2Dモデルのインポート」→「スクリプトにイベント登録処理を追加する」順番で行うとインポーターがイベントを拾えるが上手く追加できないという事態になります。

解決策

解決策としては「スクリプトにイベント登録処理を追加」→「Live2Dモデルをインポート」という順番を守ればOKです。
また先にモデルをインポートしても「モデルフォルダクリック」→「Reimport」で再度インポート処理を走らせれば対策できます。
モデルを再インポートした場合はアタッチが外れているので再度付け直しましょう。
解決されれば無事にDebug.Logが走ります。(例ではモーションの2か所にUserEventを登録しているため2つ出ています)
f:id:traitam:20180725224243p:plain


解決策が分かれば難しい問題ありませんが、分からないと何が原因か分からず最悪詰まる可能性があるかもしれません。
UserEventをUniyで扱う時は少し意識しておきたいですね。

それではみなさん、楽しい創作ライフを!