hibitの技術系メモ

数学とか3Dとか翻訳とか

FE(ファイアーエムブレム)に性差別はあるのか?~あるいは多変量解析と有意差検定~

 どうも、今回の記事はVRもCGもあまり関係ありません。敢えていえば数学です。

 皆様はFE(ファイアーエムブレム)という家庭用ゲームのシリーズをご存知でしょうか。任天堂が発売しているSRPGで、戦場でコマを動かして敵を倒して……というジャンルの草分け的存在でもあります。このシリーズ、ユニットがレベルアップする時に、そのパラメータが乱数によって上がるというユニークなシステムがありまして、その数に一喜一憂するのも大きな楽しみです。

 しかしこの成長率、どうも「美男美女>>>その他大勢」「美女・ロリ>>>醜男・老人」的なルッキズム/セクシズムに支配されていて、なんとなく現代のポリティカルコレクトネスに反しているように思えてなりません。そこで、本記事ではその点を統計解析によって厳密に検証していくのが目的になります。美醜/年齢は厳密なラベリングが難しいので、今回は性別に焦点を当てていきます。

 なお、余談になりますが、FC・SFC時代は「剣=正義=高性能=イケメン>>>斧=悪役=低性能=悪役顔」という斧差別が深刻であったのですが、トラキア776ではアファマティブアクションによる斧優遇が入りまして、今ではいいバランスに落ち着いています。やはり現実世界と同様、ゲームにも時代に合わせた倫理観のアップデートが必要ですね。後述しますが、トラキアは斧優遇以外でも、シリーズで独自の立ち位置を築いています。

成長率のリストアップ

 まず、全シリーズをまとめた成長率のリストを作成する必要があります。しかし、各シリーズによってパラメータの項目があったりなかったりするので、まずそれを整理する必要があります。整理したのが下の表です。

タイトル HP 魔力 武器 速さ 守備 魔防 体格 移動
暗黒竜と光の剣 - - -
外伝 - - -
紋章の謎 - - -
聖戦の系譜 - - -
トラキア776 - -
封印の剣 - - - -
烈火の剣 - - - -
聖魔の光石 - - - -
蒼炎の軌跡
暁の女神 - - -
新・暗黒竜と光の剣
新・紋章の謎 - - -
覚醒 - - -
if - - -
エコーズ - - - -

「△」は、成長率がほぼゼロであったり低いパラメータに設定されていたりするものです。つまり、上がるのが非常にレアなパラメータです。トラキアは「移動」と「体格」が上がる可能性があるというぶっ壊れ具合だったなあ……。

 もう一つ整理する必要がある点は、シリーズがリメイクを重ねているということです。「紋章の謎」は「暗黒竜と光の剣」のリメイクですし、更にそれをリメイクして「新・紋章の謎」が発売されています。こういったリメイクを全てカウントしていくと、同じキャラが複数出現してしまってデータが見づらくなります。なので、リメイクがされているものはそれを優先して、リメイク前のタイトルのデータは使わないという整理をします。それとは別に、異なるタイトルで同じユニットが出る(「新・紋章の謎」のカチュアと「エコーズ」のカチュア)ものや、同じ作品で年齢等が違う(「聖戦の系譜」の親世代のフィンと子世代のフィン)という例もありますが、それは異なるユニットとしてカウントします。

 以上のような要素を勘案した末に調整した表が以下になります。

タイトル HP 魔力 速さ 守備 魔防
聖戦の系譜
トラキア776 魔力
封印の剣
烈火の剣
聖魔の光石
暁の女神
新・紋章の謎
覚醒
if
エコーズ

「力」と「魔力」は、当該タイトルにそのパラメータがないので便宜的に他パラメータから流用したものです。タイトルによって「力=魔力」(つまり、武器と魔法を同時に使用するケースがない)ものと、「力と魔力は独立」(マスターナイトのように、武器と魔法とを両方使えるクラスが存在する)ものがあるので仕方ないです。トラキアは「魔防=魔力÷2」としているので、魔力を流用します。エコーズの魔防は成長率が低めに設定されているので10倍補正します。

 そのような調整を経た後の成長率リスト、いわば全シリーズ統一成長率表を作成したのですが、それを貼ると557行の膨大なデータになってしまうのでgithubにまとめております。ちなみに性別の欄は私が手作業で入力しました。疲れた……! どこかにミスがあるかもしれないので、プルリク等随時募集しております。

 なお、データの収集にあたっては主にかわき茶亭様のデータを使用させていただきました。この場を借りてお礼を申し上げます。

外れ値の除外

 なお、上のデータではカレル(封印の剣)とマリナス(封印の剣)(烈火の剣)を除外しています。カレルは成長率が一人だけダントツで高いためです。その成長率に意味があるならまだわかりますが、終盤で加入してレベルも上限に近い、いわゆる「お助けキャラ」(レベルアップしても意味ないので成長率は低いのが普通)なのに、なぜか異常なまでに成長率が高く設定されています。スタッフのお遊びでしょうか……。FEは時々スタッフの贔屓が目に見えるのが玉に瑕です。マリナスは非戦闘員の割りに成長率が高く、ノイズになりそうなので除外させてもらいました。

 また、外れ値という訳ではないのですが、聖戦の子世代の子供ユニットのほとんどは、成長率を一意に定めることが不可能なため除外しています。

