AnyPortrait > マニュアル > キャラクターにアイテム装備
AnyPortraitで作成されたキャラクターに、外部のオブジェクトを付着するために、「ソケット(Socket)」(関連ページ)と呼ばれる機能があります。
このページでは、この機能を利用して、外部のオブジェクトは、特に武器や装備などのアイテムを付着する方法を説明します。
デモシーンの「海賊少女キャラクター」と「武器メッシュ」を用意しました。
現在キャラクターが持っている既存の "武器"は削除して、「3D武器」をキャラクターが右手でつかむてみましょう。
注意
このページでは、相違点を示すために3Dモデルを用意したが、2D画像が適用されるQuadメッシーナSpriteを準備することをお勧め。
以下で説明するレンダリング方式の問題があるからです。
一番最初にする必要があり作業は「ソケット」を設定することです。
(1) 武器が付着される右手のボーンを選択します。
(2) スクリプトでは、ボーンを呼び出す必要がありますので、ボーンの「名前」を覚えています。
(3) 「Socket」属性を有効にします。
既存の「武器」は隠します。
(このプロセスは、サンプルを作成するための段階であり、無視できます。)
(1) メッシュグループの「Settingタブ」で (2) 既存の「武器」を選択し、 (3) 「Visible」をオフにします。
装着する武器を準備します。
3Dメッシュを空の「GameObject」の子に設定して、武器を構成しました。
これを準備している理由は、オブジェクトの原点が「武器の持ち手」である必要があるためです。
また、ボーンが指している方向は、Y軸なので、武器もY方向を向くようにします。
スクリプトを以下のように作成してみましょう。
using UnityEngine;
using AnyPortrait;
public class WeaponEquipScript : MonoBehaviour
{
public apPortrait portrait;
public Transform gunTransform;
void Start()
{
//キャラクターの右手ボーンを武器の親として設定
Transform handBone = portrait.GetBoneSocket("Bone Hand R");
gunTransform.parent = handBone;
//PositionとRotationをSocketと同様に作成し、Scaleの符号を補正
gunTransform.localPosition = Vector3.zero;
gunTransform.localRotation = Quaternion.identity;
Vector3 gunScale = gunTransform.localScale;
if(gunScale.x < 0) { gunScale.x *= -1; }
if(gunScale.y < 0) { gunScale.y *= -1; }
gunTransform.localScale = gunScale;
}
}
「GetBoneSocket」関数を利用して、右手ボーンのTransformをインポートすることができます。
「武器のGameObject」を「右手のボーンのTransform」の子になるように変更して、ローカルの場所を初期化すると、無機モデルが右手の動きに応じて動くことです。
上記のスクリプトをシーンに適用します。
(1) 新しい「GameObject」を作成します。
(2) 作成したスクリプトを追加したGameObjectに追加し、キャラクターと武器のTransformを変数にそれぞれ指定します。
ゲームを実行してみましょう。
武器がキャラクターの右手に付着して動くことを見ることができます。
しかしながら武器メッシュのレンダリング順序が異常です。
武器がキャラクターの手の中に位置するべきなのに、今ではキャラクターの後ろに位置します。
武器メッシュのレンダリング順序を指定するためには、メッシュのレンダリング順序、すなわち、「Sorting Order」の値を知る必要があります。
AnyPortraitエディタを再度開きます。
(1) このキャラクターの右手は、「手のひらメッシュ」と「指メッシュ」に分割されており、武器がその間に位置します。
(2) 「指メッシュ」を選択し、 (3) メッシュの「名前」(「Hand R Finger」)を記憶します。
メッシュのレンダリングの順序に応じて異なる「Sorting Order」が割り当てられるようになります。
(1) 「Bakeボタン」を押します。
(2) 「Settingタブ」をクリックします。
(3) 「Sorting Order Option」を「Depth To Order」に変更し、「Order Per Depth」を「2」に設定します。
スクリプトで武器メッシュの「Sorting Order」を「指メッシュ」より「1」少なく作ろうとします。
そのため、「Sorting Order」が「2」以上の間隔で割り当てる必要があり、他のメッシュと武器メッシュのレンダリング順序が重複していることを避けることができます。
スクリプトを以下のように変更して、「Sorting Order」をコントロールします。
using UnityEngine;
using AnyPortrait;
public class WeaponEquipScript : MonoBehaviour
{
public apPortrait portrait;
public Transform gunTransform;
public MeshRenderer gunMeshRenderer;
void Start()
{
//キャラクターの右手ボーンを武器の親として設定
Transform handBone = portrait.GetBoneSocket("Bone Hand R");
gunTransform.parent = handBone;
//PositionとRotationをSocketと同様に作成し、Scaleの符号を補正
gunTransform.localPosition = Vector3.zero;
gunTransform.localRotation = Quaternion.identity;
Vector3 gunScale = gunTransform.localScale;
if(gunScale.x < 0) { gunScale.x *= -1; }
if(gunScale.y < 0) { gunScale.y *= -1; }
gunTransform.localScale = gunScale;
//指メッシュのすぐ後ろレンダリングするように設定
int fingerSortingOrder = portrait.GetSortingOrder("Hand R Finger");
gunMeshRenderer.sortingOrder = fingerSortingOrder - 1;
}
}
武器メッシュの「MeshRenderer」の「Sorting Order」をキャラクターの「指メッシュ(Hand R Finger)」より「1」小さく設定するスクリプトです。
スクリプトに「MeshRenderer gunMeshRenderer」変数が追加されたので、Unityエディタで武器メッシュの「MeshRenderer」を割り当てます。
ここで注意する点があります。
基本的には体積を持つ「Opaque」方式の材質は「Sorting Order」でレンダリング順序を制御することができません。
したがって、この例では、3Dモデルに製作されたメッシュのレンダリング方式を「Transparent」に変更する必要があります。
「Transparent」方式の材質では、モデルのレンダリングは多少以上することができます。
したがって可能な2D画像をそのまま利用する「Quad」メッシーナ「Sprite」でアイテムを作成をお勧めします。
ゲームを実行すると、レンダリングの順序が補正され、キャラクターが正しく銃を握ることが表現されます。