エフアンダーバー

個人開発の記録

ユニティちゃんをRe-パッケージング!!

味気ないサンプルに華を添えてくれる存在として当ブログでもお世話になっているユニティちゃん。 非常にありがたい存在ではあるのですが、いざパッケージをインポートしてみるといろいろと問題が多いことに気が付きます。 そこで、Unity初心者でも簡単に扱えるようにユニティちゃんを再パッケージしてみました。

ユニティちゃん

f:id:fspace:20170318174913p:plain

ユニティちゃんとは?

ユニティちゃんはUnity Technologies Japanが提供するキャラクターで、 『ユニティちゃんライセンス』という非常に緩いライセンスのもと、 3Dモデルやドット絵、ボイスなどのアセットが配布されています。

今回、再パッケージしたのは最もシンプルでよく使われている次の二つのパッケージです。

また、次のパッケージをインポートする必要がなくなります。

公式サイト:UNITY-CHAN! OFFICIAL WEBSITE

ユニティちゃんの問題点

現状、ユニティちゃんのパッケージには次のような問題があります。

  • 複数に分割されている
  • 大量に発生する警告メッセージ
  • 長いインポート時間
  • 難解かつコメントの少ないスクリプト
  • 複雑なフォルダ構造

長いインポートを待ちつつ、パッケージを順番に読み込んだ後に、大量の警告メッセージが残されているという状況には、 さすがにため息が出るので、この辺りを解消することが今回の目的です。

成果物

ダウンロード

Unity Package

GitHubより最新バージョンのパッケージをダウンロードしてください。

パッケージ名 内容 説明
UnityChan 基本アセット 3Dモデルやシェーダ、スクリプトなどのボイス以外のあらゆるアセット
UnityChan_Voices ボイス ボイスのみの追加アセット

プロジェクト

GitHubにて公開中。

github.com

ライセンス

オリジナルのパッケージに含まれるアセットやその改変物はユニティちゃんライセンスを継承する必要があるので、 ユニティちゃんライセンスが適用されます。 気を付けるべきはロゴ・ライセンス表記と営利目的の成人向けコンテンツくらいだと思います。

私が追加したものに関してはCC0にしておきます。 これは可能な限り著作権を放棄するというものです。 MITライセンスとかにすると著作権表記が必要になってしまって面倒なので。

正直どこまでがユニティちゃんライセンスの適用範囲で、どこまでが自分の著作物と言っていいのかよくわからないのですが、 私は使用に関して一切制限するつもりはないので、ユニティちゃんライセンスにだけ気を付けてお使いください。

使い方

基本アセットのUnity Packageをダウンロードし、 メニューの"Assets" > "Import Package" > "Custom Package..."からパッケージを選択してインポートします。 ボイスを利用したい場合にはボイスのUnity Packageをダウンロードして、同様の手順でインポートします。

ユニティちゃんを自分の作成したシーン上で動かしたい場合には、 "UnityChan"プレハブまたは"UnityChanDynamic"プレハブをシーンのヒエラルキービューにドラッグアンドドロップします。 "UnityChanDynamic"プレハブでは処理負荷が少し高くなりますが、髪の毛やスカート等が物理演算によって揺れます。

ユニティちゃんのモーションやポーズ、スクリプトの動作などを確認したい場合には、 "Demo"フォルダ内の各シーンを読み込むとサンプルを確認できます。

セットアップされていない生のデータを触りたい方は"Data"フォルダ内に各種データが配置してあります。 スクリプトの動作に関するドキュメントは用意していないため、詳細を確認したい場合には、 このフォルダ内のスクリプトファイルを開いて、コードやコメントを参照してください。

また使用に際して、"License"フォルダ内の各種規約をご一読ください。 "ReadMe"ファイルは一応元パッケージのものを含めていますが、内容が古くなっている部分があります。

DynamicsXXX

