アニメーションイベントの使用
アニメーションイベントは、アニメーションクリップの特定の時間にカスタマイズされた関数を呼び出したり、アクションを実行したりする方法を提供します。
これにより、アニメーションとスクリプトの間での相互作用が可能になり、アニメーションの正確なタイミングでアクションを実行する際に便利です。
オブジェクトアニメーションへのイベントの追加
以下の例は、アニメーションオブジェクトにアニメーションイベントを追加します。
この構造は、上下に繰り返すアニメーションにアップイベントとダウンイベントを追加することで、イベントが実行されるたびにコンソールログに情報を出力します。

1) シーンにキューブを作成するには、GameObject > 3D Object > Cubeを選択します。
- 作成したキューブを選択し、インスペクターパネルの「Add Component」ボタンをクリックしてAnimatorコンポーネントを追加します。
- 追加したAnimatorにキューブAnimator Controllerを適用します。
- キューブAnimator Controllerのエントリにキューブアニメーションクリップを適用し、シーンが再生されるときにキューブアニメーションが再生されるようにします。

Animatorの登録とアニメーションクリップの編集については、以下のガイドを参照してください。
📘 Unityアニメーションイベントガイド https://docs.unity3d.com/kr/current/Manual/script-AnimationWindowEvent.html
📘 Unity学習アニメーションチュートリアル https://learn.unity.com/tutorial/may-18-animation?language=en#
2) 次のプロパティをキューブのアニメーションクリップに追加します。
- キューブのアニメーションクリップの0秒、2秒のセクションに位置のキーフレーム (x: 0, y:0, z:0) があります。
- キューブのアニメーションクリップの1秒のセクションに位置のキーフレーム (x: 0, y:1, z:0) があります。
(1) キューブのアニメーションクリップの1秒のセクションにアニメーションイベントを登録します。
- 関数 : 呼び出し
- 文字列 : 上
(2) キューブのアニメーションクリップの2秒のセクションにアニメーションイベントを登録します。
- 関数 : 呼び出し
- 文字列 : 下

- UnityでC#を使ってアニメーションイベントを書くときは、関数名をFunctionに書きます。
- ただし、TypeScriptでアニメーションイベントを呼び出すには、InvokeをFuntionに書き、関数名をStringとして引数の値を記述する必要があります。
3) プロジェクトを作成 > 作成 > ZEPETO > TypeScriptとし、ObjectAnimationControllerに名前を変更します。
- 以下のようにサンプルスクリプトを書きます。
import { ZepetoScriptBehaviour } from 'ZEPETO.Script'
export default class ObjectAnimationController extends ZepetoScriptBehaviour {
public Up() {
console.log(`Cube is Up`);
}
public Down(){
console.log(`Cube is Down`);
}
}4) 再生ボタンを押して実行すると、キューブのアニメーションが再生されている間にコンソールログの出力を見ることができます。

ローカルキャラクターのアニメーションイベントを使用して足音を再生します。
ZEPETOのキャラクターのAnimatorにアニメーションイベントを追加するには、キャラクターが作成されるときにランタイムでイベントを追加する必要があります。
以下の例では、ローカルプレイヤーのAnimatorの特定のアニメーションクリップにイベントをランタイムで適用し、イベントが発生したときに足音を再生します。
1) ローカルプレイヤーのアニメーターオブジェクトに適用されるFootStepControllerスクリプトを作成します。FootStepControllerは、Animatorにアニメーションイベントを追加する役割を担います。
- プロジェクトを作成 > 作成 > ZEPETO > TypeScript として作成し、FootStepControllerに名前を変更します。
- 以下のようにスクリプトを書きます。
import { AnimationEvent, Animator, AudioClip, AudioSource } from 'UnityEngine';
import { ZepetoScriptBehaviour } from 'ZEPETO.Script';
export default class FootStepController extends ZepetoScriptBehaviour {
// 足音効果に使用される音
public footStepSound: AudioClip;
// 足音を再生するためのオーディオソース
private _zepetoAudio: AudioSource;
// 足音をトリガーするアニメーションイベントを追加
public AddAnimationEvent() {
// このGameObjectにアタッチされたAnimatorコンポーネントを取得
const anim = this.GetComponent<Animator>();
// Animatorコンポーネントが存在するか確認
if (anim != null) {
// 足音のためのAudioSourceを作成
this.SetAudio();
// アニメーションクリップ内で足音が再生される時間を指定
const runSoundEventTimes = [0.1, 0.6];
// 指定されたアニメーションクリップにアニメーションイベントを追加
this.AddAnimationClipEvent(anim, "move_walk", runSoundEventTimes);
}
}
// 足音を再生するためのAudioSourceを設定
private SetAudio() {
// AudioSourceコンポーネントを作成し、設定
this._zepetoAudio = this.gameObject.AddComponent<AudioSource>();
this._zepetoAudio.clip = this.footStepSound;
}
// 足音をアクティブにする
public ActivateFootSteps() {
// 足音が再生されていることを示すログメッセージを出力
console.log("足音!");
// 設定されたAudioSourceを使用して足音を再生
this._zepetoAudio.Play();
}
// 指定されたアニメーションクリップにアニメーションイベントを追加
private AddAnimationClipEvent(anim: Animator, clipName: string, eventTimes: number[]) {
// アニメーションクリップのインデックスを初期化
let animationClipIndex: number;
// runtimeAnimatorControllerからすべてのアニメーションクリップを取得
const clips = anim.runtimeAnimatorController.animationClips;
// 指定されたアニメーションクリップのインデックスを見つける
for (let i = 0; i < clips.length; i++) {
if (clips[i].name == clipName) {
animationClipIndex = i;
}
}
// 指定されたイベント時間を反復処理
eventTimes.forEach(eventTime => {
// 足音トリガーのための新しいAnimationEventを作成
const newEvent: AnimationEvent = new AnimationEvent();
newEvent.time = eventTime;
newEvent.functionName = "Invoke";
newEvent.stringParameter = "ActivateFootSteps";
// 新しいAnimationEventをアニメーションクリップに追加
clips[animationClipIndex].AddEvent(newEvent);
});
}
}- スクリプトの説明
- FootStepControllerはアニメーションイベントを追加し、そのイベントが発生したときに足音の効果音を再生します。
- SetAudio()はAudioSourceコンポーネントを追加し、オブジェクトに足音の音を適用します。
- AddAnimationClipEvent()は指定されたアニメーションクリップにアニメーションイベントを追加します。次の要素を引数値として指定する必要があります。
- ローカルプレイヤー用のAnimator
- イベントが適用されるアニメーションクリップの名前
- イベントを適用するアニメーション時間の配列
- AddAnimationClipEvent()で登録されたnewEventには、次の項目が設定されます。
(1) newEvent.time : イベントが発生する際のアニメーション時間。値が0は全長の始まり、値が1は全長の終わりです。
(2) newEvent.functionName : イベントが発生する際の関数の名前。TypeScriptでは「Invoke」として型付けされるべきです。
(3) newEvent.stringParameter : イベントが関数を実行する際に関数に設定されるパラメータ値。TypeScriptは実行される関数名をリストします。
- イベントが発生すると、ActivateFootSteps()が実行され、足音が再生されます。