主成分分析

 実際に統計的有意差の検討に入る前に、ユニットの成長率の分布を見た方が面白いので先にそちらの話をします。パラメータは、HPから魔防までの8種類がありますが、8個だと多すぎるので3個に集約しましょう。もし、8個のパラメータに何の偏りもなく散在しているならば集約は不可能ですが、現実のデータにはほぼ必ず何か偏りが存在します。例えば、魔力の成長率が高いユニットは魔防のそれも高い傾向にあります。そのような似た傾向を持つパラメータをセットにして少数の重要な変数に要約する方法を主成分分析(Principal Component Analysis)と言います。偏ったデータが真っ直ぐに見える「角度」を見つけ出す方法とも言えます。以下、556ユニットに対して主成分分析を行った結果です。

f:id:hibit_at:20181022033844p:plain

f:id:hibit_at:20181022034358p:plain

 PC1、PC2、PC3の3次元のデータをそのまま表すのは不可能なので、2つの2次元に分けています。赤い文字は女性ユニット、青い文字は男性ユニットを指します。

 PC1が低い側はファやミルラといった高成長率ユニット(マムクートがロリだから、ちくしょう!)、高い側がアランやバヌトゥといった成長をあきらめたユニット(ジェイガン系)(ジェイガンは集計の都合上いませんが……)であることから、PC1は「全体的な成長率の低さ」であることがわかります。

 PC2の高い側はトリスタンやヨハルヴァといった肉体派ユニット、低い側はサラやミカヤといった魔法系ユニットであることから、PC2は「肉体派傾向」であることがわかります。PC2の高い側に、アルテナ、リーフ、キュアンと並んでいるのが親子の絆を感じさせてよいですね。逆に、ロナンは弓使いなのになぜそんなに魔力の成長率が高いの?

 PC1とPC2のベクトルは以下のようになっています。

PC1 f:id:hibit_at:20181022040937p:plain

PC2 f:id:hibit_at:20181022040953p:plain

 おおむね所感と一致していますね。

 なお、3次元のグラフもrglライブラリを使って描画可能なのですが、文字ラベルを載せられませんし、グラフを動かせないとあまり意味がないのが辛いですね。やはり人類は一刻も早く2次元ディスプレイを脱出してVR空間で3次元情報を扱えるようになるべき……。一応下に3次元グラフ(の1投影)を載せておきます。私の技量をもってすれば4次元以上のグラフも、投影と回転を駆使して描画できないこともないですが、それをしたところでわかりやすくなる訳でもないので、しません。

f:id:hibit_at:20181022034314p:plain

線形判別分析

 男女によって成長率の傾向に違いがありそうということがわかりました。では、成長率から性別を予測できるのでしょうか。先程の主成分分析は、男女関係なく数値を解析した後で「色付け」をしてその分布を見ましたが、最初から「男女」の違いがわかった上で変数を組み立てれば、成長率から男女を予測するようなモデルを作れるのではないでしょうか。線形判別分析(Linear Discriminant Analysis)という手法でそれを実験してみましょう。すごく原始的ですが、これも一種の教師あり機械学習というやつです。

 判別分析では通常、学習データ(training data)とテストデータ(test data)を分けます。全てのデータを基に学習すると良い成績が出て当たり前なので、学習データと無関係なテストデータを正しく判別できてこそということです。そこでそのようにデータを分けるかという点が重要になるのですが、ここは「暁の女神」以前(FC~Wii)と「新・紋章の謎」以降(DS~)でちょうどハードも分かれてキリがいいので、そのようにしています。(なお、全てのデータを学習に使って、データ内で学習データとテストデータを交互に分け続ける交差検証(cross validation)という手法もあるのですが、今回は正攻法でいきます)

 以下が、暁以前の312ユニットを基に学習させたモデルから、新紋章以降の244ユニットを対象に判別分析を行った結果になります。

M F sum
M 137 9 146
F 68 30 98
sum 205 39 244

 …あんまり判別率がよくないですね。特に女性(F)は過誤(Mと判定)の方が多いです。成長率だけで男女を断定することは難しそうです。

有意差検定

 いよいよ核心に入っていきます。女性ユニットは男性ユニットに比べて有意に成長率が高いと言えるのでしょうか。まずは単純なランキングを並べてみます。

順位 名前 性別 合計
1 ファ F 690
2 ミルラ F 670
3 セティ M 475
4 セリス M 440
5 チャド M 415
6 サラ F 410
7 アルテナ F 404
8 エフラム M 400
9 ミカヤ F 400
10 ビーゼ F 400

 色々な作品からバランスよく選出されていますね(GBA世代のマムクートはダントツですが)。私はこの中だとビーゼさんが一番好きです。クールだけど無愛想じゃないところが好き。4章で加入してから頑張って育てると一気にエースになれるところも好き。解析する前は、作品によって成長率の「相場」が違ったらどうしようかと思っていましたが、そこまで違いはなさそうです。男女比も、トップ10を見るだけではなんとも言えませんが、そこまで偏りはなさそうです。

 では、統計検定に入る前に、まず分布が正規分布に従っているかを確認します。自然な分布は、平均を中心に釣鐘状の分布(正規分布)を示すもので、「統計的に差がある」という場合もこの分布を前提にしているものが多いです。この前提が崩れていると(フタコブラクダみたいな分布とか)例えば偏差値とかも信頼性がなくなってしまいます。え? 偏差値って頭の良さじゃないのって?

