ZEPETOキャラクターに車両を適用する
ZEPETOキャラクターにオブジェクトを取り付けるガイドを適用することで、キャラクターが車や飛行機、ペットなどに乗っているかのように、乗り物を実装できます。
📘 以下のガイドを参照してください [ZEPETOキャラクターにオブジェクトを取り付ける]
アニメーターの設定

1) プロジェクト > 作成 > アニメーターコントローラーに移動してアニメーターコントローラーを作成し、名前をVehicleZepetoAnimatorに変更します。

2) アニメータータブで、Create State > Emptyを選択して空の状態を作成します。

3) インスペクターで適切に名前を変更し、モーションにアニメーションクリップを割り当てます。

- 希望するアニメーションクリップファイルを使用するには、カスタムアニメーションガイドを参照してください。
📘 次のガイドを参照してください [カスタムアニメーションを適用]
4) VehicleZepetoAnimatorをZEPETOPlayersにドラッグ&ドロップして設定します。

👍 ヒント
- カメラの高さが車両のサイズに応じて変更する必要がある場合、ZEPETOPlayersでCamera LookOffsetの値をプリセットできます。
サンプルコード
1) プロジェクト > 作成 > ZEPETO > TypeScript に移動して TypeScript を作成し、RideVehicle に名前を変更します。
2) 以下のようにサンプルスクリプトを書きます。
- この例の Vehicle Transform 値は、実際に適用する際に Vehicle Prefab に合わせて調整する必要があります。
import { ZepetoScriptBehaviour } from 'ZEPETO.Script';
import { ZepetoCharacter, ZepetoPlayers } from 'ZEPETO.Character.Controller';
import { Transform, Animator, GameObject, HumanBodyBones, Object, Vector3, Quaternion } from 'UnityEngine';
export default class RideVehicle extends ZepetoScriptBehaviour {
public vehiclePrefab : GameObject;
public bodyBone: HumanBodyBones;
private _localCharacter: ZepetoCharacter;
private _vehicle : GameObject;
Start() {
ZepetoPlayers.instance.OnAddedLocalPlayer.AddListener(() => {
// Find the local player and set it to _localCharacter.
this._localCharacter = ZepetoPlayers.instance.LocalPlayer.zepetoPlayer.character;
// Get the _localCharacter's animator component.
const animator: Animator = this._localCharacter.ZepetoAnimator;
// Get the position of the bone to attach the object to.
const bone: Transform = animator.GetBoneTransform(this.bodyBone);
// Create the Vehicle prefab.
this._vehicle = Object.Instantiate(this.vehiclePrefab, bone) as GameObject;
// Set Vehicle Transform
this._vehicle.transform.localPosition = new Vector3(0.5, 0,0);
this._vehicle.transform.localRotation = Quaternion.Euler(0, 0,90);
});
}
}
3) スクリプトの作成が完了したら、スクリプトをシーン内のGameObjectに追加します。
4) インスペクターで、車両のプレハブリソースと取り付けるボディボーンを割り当てます。
5) プレイボタンをクリックすると、ZEPETOキャラクターが車両に乗っているのが見えます。

👍 ヒント
- 車両のプレハブとキャラクターのアニメーションクリップを変更するだけで、さまざまな車両を作成できます。

アイテムを消費したときのサイズ変更の例
ここに楽しいアプリケーションの例があります:キャラクターが車両に乗っているときにアイテムを消費するとサイズが変わるコンテンツを実装します。
1) この例では、2種類のプレハブを用意し、消費時にサイズが増加するアイテムのタグを「Increase」、サイズが減少するアイテムのタグを「Decrease」と設定しました。
2) 各アイテムにコライダーを追加し、IsTriggerをチェックしてください。