2) ローカルプレイヤーがランタイムで作成されるときに、FootStepControllerコンポーネントをローカルプレイヤーのAnimatorオブジェクトに追加するFootStepManagerを作成します。
- プロジェクト > 作成 > ZEPETO > TypeScript として、FootStepManagerに名前を変更します。
- 以下のようにスクリプトを書きます。
import { SpawnInfo, ZepetoPlayers } from 'ZEPETO.Character.Controller'
import { ZepetoScriptBehaviour } from 'ZEPETO.Script'
import FootStepController from './FootStepController'
import { WorldService } from 'ZEPETO.World'
import { AudioClip } from 'UnityEngine';
export default class FootStepManager extends ZepetoScriptBehaviour {
// 足音のために再生される音
public footStepSound: AudioClip;
Start() {
// ローカルプレイヤーが追加されたときのイベントリスナー
ZepetoPlayers.instance.OnAddedLocalPlayer.AddListener(() => {
// ローカルプレイヤーのZepetoキャラクターにアクセス
const zepetoCharacter = ZepetoPlayers.instance.LocalPlayer.zepetoPlayer.character;
// ZepetoAnimatorのGameObjectにFootStepControllerスクリプトをアタッチ
const footStepController = zepetoCharacter.ZepetoAnimator.gameObject.AddComponent<FootStepController>();
// FootStepControllerのためにfootStepSoundを設定
footStepController.footStepSound = this.footStepSound;
// 足音をトリガーするアニメーションイベントを追加
footStepController.AddAnimationEvent();
});
}
}- スクリプトの説明
- FootStepManagerがローカルプレイヤーが追加されることを検出した後、プレイヤーのZepetoAnimatorのGameObjectにFootStepControllerスクリプトをアタッチします。
- FootStepControllerは足音の音を再生するアニメーションイベントを追加する責任があります。
- Animatorのアニメーションイベントによって実行される関数のスクリプトは、対応するAnimatorコンポーネントが適用されているオブジェクトに同一に適用されなければなりません。
- したがって、ZepetoAnimator.gameObjectを見つけて、FootStepControllerスクリプトをAddComponentとして適用する必要があります。
3) FootStepManagerのfootStepSoundに足音を適用します。

4) 再生ボタンを押して実行すると、ローカルプレイヤーが歩くたびに音が再生されるのがわかります。

👍 ヒント
- ZEPETO基本アニメーターの歩行状態は、いくつかのアニメーションブレンドと状態で構成されています。
- この例はmove_walk状態にのみ音を適用するため、AddAnimationClipEvent()をカスタマイズして、速歩やランニングなどの状態に直接入力できます。
- 音が複数のアニメーション状態に適用される場合、アニメーションブレンドのために足音が重なることがあります。これを解決するために、AnimationEvent.animatorClipInfo.weightが0.5のときに対応する音が再生されるように追加の条件文を書く必要があります。
❗️ 知られている問題
- 開発ガイドスタイルに従って実装すると、次のエラーメッセージが表示されることがありますが、実行には問題ありません。