f:id:hibit_at:20181022194848j:plain

(「無頼男/梅澤春人」6巻より引用)

 失礼、取り乱しました。何はともあれヒストグラムを書いてみたらハッキリします。下図が成長率全体のヒストグラムです。

f:id:hibit_at:20181022195214p:plain

 ついでに、男女の違いを明示してみますか。

f:id:hibit_at:20181022200614p:plain

 男性の平均は281.3、女性の平均は304.2であり、平均は女性が優れていることはすぐにわかるのですが、問題はこれが統計的に有意な差といえるかどうかです。  この分布、見かけはなんとなく釣り鐘っぽいのですが、正規性を確認するShapiro-Wilk検定を行うと

        Shapiro-Wilk normality test

data:  x[, 12]
W = 0.9096, p-value < 2.2e-16

 となり、2.2*10^{-16}というすごい数値で棄却されます、残念。これではt検定が使えない……。しょうがないのでノンパラメトリックな手法であるU検定を試みることにします。

        Wilcoxon rank sum test with continuity correction

data:  xM[, 12] and xF[, 12]
W = 30221, p-value = 0.002382
alternative hypothesis: true location shift is not equal to 0

 なんと、帰無仮説(男女差はない)の採択率は0.002382\simeq0.2\%となり棄却されてしまいました。よって、対立仮説である「男女差はある」が採択され、ファイアーエムブレムにおいてはやはり女性ユニットが成長率において優れていることが統計的にも明らかになってしまいました。なんたるポリティカルコレクトネス違反。任天堂およびインテリジェントシステムズは、現代に相応しいゲームを開発するべくその倫理観をアップデートされたし。

まとめ

  • ファイアーエムブレムにおいて、成長率は「全体的な成長率の高低」「肉体派か魔法系か」によってある程度要約される
  • 成長率だけで男女を予測するのは困難
  • 女性ユニットの方が有意に成長率が高い傾向にある
  • ポリコレ云々はすべてジョークです
  • Swtichで発売する予定の据置新作楽しみにしています

 以上です。Further studyが望まれますが、それは筆者の統計能力の上達を待ってからになります。

Blenderを一切触らずにボクセルアバターを作成する方法

 MagicaVoxelは簡単にボクセルデータを作れる素晴らしいソフトです。今まで3Dソフトを触ったことがない人でもマイクラ感覚で簡単にアバターを作れる……と言いたいところですが、アバターに持っていくためには

  • リギング
  • テクスチャ画像作成

 という2つの工程を経る必要があり、これにはBlender等の3DCGソフトを用いる必要があります。

 いや、Blenderは無料ソフトだし、サンフィッシュ熊野さんの素晴らしい解説記事があるので、これを見ながら操作すればええやんと言われたらそれまでなのですが、世の中には宗教上の理由でどうしてもBlenderを触れない人もいると思います。そのような方のために、Blenderを一切触らずにボクセルアバターを作成する方法を伝授します。

mixamoによるリギング

 mixamo、というAdobeが提供しているサービスがあります。これはなんと自動でリギングをしてくれるというとてもすごいサービスです。Adobeのユーザー登録が必要ですが、別に登録するだけで金を取られるようなものではないので、しましょう。以下、SSによる解説。

f:id:hibit_at:20181011204058p:plain

 まず、MagicaVoxelでメッシュを作成します。今回は説明のために緋色さんの素体を使わせていただきます。ありがとうございます。

f:id:hibit_at:20181011204401p:plain

 エクスポートする時に「obj」形式を選択します。

f:id:hibit_at:20181011210201p:plain

 熊野さん方式だとplyですが、ここではobjにします。そうじゃないとmixamoで読み込めないからです。出力先には、objファイルと、mtlファイルと、謎の虹色のpngファイルが出力されたと思います。このpngファイルは後で使います。

f:id:hibit_at:20181011204620p:plain

 次にmixamoを開いてこのobjデータを読み込ませます。私はすでに一通りテストした後なのでこの画面ですが、サインインしたばかりだと中央のウィンドウには誰もいないはずです。右上にあるオレンジ色の「DOWNLOAD」……ではなく、その下の「UPLOAD CHARACTER」のボタンを押します。

f:id:hibit_at:20181011204922p:plain

f:id:hibit_at:20181011205041p:plain

 先程エクスポートしたobjを読み込みます。ドラッグ&ドロップでもいけます。

f:id:hibit_at:20181011205357p:plain

 それぞれの色の輪っかをドラッグして対応する箇所にはりつけていきます。「NEXT」を押したらオートリギングが始まります。英語のメッセージで「2分ぐらいで終わります」とありますが、大体1分足らずでやってくれます。終わったらなんかメッセージウィンドウが出てきますが、何も考えずに「NEXT」を押し続けていきましょう。