揺れもの関連のDynamicsXXX系のスクリプトについて、仕様がわかりづらいので簡単に説明しておきます。

元パッケージに含まれていたSpringXXX系のスクリプトは、スクリプト内の計算で簡易的に物理っぽい挙動を再現するものでした。 一方、本パッケージに含まれるDynamicsXXX系のスクリプトはUnity標準の物理エンジンを利用して物理演算をしています。 しかし、そのためにDynamicsXXX系のスクリプトは少し特殊な仕様となっています。

レイヤー設定

Unityには特定の相手と「だけ」衝突させるような機能は存在しません。 好ましくない衝突を回避するためには、レイヤーを用いて衝突相手をフィルタリングする必要があります。 このためDynamicsManagerには揺れものと専用コライダーのレイヤーを一括で設定する機能がついています。

しかし、このような設定をしなければ動かせないという仕様ではサンプルを用意できません。 また、レイヤーおよびその衝突関係の設定はプロジェクトごとの設定項目であるため、 これらの項目を勝手に書き換えるような仕様にするのも好ましくありません。

そこで、DynamicsManagerには実行時に使われていないレイヤーを自動的に検索してそれを利用する機能をつけています。 このとき、「使われていない」ということの判断には名前が設定されているかどうかを利用しており、 全てのレイヤーに名前が設定されているとエラーとなります。

ただし、この機能はサンプルを動かすための対処的なものです。 もしゲームに組み込むことを考えているのであれば、レイヤーと衝突関係を正しく設定した後にこの機能を切ることをおすすめします。

物理オブジェクトの実体

UnityにはKinematicでない剛体(Rigidbody)で階層をつくってはいけないという制限があります。 一方で、モデルのボーンは階層を成しています。 このため、各ボーンにそのまま剛体をアタッチしてしまうと制限に違反しておかしな挙動となってしまいます。

そこで、DynamicsXXX系のスクリプトでは物理演算用のゲームオブジェクトをシーンのルートに生成し、 それに剛体をアタッチすることで物理演算を行っています。 モデルのボーンにはそれらの演算結果を転写しているだけなので、 ボーンのTransformになんらかの変更を与えてもそれらは全て無視されます。

物理演算用のゲームオブジェクトは通常見えないように設定されていますが、 DynamicsManagerの設定を変更すると、エディタ上で確認できます。

リパッケージングについて

方針

再パッケージの方針というか、目指したところ。

  • パッケージは基本アセットとボイスの二つで構成
    • インポートが遅くなる最も大きな要因がボイスの容量であるため
  • 初心者でも簡単に扱えるように
    • ドラッグアンドドロップのみで使用可能に
    • どれが本体でどれが部品なのかを明確に
  • 初心者の手本となるようなソースコード
    • なるべくきれいに整理
    • コメントを多めにつける
    • 極力基本構文のみ
    • 汎用性やパフォーマンスよりも可読性優先

スクリプト

スクリプトは元々のパッケージに含まれているものと同等の機能を持つ新しいスクリプトへとすべて書き直しました (一応元コードを参考にして書きましたがほとんど原形はないです)。

スクリプトを書き直すにあたって、 初心者でも頑張れば読めるくらいのコードにしようと考えたのですが、 Unityの入門書にどの程度C#の構文について書いてあるのかわからなかったため、ほとんど基本構文のみで書いています。

プロパティ、インターフェース、Unity定義クラス以外の継承、デリゲート、LINQあたりは意図的に避けています。 そのためC#に慣れ親しんだ人にはちょっと不格好なコードに見えるかもしれません。