3) プロジェクト > 作成 > ZEPETO > TypeScript に移動して TypeScript を作成し、ChangeObjectSize に名前を変更します。
4) 以下のようにサンプルスクリプトを書きます。
import { Collider, GameObject, Vector3 } from 'UnityEngine';
import { ZepetoScriptBehaviour } from 'ZEPETO.Script';
export default class ChangeObjectSize extends ZepetoScriptBehaviour {
public vehicle: GameObject;
Start() {
}
OnTriggerEnter(collider: Collider) {
if (collider.tag === "Increase") {
this.gameObject.transform.localScale += new Vector3(0.1, 0.1, 0.1);
GameObject.Destroy(collider.gameObject);
}
if (collider.tag === "Decrease") {
const decreaseAmount = new Vector3(0.1, 0.1, 0.1);
const newScale = this.gameObject.transform.localScale - decreaseAmount;
GameObject.Destroy(collider.gameObject);
// 例外処理: スケールが (1, 1, 1) より小さくならないようにします
if (newScale.x >= 1 && newScale.y >= 1 && newScale.z >= 1) {
this.gameObject.transform.localScale = newScale;
}
}
}
}
- コードの重要な部分は、各アイテムに触れたときにZEPETOキャラクターのサイズを変更するためにlocalScaleを修正することです。
- サイズ変更のための数値を自由に調整してください。
- ただし、スケールが(1,1,1)より小さくならないように例外を処理することを確認してください。
5) このスクリプトは、ランタイムで作成されたZEPETOキャラクターに追加する必要があります。 したがって、次のように車両を取り付けるRideVehicleスクリプトを修正してください。
import { ZepetoScriptBehaviour } from 'ZEPETO.Script';
import { ZepetoCharacter, ZepetoPlayers } from 'ZEPETO.Character.Controller';
import { Transform, Animator, GameObject, HumanBodyBones, Object, Vector3, Quaternion } from 'UnityEngine';
import ChangeObjectSize from './ChangeObjectSize';
export default class RideVehicle extends ZepetoScriptBehaviour {
public vehiclePrefab : GameObject;
public bodyBone: HumanBodyBones;
private _localCharacter: ZepetoCharacter;
private _vehicle : GameObject;
Start() {
ZepetoPlayers.instance.OnAddedLocalPlayer.AddListener(() => {
// ローカルプレイヤーを見つけて、_localCharacterに設定します。
this._localCharacter = ZepetoPlayers.instance.LocalPlayer.zepetoPlayer.character;
// _localCharacterのアニメーターコンポーネントを取得します。
const animator: Animator = this._localCharacter.ZepetoAnimator;
// オブジェクトを取り付けるためのボーンの位置を取得します。
const bone: Transform = animator.GetBoneTransform(this.bodyBone);
// Vehicleプレハブを作成します。
this._vehicle = Object.Instantiate(this.vehiclePrefab, bone) as GameObject;
// Vehicle Transformを設定します
this._vehicle.transform.localPosition = new Vector3(0.5, 0,0);
this._vehicle.transform.localRotation = Quaternion.Euler(0, 0,90);
// CharacterControllerにスクリプトを追加します
const sizeScript = this._localCharacter.gameObject.AddComponent<ChangeObjectSize>();
// スクリプトのインスペクタに車両を追加します
sizeScript.vehicle = this._vehicle;
});
}
}
- 実行時にChangeObjectSizeスクリプトを追加するコードが追加されました。
6) 再生ボタンをクリックすると、アイテムを消費するたびにキャラクターのサイズが変わるのが見えます。

車両とのインタラクション
インタラクションガイドを適用することで、車両とインタラクションした後に希望の場所で乗車することが可能です。
📘 以下のガイドを参照してください。 [オブジェクトとの相互作用]
設定
1) インタラクションガイドと同様に、DockPointオブジェクトとUIプレハブを車両プレハブに設定します。

2) Unityエディタで、上部のトランスフォームギズモトグルボタンがローカルに設定されていることを確認し、Z軸(青い矢印)がオブジェクトの外側を指すように回転させます。

3) コライダーコンポーネントを追加し、isTriggerオプションをチェックします。
4) プレイヤーがオブジェクトと対話できる範囲内にコライダーのサイズを調整します。

5) 階層 > 空のオブジェクトを作成に進み、DockPointの子として空のオブジェクトを作成し、IconPosに名前を変更します。

6) PrefIconCanvasをオブジェクトインタラクションガイドと同様に設定し、それをプレハブにします。

7) 追加ステップ: 降車ボタンを作成する
- Hierarchy > UI > Buttonに移動して、車両オブジェクトの子としてボタンを作成し、それを「降車ボタン」と名前を変更します。
車両に乗車アニメーションを追加する
キャラクターが車両に乗ったり降りたりする際には、自然なアニメーター設定が必要です。
以下のガイドは、乗車または降車に必要なアニメーター設定を手助けします。
カスタムアニメーションを適用するガイドを参照して、カスタムアニメーターに座っているアニメーション状態を追加します。
📘 以下のガイドを参照してください。 [カスタムアニメーションの適用]
1) 追加したアニメーションステートを右クリックし、Make TransitionをクリックしてIdleからSittingへの遷移を作成し、SittingからIdleへの遷移も作成します。作成した遷移を選択し、Has Exit Timeオプションのチェックを外します。

2) カスタムアニメーター → パラメータ → [ + ] で、Bool条件を追加し、isRidingに名前を変更します。

3) SittingからIdleステートへの遷移について、Conditions → [ + ]をクリックし、isRiding条件を追加し、オプションをfalseに設定します。

4) IdleからSittingステートへの遷移について、Conditions → [ + ]をクリックし、isRiding条件を追加し、オプションをtrueに設定します。