f:id:hibit_at:20181011205615p:plain

 終わったらリギング済みのキャラクターが画面に出てきます。ここでやっと右上の「DOWNLOAD」を押します。ここで左側にあるアニメーションアイコンを押すとアバターが動き出してTポーズでなくなってしまうので注意です

f:id:hibit_at:20181011205819p:plain

 フォーマットはfbx、ポーズはTポーズでDOWNLOADしましょう。

Unityでの操作

 できあがったfbxをUnityに持ち込みます。……が、真っ白です! これは、fbxはテクスチャ画像を含まないという仕様によるものです。なので、別途テクスチャ画像を用意してあげる必要があります。実はそれが、最初にobjファイルをエクスポートした時に出した謎のpngファイルです。

f:id:hibit_at:20181011210538p:plain

 真っ白なfbxをクリックした時に出てくるマテリアルにpng画像をぶち込めば……

f:id:hibit_at:20181011210651p:plain

 このように無事最初の着色通りのアバターができました。カラーパレットからピンポイントで色を持ってくるような変態的なUVマップを持っているということでしょうね。

 ちなみに、もっとベタッとした発色にしたい~という方はUnlit Shaderにしてください。

f:id:hibit_at:20181011211022p:plain

 ここで変えられます。

humanoidを適用

 今だとまだアバターは直立不動のgenericアバターなので、humanoidを適用します

f:id:hibit_at:20181011211813p:plain

 右上の欄にある「Animations」を「Rig」にして、「Generic」を「Humanoid」にして、「Apply」を押します。これでhumanoidになりました。これでアバターに「VRC Descriptor」を適用すればもうアップロード可能に……!

(※VRC Descripotorの適用等についてはこのページの解説がとても詳しいです)

ボーンの罠

f:id:hibit_at:20181011212216p:plain

 Your rig has the UPPER CHEST mapped in the Humanoid Rig. This Will Cause Problems with IK.じゃあないんだよYour rig has the UPPER CHEST mapped in the Humanoid Rig. This Will Cause Problems with IK.じゃあ。

(和訳:あなたのリグには、ヒューマノイドリグにマップされたUPPER CHESTがあります。これはIK上の問題を引き起こす可能性があります。)

 はいはい、UPPER CHESTを外せばいいのね。Configureしていきましょう。

f:id:hibit_at:20181011212444p:plain

f:id:hibit_at:20181011212533p:plain

 ここを選択してDelキーを押せばここのリグを外すことができます。

 これでやっとアップロード可能に……!

f:id:hibit_at:20181011212703p:plain

 は~~~~~~~~?

 Spine Hierarchy incorrect. Make sure that the parent of both Shoulders and the Neck is the Chest.じゃあないんだよSpine Hierarchy incorrect. Make sure that the parent of both shoulders and the Neck is the Chest.じゃあ。

(和訳:Spineの階層が正しくありません。ShouldersとNeckの親がChestになっていることを確かめてください。)

 結論から言うと、もともとUpper ChestにあったボーンをChestにもってくる必要があります。何このトラップ。

f:id:hibit_at:20181011212954p:plain

 こうなればOKです。

 これでやっとアバターがアップロードできます。

 blenderを無視して、mixamoで横着したものには、最後には神罰が待っているのだ……!

アニメーションオーバーライドによって中腰になってしまったアバターを直す方法(Unity5.6.3用)

※Unityのアップデートに伴い、以下の「方法1」は使用できなくなりました。Unity2017用の方法は、こちらを参照願います。

 アニメーションオーバーライドを適用したアバターはなぜか以下のように中腰になってしまうことが知られています。

f:id:hibit_at:20180921214146p:plain

方法1(手軽なやつ)

 これを解決するためには、

 この方法が一番手っ取り早いです。

 先日この方法を動画にしたものをTwitterに投稿したので、それを見るのがわかりやすいです(手前味噌)。

 こんな感じで操作すれば一瞬で中腰を直すことができます。

 めでたしめでたし。

 ……。

 聞こえる……。

 聞こえるぞ……中腰に親を殺された者達の恨みの声が……!

方法2(中腰を憎む人用)

 実は上の方法で中腰を直しても再生中は中腰になってしまいます(再生が終われば直ります)。中腰にトラウマのある方にとっては、それを見るのもイヤだということがあるでしょう。今日はそんな中腰ヘイターのために、完膚なきまでに中腰を絶滅させる手段を伝授します。

 Unityのアセット欄をたどって、

Assets > VRCSDK > Examples > Sample Assets > Animation

 の中にある「tpose-new」の横にある小さな再生ボタンを押します。(押しづらいわ!)

f:id:hibit_at:20180921214316p:plain

 そうしたらその横に「tpose-new」というアニメーションファイルが出てくると思うので、それを選択した状態でアニメーションウィンドウを押すと、   f:id:hibit_at:20180921214535p:plain

 このように、夥しい数のアニメーションコンポーネントが出てきます。これを全部コピーして、元々あった(つまり中腰の原因になっていた)アニメーションにペーストします。

f:id:hibit_at:20180921214856p:plain

 解決!

 こうしてこの世から中腰が消え、VRCの世界の平和は保たれることとなった。

 TRUE END

※方法1でも特に不都合はないので、こだわりがなければ方法1をオススメします。  

