今回はblenderで作成した服をUnityに取り込んで使用し、ゲーム中にキャラクターの服の着せ替えを出来るようにしたいと思います。
キャラクターの服や鎧、防具を作成するには
の記事で使ったblenderのアドオンMakeClothesを使って作成すると比較的作りやすいです。
本格的な3DCGの作成については専門の書籍やサイトを見てください。
今回の着せ替え機能を搭載すると
↑のような感じになります。
木の色の服はCloth機能を取り付けているので指定したコライダと衝突がされています。
Cloth機能の詳細は今回の記事ではやらないので、別途Clothの記事を参照してみてください。
blenderで服を出力
Blenderで服を作成しそれをUnityに取り込む時の設定等について見ていきます。
既にUnityに問題なく服のモデルを取り込みテクスチャの設定がされている場合は必要ないので『取り込んだ服のモデルをキャラクターに着せる』の項目まで飛ばしてください。
blenderで服を出力していきます。
blenderで服だけを選択し、UVWrapを表示します。
UVWrapの表示方法等は先ほどのMakeClothesを使った服の作り方の記事の中で触れているので参照してください。
すでにテクスチャを服に設定しているので、
UVWrapの画面の中を右クリックしてアクティブにし、Aキーを押して展開されたMeshを全選択します。
Sキーを押すとサイズの変更が出来るのでマウスを動かしてサイズを調整し、服に設定したテクスチャが好みになるように調整します。
調整が終了したら右クリックを押して確定します。
ここで調整したUVWrapはUnityでも有効となるので自分の好みの服のデザインとなるよう調整してください。
わたくしは↑のようにハートのテクスチャを服に貼り付け、サイズを調整しました。
UVWrapのサイズを調整すればハートをもっと増やしたりする事も出来ます。
Unityで服を着せ替えする場合、キャラクターのボーンの動く部分と服の部位を別に作った方がうまくいきます。
例えば胴周りはEthanで言うと胸のボーンの部分だけ、肩の部分は腕のボーン、足のすねの部分は足のボーン等です。
全身一片に作る場合はCloth機能を使ったとしてもなかなか難しそうです・・・・(^_^;)
Unityで使うサイズに合わせてblender側で出力設定をする
これで設定が終了したので、服をFBX形式で出力しましょう。
まずは服のサイズを調整する為にメートル表示に切り替えます。
Objectモードで位置や角度、Scaleを調整して服のサイズを普通の人間が着れるサイズにします。
↑のように位置、角度、Scaleが変更されています。
以下がサイズ調整した服です。
Objectモードで変更した位置や角度、Scaleは変更したままとなっているので、Ctrl+Aキーを押して、現在の位置、角度、Scaleをデフォルトの値にします。
Tキーを押して出てくるツールシェルフで全てにチェックを入れます。
↑のように変更した後の値がデフォルト値となります。
これで設定が出来たので、服を出力します。
服をEditモードで全選択、またはObjectモードで全選択した状態で↑のようにSelected Objectにチェックを入れます。
ここにチェックを入れると選択されているオブジェクトのみ出力されるようになります。
なのでMakeClothesで人のモデルと服を作成していた時に服だけ出力したい場合は服だけを選択しSelected Objectにチェックを入れます。
Scaleの右側のボタンを押して解除状態にします。
Forwardはそのまま-Z Forwardにしておきます。
!EXPERIMENTAL! Apply Transformにチェックを入れておきます。
Export FBXボタンを押すと服のFBXファイルが出力されます。
実際にUnityに服を取りこむと服のモデルはX、Y、ZのScaleが1となり、シーンに配置するとそのままScaleが1となっています。
MakeClothesで出力した服のMeshは元のサイズがかなり大きいのでFBX形式での出力、Unityでの取り込み時のサイズ調整がややこしいですね・・・(^_^;)
上の画像ではRotationのXが270となっていますが、さきほどの出力設定をしておくと0となっているはずです。
Unity側でサイズ調整をする
Unityで取りこんだ後にサイズを合わせます。
↑のように服のモデルを選択しインスペクタのModelのScale Factorを使ってサイズを調整します。
ここで調整した値はApplyを押すまで反映されませんので気を付けてください。
今回取りこんだ服のモデルはblender上でも10倍の大きさとなっていたのでScale Factorに0.1を設定しUnity側のサイズに合うようにします。
服のテクスチャを取り込みマテリアルに設定する
Material NamingをModel Name + Model’s Materialにし、服のモデルの名前のマテリアルを同時に作成します。
Applyを押すと服のモデルと同じ名前のMaterialが作成されるので、そこにテクスチャを取りこんで設定をします。
今回のわたくしのサンプルでは服のモデルをtShirt2とtShirt3という名前で取りこみます(2つあるのは服を着せかえる為です)。
その為tShirt2-TShirtとtShirt3-TShirtというマテリアルがMaterialsフォルダに作成されます。
テクスチャは取りこまれてないのでUnityでテクスチャを取りこんでマテリアルに設定します。
テクスチャを取り込みたいフォルダ上で右クリックしてImport New Asset..を選択しテクスチャファイルを選択します。
テクスチャを取り込んだらtShirt2-TShirtとtShirt3-TShirtマテリアルのAlbedoに取りこんだテクスチャファイルを設定してください。
↑のようにMaterialにテクスチャが設定されました。
これで服の取りこみが終わりました。
取り込んだ服のモデルをキャラクターに着せる
次はtShirt3かtShirt4モデルをシーン上にドラッグ&ドロップしてみましょう。
服のサイズが人のモデルと同じような大きさになっているはずです(人のモデルサイズにもよりますが・・・)。
本当は服を設置した時にRotationのX、Y、Zが0の時に服が立っている状態にしたかったのですが、うまく調整出来なかったのでUnity側で調整するようにします。
(Unityに取り込んだ時にRotationが変更されないように、Blenderでの出力設定を変更しました。なので服を立たせた状態ではRotationの値が0とはなっていません。2017/08/25)
シーン上に人型のモデルを配置し、Animatorやキャラクターを動かすスクリプトの設定をしておきます。
すでにTシャツを着ているのでこの上に着る服を着せかえることになりますね。
服をキャラクターに合うように位置とサイズを調整する
シーンに配置した服をその人型モデルの上半身に服が合うように調整します。
↑のように人型モデルに服のサイズや位置を合わせます。
サイズ調整をする時はインスペクタのTransformを調整するよりも↑のようにUnityのメニューバーの下のモードを選択し、
Sceneタブでそれぞれの方向へドラッグ&ドロップしてサイズを調整するとわかりやすいです。
調整が終了したら服を人型モデルのボーン以下にドラッグ&ドロップして移動させ、キャラクターの動きに合わせて服が動くようにします。
今回はMakeHumanで作成したモデルのボーンspine3以下にtShirt3を配置しました。
↑のように人の動きに合わせて服も動きました。
服の着せ替えで重要なポイント
ここで気をつけないといけないポイントがあります。
今回の場合はspine3以下に服を配置しているので、spine3のボーンに合わせて服が動きます。
なのでspine3とは関係ないボーンの動きに服は合わせて動かないという点です。
サンプル動画を見ているとわかると思いますが、服が人型モデルの動きによっては透けて見えてしまっています。
これは人型モデルの足等のボーンの動きで服のモデルの上側に表示されているからです。
なのでボーンに合わせた範囲で服を作成する必要があります。
また、体全体を覆う服、例えばドレス等をキャラクターに着せる場合spine3の子要素にドレスを配置するとspine3のボーンの動きでドレスも動くので、
下半身の動きとは連動出来ません。
着せ替えをしないというのであればあらかじめblenderやMakeHuman等でドレスをキャラクターに着せた状態の3Dキャラクターを作成した方がいいのかもしれません。
体の部位毎に着せかえるのであればボーンに合わせてそれぞれの防具等を作成していき、それぞれのボーンの子要素に防具を配置していきます。
他のやり方としてはあらかじめ服を着せたキャラクターをいくつか用意しておきキャラクター毎取り変えて着せ替えとする方法もありますが、
多くの服を着せかえる場合は現実的ではないかもしれません。
この記事を書いた時点では知らなかったんですが、Cloth機能を使うと着せ変えた服をリアルタイムに形状を変化させる事が出来ます。
Cloth機能に関しては
を、Cloth機能を髪、鎧、マントに設定した記事は、
を参照してみてください、結構感動ものの機能ですね(^_^)v
すね用の防具を作成する
上着を作成したついでにすねを保護する防具を作成しておきます。
blenderですね用防具を作成し出力する
MakeClothesのSkirt部分を使い防具を作成します。
さきほどのTシャツと同じようにSkirtのいらない部分を削除して、すね用の防具を作成します。
削除しただけでは内側部分がまっすぐなので内側のメッシュをすべて選択した状態でRキーを押しキャラクター側に少し回転させておきます。
法線(メッシュが向いている方向)は他のメッシュと逆にならないように気を付けて回転させてください(テクスチャを張り付けた時におかしくなる)。
張り付けるテクスチャの設定をしたらすね用ガードの完成ですが、Skirtの部分を編集して作成した為に原点から離れています。
そこで、Nキーを押して出てくるタブの中のTransformでMedianのX、Y、Zをすべて0にします。
すると↑のようにすね用ガードが原点の位置にきます。
この作業をすると何がいいかと言うとUnityで取り込んだ時にすね用ガードの原点の位置が真ん中になります。
blender側で移動させていないとUnity側での原点の位置がすね用ガードの右上の方になっている為、移動等を行う時の中心が実際のすね用ガードよりも右上に表示されてしまいます。
blenderですね用ガードを出力しregGuardという名前で保存し、Unityで取り込みます。
すね用がガードをUnityで取り込みキャラクターに装備させる
Tシャツと同じように右足、左足にすね用ガードregGuardを装備させます。
↑のようにすね用ガードregGuardを右足、左足のボーンの子要素に配置し位置や回転を調整しました。
↑が実際に装備させた状態になります。
すね用ガードがペラペラなので位置・回転の調整が結構難しいです・・・・(^_^;)
これでキャラクターに上着、すね用ガードを着せる事が出来ました。
スクリプトから装備品を装備させる
着せ替え機能を作成する前に、キャラクターに上着とすね用ガードを最初から装備させるのではなくスクリプトから装備させるようにしてみます。
つまり装備はプレハブとして用意しておき、装備を切り替えた時にインスタンス化してキャラクターに着せるようにします。
現時点ではさきほど装備させたTシャツとすね用ガードは消さないようにしてください。
まだ使います。
インスタンス化した時に装備品のプレハブのデータを使ってキャラクターのどの位置に表示するかを指定します。
装備品毎にサイズや位置を記憶しておくスクリプトEquipInfomationを作成する
まずは装備情報の管理をするスクリプトEquipInformationを作成して装備品それぞれの情報を返すようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | using UnityEngine; using System.Collections; public class EquipInformation : MonoBehaviour { // アイテムの種類を表す列挙型 public enum KindOfItem { Armor, RightRegGuard, LeftRegGuard }; // アイテムの種類 [SerializeField] private KindOfItem kindOfItem; // 位置情報 [SerializeField] private Vector3 pos; // 角度情報 [SerializeField] private Vector3 rot; // Scale情報 [SerializeField] private Vector3 scale; // アイテムの種類を返す public KindOfItem GetKindOfItem() { return kindOfItem; } // 位置情報を返す public Vector3 GetPosition() { return pos; } // 回転情報を返す public Vector3 GetRotation() { return rot; } // 大きさ情報を返す public Vector3 GetScale() { return scale; } } |
EquipInformationスクリプトは位置・回転・大きさのTransform情報を返します。
装備を変更する時にこの装備がインスタンス化されたらメソッドを使ってデータを呼び出すようにします。
装備品毎に簡単に値を書き換えられるようにインスペクタで値を設定出来るようにしています。
KindOfItem型の変数でアイテムの種類を設定出来るようにし、別のスクリプトで装備の種類を取得出来るようにして装備する場所を設定出来るようにしています。
これでEquipInformationスクリプトが出来たので、さきほどキャラクターに装備させたTシャツ、左右のすねガードのゲームオブジェクトに設定してください。
左右のすねガードはわかりづらかったので名前をLeftRegGuardとRightRegGuardに変更しました。(^_^;)
EquipInformationスクリプトを取りつけたので、インスペクタで値を設定します。
tShirt(名前は変わってますが)の値を設定してみましょう(LeftRegGuardとRightRegGuardの値も同じやり方で設定してください)。
Tシャツのインスペクタを表示させTシャツは鎧系の防具なのでKindOfItemをArmorにします。
pos、rot、scaleをTransform情報を見ながら同じ値を書き込んでいきます。
ここで設定するTransform情報はさきほどキャラクターに装備させたTシャツやすね用ガードの情報でなければいけません。
なぜならインスタンス化したときにこの情報を使ってキャラクターに装備させる為です。
LeftRegGuardとRightRegGuardも同じように設定し、それぞれをProjectタブのAssetsフォルダにドラッグ&ドロップしプレハブ化します。
↑のように装備品フォルダを作成し、そこにEquipInformationスクリプトを設定したTシャツ、左右のすねガードのプレハブが出来ました。
ここで注意しなければいけないのが、装備品をインスタンス化した時に同じ位置に表示されるかどうかがまだわからないので、あらかじめ装備させているTシャツやすねガードはまだ削除しないでください。
スクリプトがうまく働かなかった時はキャラクターに装備品を合わせるところからやり直さなくてはいけなくなりますので。(^_^;)
装備品を変更するChangeGuardスクリプトの作成
次はキャラクター自身に装備品を変更するChangeGuardスクリプトを設定します。
名前が少し変ですがこれはわたくしの都合なので気にしないでください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | using UnityEngine; using System.Collections; using System.Collections.Generic; public class ChangeGuard : MonoBehaviour { // 鎧の親のボーン [SerializeField] private Transform parentArmor; // 右用すねガードの親のボーン [SerializeField] private Transform parentRightRegGuard; // 左用すねガードの親のボーン [SerializeField] private Transform parentLeftRegGuard; // 鎧ゲームオブジェクト配列 [SerializeField] private List<GameObject> armors; // 右用すねガードゲームオブジェクト配列 [SerializeField] private List<GameObject> rightRegGuards; // 左用すねガードゲームオブジェクト配列 [SerializeField] private List<GameObject> leftRegGuards; // 現在装備中の鎧 private GameObject armor; // 現在装備中の右用すね用ガード private GameObject rightRegGuard; // 現在装備中の左用すねガード private GameObject leftRegGuard; // 現在の鎧番号 private int armorCount; // 現在の右すね用ガード番号 private int rightRegGuardCount; // 現在の左すね用ガード番号 private int leftRegGuardCount; [SerializeField] private List<CapsuleCollider> capsuleColliders; void Start () { armorCount = 0; rightRegGuardCount = 0; leftRegGuardCount = 0; // 最初は何も装備しない ChangeArmor(); ChangeLegGuard(); } void Update () { // 1キーが押されたら鎧を変更 if(Input.GetKeyDown("1")) { ChangeArmor(); // 2キーが押されたらすね用ガードを変更 } else if(Input.GetKeyDown("2")) { ChangeLegGuard(); } } // 鎧変更関数 void ChangeArmor() { // 今装備している鎧を削除 if (armor != null) { Destroy (armor); } // 装備が設定されている時 if(armorCount != 0) { var equipInfo = armors[armorCount].GetComponent<EquipInformation>(); // 鎧の番号でプレハブをインスタンス化 armor = Instantiate<GameObject>(armors[armorCount]); // parentArmorを親要素に設定 armor.transform.SetParent(parentArmor); // 鎧の位置・回転・大きさの設定を行う armor.transform.localPosition = equipInfo.GetPosition(); armor.transform.localRotation = Quaternion.Euler(equipInfo.GetRotation()); armor.transform.localScale = equipInfo.GetScale(); // Clothを使う場合はコライダを設定 var cloth = armor.GetComponentInChildren <Cloth> (); if (cloth != null) { cloth.capsuleColliders = capsuleColliders.ToArray(); } } armorCount++; if(armorCount >= armors.Count) { armorCount = 0; } } // すねガード変更関数 void ChangeLegGuard() { // 今装備しているすねガードを削除 if (rightRegGuard != null) { Destroy(rightRegGuard); } if (leftRegGuard != null) { Destroy(leftRegGuard); } // 装備が設定されている時 if(rightRegGuardCount != 0) { var equipInfo = rightRegGuards[rightRegGuardCount].GetComponent<EquipInformation>(); // 右用すねガードの番号でプレハブをインスタンス化 rightRegGuard = GameObject.Instantiate(rightRegGuards[rightRegGuardCount]); // parentRightRegGuardを親要素に設定 rightRegGuard.transform.SetParent(parentRightRegGuard); // すねガードの位置・回転・大きさの設定を行う rightRegGuard.transform.localPosition = equipInfo.GetPosition(); rightRegGuard.transform.localRotation = Quaternion.Euler(equipInfo.GetRotation()); rightRegGuard.transform.localScale = equipInfo.GetScale(); // 装備が設定されていない時は鎧インスタンスを削除 } rightRegGuardCount++; if(rightRegGuardCount >= rightRegGuards.Count) { rightRegGuardCount = 0; } // 装備が設定されている時 if(leftRegGuardCount != 0) { var equipInfo = leftRegGuards[leftRegGuardCount].GetComponent<EquipInformation>(); // 左用すねガードの番号でプレハブをインスタンス化 leftRegGuard = GameObject.Instantiate(leftRegGuards[leftRegGuardCount]); // parentLeftRegGuardを親要素に設定 leftRegGuard.transform.SetParent(parentLeftRegGuard); // すねガードの位置・回転・大きさの設定を行う leftRegGuard.transform.localPosition = equipInfo.GetPosition(); leftRegGuard.transform.localRotation = Quaternion.Euler(equipInfo.GetRotation()); leftRegGuard.transform.localScale = equipInfo.GetScale(); // 装備が設定されていない時は鎧インスタンスを削除 } leftRegGuardCount++; if(leftRegGuardCount >= leftRegGuards.Count) { leftRegGuardCount = 0; } } } |
↑が装備品を切り替えるスクリプトの全文になります。
ChangeGuardスクリプトの解説
それではスクリプトの解説をしていきましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | // 鎧の親のボーン [SerializeField] private Transform parentArmor; // 右用すねガードの親のボーン [SerializeField] private Transform parentRightRegGuard; // 左用すねガードの親のボーン [SerializeField] private Transform parentLeftRegGuard; // 鎧ゲームオブジェクト配列 [SerializeField] private List<GameObject> armors; // 右用すねガードゲームオブジェクト配列 [SerializeField] private List<GameObject> rightRegGuards; // 左用すねガードゲームオブジェクト配列 [SerializeField] private List<GameObject> leftRegGuards; // 現在装備中の鎧 private GameObject armor; // 現在装備中の右用すね用ガード private GameObject rightRegGuard; // 現在装備中の左用すねガード private GameObject leftRegGuard; // 現在の鎧番号 private int armorCount; // 現在の右すね用ガード番号 private int rightRegGuardCount; // 現在の左すね用ガード番号 private int leftRegGuardCount; |
parentArmor、parentRightRegGuard、parentLeftRegGuardは装備品をインスタンス化した時の親要素のTransformを指定します。
Tシャツの親はEthanをキャラクターに使っているとEthanSpine2のボーンなのでインスペクタでEthanSpine2のボーンを指定する事になります。
armors、rightRegGuards、leftRegGuardsは配列のゲームオブジェクトフィールドで、装備可能なプレハブを設定する事になります。
配列の最初の要素は空にしておき装備しない状態も用意しておきます。
今回のサンプルでは装備を変更したい箇所に対応したキーを押した時に次の装備品に装備を変更するようになっています。
armor、rightRegGuard、leftRegGuardは現在装備中のゲームオブジェクトを入れておく変数です。
装備を切り替えた時にこの変数を削除しインスタンス化した装備を消します。
armorCount、rightRegGuardCount、leftRegGuardCountは装備部位ごとに現在どの装備をしているかを表す数値になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | void Start () { armorCount = 0; rightRegGuardCount = 0; leftRegGuardCount = 0; // 最初は何も装備しない ChangeArmor(); ChangeLegGuard(); } void Update () { // 1キーが押されたら鎧を変更 if(Input.GetKeyDown("1")) { ChangeArmor(); // 2キーが押されたらすね用ガードを変更 } else if(Input.GetKeyDown("2")) { ChangeLegGuard(); } } |
Startメソッドで現在装備中の配列の位置を初期化し、ChangeArmorとChangeLegGuardメソッドでTシャツとすねガードを最初の装備に変更します。
最初の装備は何も設定していないので何も装備しない状態にしています。
Updateメソッド内では1キーを押した時にChangeArmorメソッドを呼び、2キーを押した時にChangeGuardメソッドを呼び出しています。
今回はサンプルなので対応するキーを押した時に装備品を変更するという仕様にしています。
通常であれば装備変更画面などで装備品の切り替えを行いその時にChangeArmorやChangeLegGuardメソッドを呼び出すという風に作ればいいと思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | // 鎧変更関数 void ChangeArmor() { // 今装備している鎧を削除 if (armor != null) { Destroy (armor); } // 装備が設定されている時 if(armorCount != 0) { var equipInfo = armors[armorCount].GetComponent<EquipInformation>(); // 鎧の番号でプレハブをインスタンス化 armor = Instantiate<GameObject>(armors[armorCount]); // parentArmorを親要素に設定 armor.transform.SetParent(parentArmor); // 鎧の位置・回転・大きさの設定を行う armor.transform.localPosition = equipInfo.GetPosition(); armor.transform.localRotation = Quaternion.Euler(equipInfo.GetRotation()); armor.transform.localScale = equipInfo.GetScale(); } armorCount++; if(armorCount >= armors.Count) { armorCount = 0; } } |
ChangeGuardはChangeArmorメソッドとほぼ同じなので割愛します。
ChangeArmorメソッドではarmorCountが0じゃない時、つまり装備品が設定されている時に装備品からEquipInformationスクリプトを取得します。
armors配列からゲームオブジェクトを取得しインスタンス化します。
インスタンス化する時に位置情報等を設定する事が出来ますが、親を指定する前に設定するとおかしくなるのでこの時点では単純にインスタンス化するだけにしています。
その後SetParentメソッドで装備の親要素を指定しています。
親要素を指定したらEquipInformationスクリプトを使って情報を取得し、インスタンス化した装備品に設定をします。
localPositionやlocalRotation、localScaleとなっているのは親要素からの相対値を指定する為です。
装備品はボーンの子要素なので親要素からの相対値を指定する必要があります。
プレハブ化した時のTransform情報は親要素からの相対値なので、ここではlocalに設定する事になります。
装備品が初期装備(何も設定していない)に戻った時はインスタンス化したゲームオブジェクトを削除しています。
装備品は品数分を繰り返し切り替えますが、装備品の数を超えた時は初期装備に戻ります。
装備を切り替えたら次の装備品を指すように配列の要素番号を1足しています。
これでChangeGuardスクリプトが完成しました。
キャラクターにChangeGuardスクリプトを設定し、インスペクタでパラメータを設定します。
↑のようにTシャツ、左右のすねガードの親となるボーンを設定し、装備配列のSizeをそれぞれ2にし(今回は部位毎に1つの装備品しかない為)、0番目は空白で1番目に作成した装備品をドラッグ&ドロップするか選択して設定してください。
Cloth機能を使う
装備の切り替え機能が出来ましたが、装備品はキャラクターのボーンに相対的に動きますが服がキャラクターの体にめり込んでしまいます。
その為、装備を切り替えた時にClothに指定するコライダの設定も行えるように変更します。
Cloth機能の詳細については
を参照してください。
Cloth機能に使うコライダの取り付け
まずはキャラクターの子要素の対応するボーンの子要素に空のゲームオブジェクトを作成し、適当に名前を付けCapsuleColliderを取り付けます。
↑のようにボーンの子要素に空のゲームオブジェクトを作成しました。
コライダのサイズは
↑のような感じのサイズと位置で設定しました。
ChangeGuardスクリプトに機能を追加
ChangeGuardスクリプトに処理を追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | [SerializeField] private CapsuleCollider[] capsuleColliders; // 鎧変更関数 void ChangeArmor() { // 今装備している鎧を削除 if (armor != null) { Destroy (armor); } // 装備が設定されている時 if(armorCount != 0) { var equipInfo = armors[armorCount].GetComponent<EquipInformation>(); // 鎧の番号でプレハブをインスタンス化 armor = Instantiate<GameObject>(armors[armorCount]); // parentArmorを親要素に設定 armor.transform.SetParent(parentArmor); // 鎧の位置・回転・大きさの設定を行う armor.transform.localPosition = equipInfo.GetPosition(); armor.transform.localRotation = Quaternion.Euler(equipInfo.GetRotation()); armor.transform.localScale = equipInfo.GetScale(); // Clothを使う場合はコライダを設定 var cloth = armor.GetComponentInChildren <Cloth> (); if (cloth != null) { cloth.capsuleColliders = capsuleColliders.ToArray(); } } armorCount++; if(armorCount >= armors.Count) { armorCount = 0; } } |
インスペクタで先ほど作成した3つのコライダを設定出来るようにしておきます。
今回は鎧部分だけCloth機能を使う事にします。
その為、ChangeArmorメソッド内だけに処理を追加します。
インスタンス化した鎧の子要素(メッシュ情報のオブジェクト)からClothコンポーネントを取得し、そのコライダにインスペクタで設定したコライダを指定します。
鎧のプレハブにClothコンポーネントの取り付け
鎧のプレハブのメッシュオブジェクトにClothコンポーネントを取り付け、ウエイトを設定します。
鎧プレハブは
わたくしの場合↑のような階層になっており、defaultがメッシュ部分になります。
インスペクタからClothを取り付けます。
Skinned Mesh RendererのMeshに鎧のメッシュを指定します。
Clothのウエイト付けに関しては先ほどのリンク先を参照してください。
これでCloth機能に対応した着せ替えが出来ます。
これで機能が完成しました。
キャラクターの装備が変わるか確認する
Unityの実行ボタンを押して確認してみましょう。
↑のように1、2のキーを押した時にそれぞれの装備が切り替わるようになりました。
ゲームで武器、兜や鎧等の装備品を変更したい場合に、今回の機能を応用すると着せ替え機能が作れると思います。
記事中でも言及しましたが、ボーンの動きと合わないと装備品を突き抜けてしまうのでそこら辺は注意が必要ですね。
シェーダ―を使ってカリングを行わない
Unityの基本のシェーダ―ではカリングが行われ、見えていない部分は表示せず処理負荷を減らしているようです。
シェーダ―は陰影処理をするプログラムという意味ですが、Unityのシェーダ―ではオブジェクトの描画を設定しているファイルという事ですかね。
今回作成したTシャツをSceneタブにして中身を覗いてみると↑のように服の内側が透けて見えています。
ですが物によっては中身から見た時に透けないようにしたい事もあると思います。
そんな時はカスタムシェーダ―を作成し、カリングを行わないシェーダ―をTシャツに設定するといいみたいです。
↑のようにProjectタブのAssetsフォルダ内で右クリック→Shader→Standard Surface Shaderを選択し、名前をtshirt4とします。
↑のようにシェーダ―ファイルが作成されました。
tshirt4ファイルをダブルクリックしてMonoDevelopを開きます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Shader "Custom/tshirt4" { Properties { _Color ("Color", Color) = (1,1,1,1) _MainTex ("Albedo (RGB)", 2D) = "white" {} _Glossiness ("Smoothness", Range(0,1)) = 0.5 _Metallic ("Metallic", Range(0,1)) = 0.0 } SubShader { Tags { "RenderType"="Opaque" } LOD 200 cull off CGPROGRAM |
LOD 200の下にcull offという記述を追加し保存します。
↑のようにtshirt4を選択しShaderを今作成したtshirt4シェーダ―に変更します。
↑のように自分で作成したカスタムシェーダ―のtshirt4を設定しました。
それではSceneタブでTシャツの中身を覗いてみましょう。
↑のようにTシャツの中身も表示されていますね!
Unityではカメラの描画範囲だけを表示するフラスタルカリングが行われていますが、カメラで写している部分だけを描画するオクルージョンカリングの機能もあります。
それはまだ使った事がないのでいずれまた記事に出来たらと思います。
今回のシェーダ―関連の設定に関しては
を参考にさせて頂きました。
終わりに
この服を着せかえる機能の記事は去年の11月中にはすでに完成していたんですが、なんだかんだで3カ月公開出来ていなかったんですね。
この記事を公開した事で今まで貯めておいた記事は全部なくなりました。
( ノД`)シクシク…
ますます記事の更新ペースは落ちていくと思います・・・・(-_-)