スクリプト
InteractionIcon.tsスクリプトを作成します。これは、車両プレハブのトリガーエリアに入るとインタラクションUIを表示するものです。
書かれたInteractionIcon ZEPETOScriptをDockPointオブジェクトに追加し、インスペクタでPref Icon CanvasとIcon Positionを割り当てます。
UIと対話した後に車両に乗る方法についてのサンプルコードは、以下のRideVehicleExampleを参照してください。
import { Animator, GameObject, HumanBodyBones, Physics, Transform, Vector3, WaitForEndOfFrame } from 'UnityEngine';
import { ZepetoScriptBehaviour } from 'ZEPETO.Script';
import { ZepetoPlayers, ZepetoCharacter, CharacterStateMachine } from "ZEPETO.Character.Controller";
import { Button } from 'UnityEngine.UI';
import InteractionIcon from './InteractionIcon';
export default class RideVehicleExample extends ZepetoScriptBehaviour {
@SerializeField() private bodyBone: HumanBodyBones;
public isRiding: bool;
public getOffBtn: Button;
public vehicleObj: GameObject;
private _interactionIcon: InteractionIcon;
private _localCharacter: ZepetoCharacter;
private _playerSittingPosition: Vector3;
private _animator: Animator;
private Start() {
ZepetoPlayers.instance.OnAddedLocalPlayer.AddListener(() => {
this._localCharacter = ZepetoPlayers.instance.LocalPlayer.zepetoPlayer.character;
this._animator = this._localCharacter.ZepetoAnimator;
});
this._interactionIcon = this.transform.GetComponent<InteractionIcon>();
this._interactionIcon.OnClickEvent.AddListener(() => {
// インタラクションアイコンがクリックされたとき、アイコンを隠してインタラクションを実行する
this._interactionIcon.HideIcon();
this.DoInteraction();
});
// getOffBtn(車両から降りるボタン)のクリックイベントを設定します。
this.getOffBtn.onClick.AddListener(() => {
if(this.isRiding) {
this.StopInteraction();
this._interactionIcon.ShowIcon();
}
});
this.getOffBtn.gameObject.SetActive(false);
}
//乗車ロジックを実行するメソッド
private DoInteraction() {
// Animatorの遷移値を設定して、現在のアニメーション状態を座っている状態に切り替えます。
this._animator.SetBool("isRiding", true);
this.StartCoroutine(this.SnapBone());
// 現在のアニメーションを修正するために、Animatorを無効にします。
this._localCharacter.StateMachine.constraintStateAnimation = true;
// 車両オブジェクトの親をローカルキャラクターに設定します。
this.vehicleObj.transform.parent = this._localCharacter.transform;
// getOffButtonをアクティブにします。
this.getOffBtn.gameObject.SetActive(true);
this.isRiding = true;
}
private StopInteraction() {
// Animatorの遷移値を設定して、アニメーション状態をアイドルに切り替えます。
this._animator.SetBool("isRiding", false);
// Animatorを再度アクティブにします。
this._localCharacter.StateMachine.constraintStateAnimation = false;
this.isRiding = false;
// Vehicle Objectの親をnullに設定します。
this.vehicleObj.transform.parent = null;
// getOffButtonを無効にします。
this.getOffBtn.gameObject.SetActive(false);
}
// 車両にボーンをスナップするためのコルーチン
private *SnapBone() {
const animator: Animator = this._localCharacter.ZepetoAnimator;
const bone: Transform = animator.GetBoneTransform(this.bodyBone);
let idx = 0;
while (true) {
// ボーンとキャラクターの位置の距離を計算します。
const distance = Vector3.op_Subtraction(bone.position, this._localCharacter.transform.position);
const newPos: Vector3 = Vector3.op_Subtraction(this.transform.position, distance);
// プレイヤーの座っている位置を更新し、キャラクターの位置と回転を設定します。
this._playerSittingPosition = newPos;
this._localCharacter.transform.position = this._playerSittingPosition;
this._localCharacter.transform.rotation = this.transform.rotation;
yield new WaitForEndOfFrame();
idx++;
// アニメーションの5フレーム中に位置を調整します。
if (idx > 5) {
return;
}
}
}
}
- スクリプトの流れは次のとおりです:
- 開始()
- アイコンがクリックされると、this._interactionIconが無効化され、DoInteraction()関数が呼び出されます。
- DoInteraction()
- アニメーターの遷移値を設定して、座っているアニメーションを再生します。
- Snap Bone()コルーチンを開始して、ZEPETOキャラクターのbodyBoneをtargetTransformに接続します。
- この関数を使用して、this._localCharacter.StateMachine.constraintStateAnimation = true; 現在のアニメーターの遷移を無効にし、現在再生中のアニメーションをロックします。
- 車両オブジェクトの親がZEPETOキャラクターに変更されます。
- 右上のGet Offボタンが有効化されます。
- StopInteraction()
- アニメーターの遷移値を設定して、Idleアニメーションを再生します。
- 状況に応じて適切なアニメーションが再生されるように、アニメーターの遷移を再有効化します。
- 車両オブジェクトの親をnullに設定します。
- Get Offボタンを無効化します。
- this.getOffBtn.onClick
- StopInteraction()関数が呼び出されます。
- this._interactionIconが有効化されます。
書かれた RideVehicleExample ZEPETOScript を DockPoint に追加し、インスペクタで Get Off ボタンと車両プレハブを割り当てます。

[▶︎(再生)] 車両に乗るために再生ボタンを押してください。

👍 ヒント
- 上記のサンプルは、マルチプレイヤー同期の対象とならないコンテンツの例です。
- マルチプレイヤー同期を実装するには、各プレイヤーがどの車両に乗っているか、車両のサイズと位置などの情報を同期する必要があります。