5次元立方体に関する数学的解説

 先日、以下のツイートがややバズりました。

 

 主にプログラミングに関する解説については、qiitaに載せましたが、

 5次元のままでは3次元で描画できないので3次元に投影する必要があります。投影の方法としてはステレオ投影が有名ですが、これだけだと1次元しか集約できないので、その他に斜投影を使います。

 の辺りは数学的な予備知識がないとサッパリだと思うので、このエントリではその辺りに解説を加えていきたいと思います。

そもそも次元とは

 ここではn次元空間に限って話そうと思います。

  • 1次元は軸が1つ → 直線
  • 2次元は軸が2つ → 平面
  • 3次元は軸が3つ → 空間

 というのは比較的理解しやすいと思いますが、じゃあその次に来る4次元とは何なのか? というのは非常に想像しづらいと思います。まず言っておかなければならないのは、

「4次元空間 = 3次元空間 + 時間」ではない

 ということです。確かに時間を加えると新たな情報の軸ができますが、それは空間と等価ではありません。あくまで擬似的な解釈です。更に5次元までいくと「5次元空間 = 3次元空間 + 時間 + 並行世界だ」という意見も見かけますが、それも間違い、というか不完全な解釈です。

 2次元の場合に落として考えるとわかりやすいと思いますが、1m*1mの正方形が1秒間存在したら「2次元空間+時間」という意味では3次元ですが、これは「立方体」と言えるでしょうか。言えないです。そもそも1m = 1sではないですし、3次元空間ならばできるはずの回転といった動作が定義できません。同様に、立法体が1秒間存在したとしても、それをもって3次元生命体である我々が「4次元立方体(八胞体、Tesseract)を見た!」とは言えません。相対性理論まで考えれば光速×時間は空間と等価になりミンコフスキー空間内での回転を考えることができますが、そういうのはおいといて)

 5次元空間はあくまで5次元の空間です。我々が普段、「空間」として3つの軸が5つに増えただけです。ただ、我々がそれを観ることはどうしても不可能です。

感じることは出来ないが、考えることはできる

 我々がありのままの多次元立方体を観るのは不可能です。あきらめましょう。

 ……というのでは悲しいので、なんとかして観る方法を考えます。

 いきなり5次元だとハードルが高いので、4次元立方体から考えます。

f:id:hibit_at:20180914191816p:plain ↑こんなやつ

 ここでも次元を落として考えましょう。3次元の物体の形状をどうにかして相手に伝えたい時に、紙に描きます。3次元立方体を描くとしたら、次のような図を描くのではないでしょうか。(そして今わたしも2次元のディスプレイに写しています)

f:id:hibit_at:20180912232659p:plain

 ここで我々は無意識に「投影(projection)」という行為を行っています。太陽の影が人間の体(3次元)を地面に影(2次元)として写すように、元の情報を「押しつぶして」次元を1つ下げているのです。では、どのように押しつぶすのか? 人間が立方体を紙に描くときは、上の図のように「いい感じの」角度で描きますが、これだと2次元人に立方体を説明するのは困難だと思います。多分、

「なんだこの歪んだ形は? これが正方形なんて信じられないよ」

 と言われると思います。これが歪んでないと感じるのは、あなたが3次元人だからです。愚かな2次元人に説明しやすくするために、もう少し「真っ直ぐ」な位置に太陽を設定するとどうでしょう。

f:id:hibit_at:20180914192434p:plain

 立方体の真上に太陽があるとします。ABCDの点は、A'B'C'D'の位置に影が落ちることがわかると思います。これを太陽の視点から見下ろすと

f:id:hibit_at:20180914193206p:plain

 こうなります。愚かな2次元人には、上の図が描かれた紙を見せながらこう説明するとしましょう。

「どうだい? A'B'C'D'は正方形、EFGHも正方形であることはわかるだろう? 本当はその周りにある4つの四角形も正方形だけど、紙に書くにはこうするしかなかったんだ。全ての辺が同じ長さで、全ての辺が直角に交わっていると言っても信じられないかな。え? 正方形の中に正方形があるじゃないかって? 説明しづらいな……まあ君ら2次元人には理解できないか」

それでは次元を1つ上げてみよう

 今度は愚かになるのは我々人間さんサイドになります。今度は4次元の図を3次元の図に投影します。とは言っても、4次元での描画は当然不可能なのでなにか方法を考えます。そこで、元々の3次元空間を圧縮して「平面」と考えると、次のような形で先程とまったく同じ投影を考えることができます。

f:id:hibit_at:20180914194948p:plain

 こうして3次元世界に投影された4次元立方体が以下の図になります。

f:id:hibit_at:20180914191816p:plain

 内側にある立方体が、上図で赤で描いた「平面」です。太陽から遠いため、その分「影」が小さいです。外側にある立方体が、上図で青で描いた「平面」です。太陽に近いため、その分「影」が大きいです。

 数式で書くとこんな感じです。(※ 4次元目をwとする)

x' = \frac{x}{2-w}
y' = \frac{y}{2-w}
z' = \frac{z}{2-w}

 四次元人(誰?)は上図の形をした立体を見せながらこう説明するでしょう。