一方で、条件演算子(~?~:~)、列挙型(enum)、構造体(struct)あたりはコードを読みやすくするために、 属性(~Attribute)、ifディレクティブ(#if/#endif)あたりはエディタの利便性のために許容しています。 読んでいて意味がわからなかった場合には各自調べてください。

・・・とまあ、こだわっている風ではありますが、 実際には一部のスクリプトはそこそこ難しく、おそらく初心者には読めないだろうなと思います。 制約を貫いているのは単に意地になっているだけですね。 とりあえず、C#っぽくないコードになってるのはこういう理由だよ、ということだけ。

対応表

各スクリプトの対応と相違点。

元スクリプト 新スクリプト 相違点
AutoBlink AutoBlink
BlinkablePart
対象の指定をスクリプトをアタッチする方式に。
CameraControl ViewingModeCamera
FaceUpdate FacialAnimator レイヤー指定が必要に。
IdleChanger MotionSwitcher 操作方法を上下から左右に。
IKCtrlRightHand IKTarget 右手以外にも切り替え可能に。
RandomWind RandomWind
SpringBone DynamicsRoot
DynamicsBone
スクリプトのアタッチ対象が末端に向けてひとつスライド、根本に専用スクリプトが必要に。
SpringCollider DynamicsCollider 形状が球からカプセルに。
SpringManager DynamicsManager スクリプト内での計算から標準の物理エンジンを使用する方式に。
ThirdPersonCamera ThirdPersonCamera 位置の指定がTransformの参照から相対座標値に。
UnityChanControl-
ScriptWithRigidBody
UnityChanController
UnityChanStateController
StateMachineBehaviourを利用する方式に。その他全体的に変更。

変更点一覧

とりあえずメモしておいたものだけ。 何か思い出したら追記します。

  • 各モデルのノードを適切な名前に変更
  • 各モデルのアニメーションスタックを適切な名前に変更
  • 各モデルのブレンドシェイプを適切な名前に変更
  • "unitychan_all"アバターマスクを作成し、各アニメーションのマスク設定に適用
  • 各アニメーションモデルのRigに"unitychan.fbx"のアバターを適用
  • "BoxUnityChan.fbx"のRigに"unitychan.fbx"のアバターを適用
  • "Character1_Spine"に設定されていたアニメーションを削除
  • "JUMP00"アニメーションのカーブ"JumpHeight"と"GravityControl"を削除
  • "UnityChanActionCheck/ARPose"アニメーターコントローラーのパラメータ"Back"と"Next"をBoolからTriggerへ変更
  • "UnityChanLocomotions"アニメーターコントローラーの構造を変更
  • "UnityChanLocomotions"アニメーターコントローラーのジャンプモーションを"JUMP00"から"JUMP00B"へ変更
  • "unitychan_dynamic"の"J_L_SusoFront_01"のTransformがリセットされている問題を修正
  • ステージのマテリアルをシンプルなものに変更
  • 古いシェーダーが適用されていた"BoxUnityChan.fbx"のマテリアルを再インポート
  • 重複していたマテリアルを削除
  • "CreateLocatorHere"エディタ拡張を削除
  • 各プレハブから"LookPos"を削除
  • 不要になったプレハブを削除
  • スプラッシュスクリーン用のアセット群を削除
  • 内容が正しくなくなった一部のドキュメントを削除
  • ライセンス関係のファイルを最新のものに更新
  • すべてのテキストファイルを改行コードLFのBOM付UTF-8に統一
  • 全スクリプトを書き直し
  • 一部アセットの名前を変更

ユニティちゃんライセンス

ユニティちゃんライセンス

この作品はユニティちゃんライセンス条項の元に提供されています

おわりに

元々少し整理するだけだったはずなのですが、いつの間にやら大改修に・・・。 おかげでブログの更新も滞って、ネタがたまってきたのでこれから少しずつ放出していくつもりです。

ブログ更新の通知用にTwitter始めようと思います。 SNS使いこなせない人間なので、以前アカウントだけ作って挫折したのですが、今なら最悪ブログの更新だけでもつぶやけるので。 アカウントについてはプロフィールの部分に書いておきます。

パッケージに関して質問やバグ報告等あればいつでもどうぞ。



執筆時のUnityのバージョン:5.5.2f1