「どうだい? 内側にあるのも立方体、外側にあるのも立方体であることはわかるだろう? 本当はその外側にある6つの立体も立方体だけど、この世界に持ってくるにはこうするしかなかったんだ。全ての辺が同じ長さで、全ての辺が直角に交わっていると言っても信じられないかな。え? 立方体の中に立方体があるじゃないかって? 説明しづらいな……まあ君ら3次元人には理解できないか」

更に次元を1つ上げるぞ

 話はこれに留まりません。我々の目的は5次元なのですから。

 今度は上の方法(ステレオ投影)は使えません。ステレオ投影を2回使ってもほとんど見た目が変わらないので意味がないからです。そこで今度は斜投影という方法を使います。と言っても、これはステレオ投影より簡単です。

f:id:hibit_at:20180914201722p:plain

 上の図もまた立方体ですが、左下の正方形が手前、右上の正方形が奥にあること、そしてナナメの成分が奥行きを表していることはすぐに分かると思います。これは「奥行きの分だけタテとヨコを足す」ことによって、立体を平面に表現しています。数式で書くとこんな感じです。

x' = x+\frac{z}{2}
y' = y+\frac{z}{2}

 ここで、

  • ステレオ投影
  • 斜投影

 という2つの方法で次元を2つ下げる方法がわかったので、これを組み合わせて

x' = \frac{x}{2-w}+\frac{v}{2}
y' = \frac{y}{2-w}+\frac{v}{2}
z' = \frac{z}{2-w}+\frac{v}{2}

 という変換により、5次元を3次元に圧縮することができます(※4,5次元目をw,vとする)。その結果できたのがこちら。

f:id:hibit_at:20180914201944p:plain

 今までの説明を踏まえると、

  • 赤色が斜投影上「手前」にある四次元立方体
  • 緑色が斜投影上「奥」にある四次元立方体

 であることが分かると思います。そして赤の「立方体」と緑の「立方体」を青い辺でつないだものもまた四次元立方体です。もちろん、全ての辺が同じ長さで、全ての辺は直角に交わっています。想像できるでしょうか?

 これらを「回転」させと(5次元あるので、_5C_2=10通りあります)以下のようになります。

 

 あなたは5次元立方体を理解できたでしょうか?

Blender触ったことないけど販売モデルを巨乳に改変したいという人へ

Blenderのバージョンはv2.79です

プロローグ

(遠慮がちに扉を開ける音)

―――おや、見ない顔だな。どうしてこんな辺鄙なところまで。

 なるほど、最近VRCを始めて、トラストも解除されて、アバターも買ったが、そのままだと味気ないから改変したい、と。ならgimpをDLしてテクスチャの色でも変えたらどうだ。何、それだけじゃ嫌だ? メッシュにも手を加えたい? おいおい、勘弁しろよ。ニ面図はおろか、イメージイラストも持たずに何を言ってやがる。まったく、オレはエスパーじゃ…

 ……! そういうことか。わかったぞ、お前さんのやりたいこと。

 アバターを巨乳に改変することでしか救われない魂がある。お前さんも”そう”だろ。目を見れば理解る。いいぜ、付き合ってやるぜ。

ボーンを拡大する

 こいつが一番手っ取り早い。胸ボーンが設定されていることが条件となるが、販売されているアバターならまあ大丈夫と考えて良いだろう。手順は簡単。Unityのボーンヒエラルキーにある胸ボーンを選んで

f:id:hibit_at:20180913193239p:plain

 インスペクタにあるTransformからScaleを変えて、

f:id:hibit_at:20180913193346p:plain

 これでOK。簡単だろう?

 ……納得してないって顔してるな。まあ無理もない。これはただボーンに対応している頂点を一律に拡大しているだけだからな。モデラーが想定しているサイズでの形をそのまま機械的に拡大すれば、拡大率が上げれば上がるほど不自然になっていくのは当然だ。ダイナミックボーンで揺らしても不自然になることが多いしな。

 これで満足できなけりゃ、いよいよBlenderの出番だ。その覚悟がお前さんにあるのかい……と言いたいところだが、その様子じゃ確認の必要はなさそうだな。

プロポーショナル編集

 いいか、お前さんが使う武器は1つだけだ。プロポーショナル編集、それがそいつの名前さ。だが、Blenderを触ったこともないお前さんのために、それに至るまでの道のりをイチから説明してやろうじゃねえか。まずBlenderを起動しろ。

f:id:hibit_at:20180913193818p:plain

 無粋なキューブはXキー(またはdelキー)で削除だ。

f:id:hibit_at:20180913193944p:plain

 改変したいモデルを「ファイル」→「インポート」→「FBX」。

f:id:hibit_at:20180913194323p:plain

 かわいそうだが脱いでもらおうか。とは言っても非表示にするだけだ。上図のマークをクリックで余計なオブジェクトを非表示。

f:id:hibit_at:20180913195043p:plain

 さすがに脱がせたあとの姿をソリッド表示する訳にはいかねえ。こんな場末でも一応パブリックなスペースだからな。こっから先はワイヤーフレーム表示+適宜隠蔽でいかせてもらうぜ(販売アバターワイヤーフレームを全部出すのも望ましくないしな)。上図のマークをクリックして「ワイヤーフレーム」だ。(Zキーでも切り替えられる。こっちの方が圧倒的に速いな)

f:id:hibit_at:20180913195546p:plain

 次は「オブジェクトモード」を「編集モード」に。ショートカットキーはTabキー。Blenderで最も使うショートカットキーのひとつだろうな。

f:id:hibit_at:20180913195742p:plain

 そしたらここのチェックもつけておけ。左右対称に編集するモードだ。アシンメトリーなソレが趣味なら敢えて勧めはしないが……普通は左右対称だろうな、お前さんが作りたいソレは。

f:id:hibit_at:20180913200010p:plain

 選択モードは「頂点」に。ショートカットキーのCtrl + Tabキーでも切り替えられる。これも良く使うから覚えておいた方がいいだろう。

f:id:hibit_at:20180913200237p:plain

 下準備もそろそろ終わりだ。5キーを押してから、1,3,7キーで視点を切り替えられる。モデルの向こう側にタテヨコのグリッドが見えたらOKだ。そうじゃなければもう一回5キーを押せ。視点は基本的にこの3種類で大丈夫だ。と言うか、この3種類しか使うなとさえ言っていい。変にナナメの視点で操作をするとバランスが崩れる。

f:id:hibit_at:20180913200449p:plain

 ようやくここでプロポーショナル編集の出番だ。上図のマークをクリックして「有効化」にしろ。…っと、ひとつ大事なことを伝え忘れていた。

 Blenderのデフォルトでは選択が「右クリック」だ。まったく、なんでこんな意味不明な独特なUIにしたんだろうな。それで構わねえならそれでもいいが、変えたいなら「ファイル」→「ユーザー設定」の後に「入力」→「左」だな。

f:id:hibit_at:20180916011132p:plain

f:id:hibit_at:20180916011209p:plain

 さて、気を取り直して好きな頂点を選んでからGキーで移動して、マウスのスクロールをグリグリすると……

f:id:hibit_at:20180913201442g:plain

 マーベラス! ここまで来たらお前さんは、自分が”造る”力のカケラを手に入れたと実感しているはずだ。ゴールはすぐそこだ。操作をミスった時はCtrl + Z、戻した操作をやっぱりやり直したい時はCtrl + Shift + Zだ。アンドゥ履歴は選択箇所も含めて記録されるから、お前の操作は必ず無駄にならない。焦る必要はない。幸運を祈ってるぜ。

エピローグ

―――おや、いらっしゃい。

 ああ、私先週からここのマスターを任されました者です。お客さん、いいアバターですねえ。デカいし、その上破綻がない。揺れ方から察するし、返しボーンを入れておられますね。丁寧にウェイトを塗られたこともわかります。こだわりを感じますよ。それでご注文は……え、ああ、あの人ですか。

 言いづらいんですけど……あの人ね、BANされたんですよ。

 使っているアバターが露骨すぎてガイドラインに抵触しちゃいましてね。命あっての物種じゃないですけど、アカウントあってのVRCですから。お客さんもその、やり過ぎには気をつけてくださいね。ああ、すいません、本当は初対面のお客さんに言うことじゃないんだけど、お客さんはなんだか初めてって感じがしなくて……なんだか、あの人に似てるんですよ。なんでかな、お客さんは落ち着いた方だし、あの人とはむしろ正反対な感じなのに。でも何か、魂って言うのかな、それが似てるんですよ。

 ほら、アバターを巨乳に改変することでしか救われない人っているじゃないですか。あなたも”そう”でしょう。モデルを見ればわかりますよ。


・Live streaming, advertising or publicly sharing content that is sexually explicit in nature or simulates sex acts is not permitted. Doing so may result in moderation action being taken against your account up to (but not limited to) banning of the offending user account depending on the severity of the act in question.
・Pornography & nudity is not allowed.

VRChat Community Guideline

(以下:筆者翻訳)
・明白に性的である、または性的な行動を模したコンテンツをライブストリーミング、宣伝または公共にシェアすることは許されません。それらをすることは、あなたのアカウントに対するモデレーションとして(ここに書かれているような行動の酷さによっては)不快なアカウントにバン(それに限りませんが)という結果をもたらしかねません。
・ポルノと裸は許されません。

めんどくさいダイナミックボーンを効率的に入れる方法

※ダイナミックボーンは有料のアセットです。Unity Asset Storeにて$20(価格は変動することがあります)で購入できます。

 髪や服などの揺れものを表現したい時に、ダイナミックボーンは強力な武器となります。しかし、ボーンが増えてくるとそれにいちいち対応させるのは面倒な作業になってきます。そういった時に、ダイナミックボーンの性質について以下の3点を知っていると効率的に作業できます。

1 子ボーンのすべてに影響が及ぶ

 アバターのボーンヒエラルキー(bone hierarchy)は


hips(尻) → upperleg(太もも)→ 足の指先まで

spine(脊椎)

chest(腰) → shoulder(肩) → 腕の指先まで

neck(首)

head(頭)

髪にボーンが入っていれば以降も続く


 という構造になっています。そして、上流のボーンにダイナミックボーンを適用すれば下流のボーンにもすべて適用されるという性質があります。例えばspineにダイナミックボーンを入れた場合、上半身全体にダイナミックボーンが適用され、

f:id:hibit_at:20180911201514g:plain

 ゴム人間か!

 となります。  なんだか、

f:id:hibit_at:20180911200937p:plain

(from Wikipeida(CC BY-SA 3.0))

 生物の系統樹における単系統の話を思い出すのは私だけでしょうか。

 これを利用すれば、髪のボーンが20個ちかくあるシャーロちゃんのような子でも、headにダイナミックボーンを入れるだけでいいということがわかります。

f:id:hibit_at:20180911202309p:plain

 特にrootの指定やコライダーの設定が絡んでくると時短効果が高いです。ただこれはデメリットにもなって、全て同じパラメータが設定されてしまいます。実用上それで困ることはあまりないと思いますが、髪のボーン1個1個に異なるパラメータやコライダーを設定したい! というこだわりを持つ方は、やはり丁寧にダイナミックボーンを適用するしかなさそうです。

 ここで「headにダイナミックボーンを入れたら、髪だけじゃなく顔自身も揺れてしまうんじゃないの?」と思った方は鋭い。なぜかheadは固定されています。Blenderのポーズモードだと普通に回転するので、Unity上の制御のようです。恥ずかしながら理由は不明……。もちろんneckにダイナミックボーンを入れたら顔がぐわんぐわん揺れてホラーな画になりますよ。

2 適用除外(exclusion)を指定できる。

f:id:hibit_at:20180911204032p:plain

 ダイナミックボーンには適用除外(exclusion)を指定できます。これを使えば、


あるボーン

(この間のボーンはすべてダイナミックボーンが適用される)

あるボーン

(ここから先は適用されない)


 という制御が可能になります。例えばシャーロちゃんは、hipsの直下に20個近いスカートのボーンがあります。hipsにダイナミックボーンを入れればこれらのボーンすべてを揺らすことができますが、巻き添えで全身が揺れてしまいます。そこで、spineとupperleg(右と左の両方)にexclusionを指定すれば、揺れの巻き添えを「止め」ることができます。

3 どこのボーン(というかオブジェクト全般)に入れてもいい

 これは私も実験していて衝撃だったのですが、別に髪を揺らしたいから髪にダイナミックボーンを入れる必要はありません。ダイナミックボーンが適用されるかは「root」に何を指定されるかだけで決まり、全然関係ないキューブオブジェクトにコンポーネントを入れても、そのrootにあるボーンを指定すればそのボーン(及び下流のボーン)は揺れます。ひとつひとつの髪にすべてコンポーネントを入れていたあの苦労はなんだったのか……。

 まあ、わかりやすさもかねてhipsに入れるのがいいと思います。

(2018/09/13追記。無関係なゲームオブジェクトにいれると揺れ方が変になることがあるようです)

スマートなダイナミックボーンの入れ方の例

 今までの話をまとめると、

f:id:hibit_at:20180911205014p:plain

 これだけの設定で、

f:id:hibit_at:20180911205234g:plain

 この揺れが再現できるということですね。

 余談ですが、ボーンのヒエラルキーが頭やつま先からでなく、尻から始まるのはなにか変な感じがするでしょうか。しかし、すべての動物の受精卵の分化は肛門(または総排出腔)から始まることを考えると、ボーンヒエラルキーがhipsから始まっていることは理にかなっていると言えなくもないかもしれない可能性を否定できない。

..It is not birth, marriage or death, but gastrulation which is truly the most important time in your life.

Lewis Wolpert, 1986

…人生において真に最も重要な時は、誕生でも結婚でも死でもない。それは原腸形成である。

ルイス・ウォルパート 1986

 皆様もダイナミックボーンの性質を良く理解して、良き揺れものライフを。

クロースコンポーネントが爆発する/縮む時の対処法

クロースコンポーネント爆発事件

 アバター制作において、時にボーンだけでは表現が難しい場合があります。服がたるむ様子などがその代表的な例でしょう。そのような時にUnityのクロースコンポーネントは強力な武器になります。

f:id:hibit_at:20180910205656p:plain

 使い方も簡単です。このようにピン止め部分を指定して、コライダーを別途指定して…

f:id:hibit_at:20180910204228g:plain

 爆発しとるやないか!

 なぜこのようなことが起こってしまったのでしょうか。

解決策

f:id:hibit_at:20180910205800p:plain

 結論から言うと、Blender(Maya使ったことないですけど、多分Mayaでも出来るでしょう)で「回転と拡縮の適用」をすれば直ります。ある程度実験した結果、どうやらボーンヒエラルキーの中にオブジェクトが位置付けられると、強制的に位置やスケールが指定されてしまうようです。普段は「元の拡大率」が表に出ることはないのですが、なぜかクロースコンポーネントを適用した時だけ元の拡大率に戻ろうとするムーブをしてしまうみたいです。私は経験がないですが、恐らく同様の理由で「縮む」時もこの対策が有効かと思われます。

f:id:hibit_at:20180910210409g:plain

 和解した! 俺はクロースと和解したぞ!

補足

 Blenderで編集を加えた時はUnity上ではなく、エクスプローラ上でファイルを置き換えると、Unity上でやった操作を残したままfbxファイルだけ置き換えることができます。初心者の頃はいちいちPrefabを消して一から作り直してました……。

f:id:hibit_at:20180910210512p:plain

 皆様も良きUnityライフを。