การใช้เหตุการณ์แอนิเมชัน
เหตุการณ์อนิเมชันให้วิธีการเรียกฟังก์ชันที่กำหนดเองหรือดำเนินการในเวลาที่เฉพาะเจาะจงในคลิปอนิเมชัน
สิ่งนี้ช่วยให้มีการโต้ตอบระหว่างอนิเมชันและสคริปต์ และมีประโยชน์เมื่อดำเนินการในเวลาที่แน่นอนของอนิเมชัน
การเพิ่มเหตุการณ์ในอนิเมชันของวัตถุ
ตัวอย่างต่อไปนี้เพิ่มเหตุการณ์อนิเมชันให้กับวัตถุที่มีการอนิเมชัน
โครงสร้างนี้จะส่งข้อมูลไปยังบันทึกคอนโซลเมื่อใดก็ตามที่มีการดำเนินการเหตุการณ์โดยการเพิ่มเหตุการณ์ขึ้นและเหตุการณ์ลงในอนิเมชันที่ทำซ้ำขึ้นและลง

1) เลือก GameObject > 3D Object > Cube เพื่อสร้างลูกบาศก์ในฉาก.
- เลือกลูกบาศก์ที่สร้างขึ้นและเพิ่มคอมโพเนนต์ Animator โดยคลิกที่ปุ่ม Add Component ในแผง Inspector.
- นำเข้า Animator Controller ของลูกบาศก์ไปยัง Animator ที่เพิ่มเข้าไป.
- นำเข้าแอนิเมชันคลิปของลูกบาศก์ไปยังจุดเริ่มต้นของ 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) เพิ่มคุณสมบัติต่อไปนี้ในคลิปแอนิเมชันของลูกบาศก์.
- มีเฟรมหลักของตำแหน่ง (x: 0, y:0, z:0) ในช่วง 0 วินาที, 2 วินาทีของคลิปแอนิเมชันของลูกบาศก์.
- มีเฟรมหลักของตำแหน่ง (x: 0, y:1, z:0) ในช่วง 1 วินาทีของคลิปแอนิเมชันของลูกบาศก์.
(1) ลงทะเบียนเหตุการณ์แอนิเมชันในช่วง 1 วินาทีของคลิปแอนิเมชันของลูกบาศก์.
- ฟังก์ชัน : เรียกใช้
- สตริง : ขึ้น
(2) ลงทะเบียนเหตุการณ์แอนิเมชันในช่วง 2 วินาทีของคลิปแอนิเมชันของลูกบาศก์.
- ฟังก์ชัน : เรียกใช้
- สตริง : ลง

- เมื่อเขียนเหตุการณ์อนิเมชันผ่าน C# ใน Unity ให้เขียนชื่อฟังก์ชันใน 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) หากคุณกดปุ่มเล่นเพื่อรัน คุณจะเห็นการแสดงผลในคอนโซลในขณะที่อนิเมชันของลูกบาศก์กำลังเล่นอยู่.

เล่นเสียงฝีเท้าด้วยการใช้เหตุการณ์อนิเมชันบนตัวละครในท้องถิ่น
เพื่อเพิ่มเหตุการณ์อนิเมชันไปยัง Animator ของตัวละคร ZEPETO เหตุการณ์ต้องถูกเพิ่มในระหว่างการทำงาน เมื่อสร้างตัวละคร
ตัวอย่างต่อไปนี้ใช้เหตุการณ์กับ Animation Clip เฉพาะของ Animator ผู้เล่นในท้องถิ่นในระหว่างการทำงาน และเล่นเสียงฝีเท้าขณะเกิดเหตุการณ์
1) สร้างสคริปต์ FootStepController ที่จะถูกนำไปใช้กับวัตถุ Animator ของผู้เล่นในท้องถิ่น FootStepController มีหน้าที่ในการเพิ่มเหตุการณ์การเคลื่อนไหวไปยัง Animator.
- สร้างโปรเจกต์ > สร้าง > ZEPETO > TypeScript และเปลี่ยนชื่อเป็น FootStepController.
- เขียนสคริปต์ตามด้านล่าง.
นำเข้า { AnimationEvent, Animator, AudioClip, AudioSource } จาก 'UnityEngine';
import { ZepetoScriptBehaviour } จาก 'ZEPETO.Script';
ส่งออกคลาส FootStepController เป็น ZepetoScriptBehaviour {
// เสียงที่ใช้สำหรับเอฟเฟกต์เสียงฝีเท้า
public footStepSound: AudioClip;
// แหล่งเสียงสำหรับเล่นเสียงฝีเท้า
private _zepetoAudio: AudioSource;
// เพิ่มเหตุการณ์อนิเมชันเพื่อกระตุ้นเสียงฝีเท้า
public AddAnimationEvent() {
// รับส่วนประกอบ Animator ที่แนบมากับ GameObject นี้
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("FootSteps!");
// เล่นเสียงฝีเท้าด้วย 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() เพิ่มเหตุการณ์อนิเมชันไปยังคลิปอนิเมชันที่ระบุ คุณต้องใส่ส่วนประกอบต่อไปนี้เป็นค่าพารามิเตอร์
- อนิเมเตอร์สำหรับผู้เล่นท้องถิ่น
- ชื่อคลิปอนิเมชันที่เหตุการณ์ถูกนำไปใช้
- อาร์เรย์ของเวลาอนิเมชันที่นำเหตุการณ์ไปใช้
- ใน newEvent ที่ลงทะเบียนด้วย AddAnimationClipEvent() จะมีการตั้งค่ารายการต่อไปนี้
(1) newEvent.time : เวลาแอนิเมชันเมื่อเหตุการณ์เกิดขึ้น ค่า 0 คือจุดเริ่มต้นของความยาวทั้งหมด และค่า 1 คือจุดสิ้นสุดของความยาวทั้งหมด.
(2) newEvent.functionName : ชื่อของฟังก์ชันที่เหตุการณ์เกิดขึ้น ใน Typescript ควรมีการกำหนดประเภทเป็น "Invoke".
(3) newEvent.stringParameter : ค่าพารามิเตอร์ที่ตั้งไว้ให้กับฟังก์ชันเมื่อเหตุการณ์เรียกใช้ฟังก์ชันนั้น Typescript จะระบุชื่อฟังก์ชันที่จะถูกเรียกใช้.
- เมื่อเกิดเหตุการณ์ ActivateFootSteps() จะถูกเรียกใช้และเสียงฝีเท้าจะถูกเล่น.

2) ตอนนี้สร้าง FootStepManager ที่เพิ่มคอมโพเนนต์ FootStepController ไปยังวัตถุ Animator ของผู้เล่นท้องถิ่นเมื่อผู้เล่นท้องถิ่นถูกสร้างขึ้นในระหว่างการทำงาน.
- โปรเจกต์ > สร้าง > 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;
// แนบสคริปต์ FootStepController ไปยัง GameObject ของ ZepetoAnimator
const footStepController = zepetoCharacter.ZepetoAnimator.gameObject.AddComponent<FootStepController>();
// ตั้งค่า footStepSound สำหรับ FootStepController
footStepController.footStepSound = this.footStepSound;
// เพิ่มเหตุการณ์อนิเมชันเพื่อกระตุ้นเสียงฝีเท้า
footStepController.AddAnimationEvent();
});
}
}- คำอธิบายสคริปต์
- หลังจากที่ FootStepManager ตรวจพบว่าผู้เล่นท้องถิ่นกำลังถูกเพิ่ม มันจะแนบสคริปต์ FootStepController ไปยัง GameObject ของ ZepetoAnimator ของผู้เล่นนั้น.
- FootStepController มีหน้าที่เพิ่มเหตุการณ์อนิเมชันที่เล่นเสียงฝีเท้า.
- สคริปต์ของฟังก์ชันที่ดำเนินการโดยเหตุการณ์อนิเมชันของ Animator ต้องถูกนำไปใช้กับวัตถุที่มีส่วนประกอบ Animator ที่เกี่ยวข้องอย่างเหมือนกัน.
- ดังนั้นคุณต้องค้นหา ZepetoAnimator.gameObject และนำสคริปต์ FootStepController ไปใช้เป็น AddComponent.
3) ใช้เสียงฝีเท้าไปที่ footStepSound ของ FootStepManager.

4) หากคุณกดปุ่มเล่นเพื่อรันมัน คุณจะเห็นว่าเสียงจะเล่นตามขั้นตอนของผู้เล่นท้องถิ่นเมื่อพวกเขาเดิน.

👍 เคล็ดลับ
- ZEPETO Basic Animator's Walk State ประกอบด้วยการผสมผสานและสถานะการเคลื่อนไหวหลายอย่าง.
- เนื่องจากตัวอย่างใช้เสียงเฉพาะกับสถานะ move_walk คุณสามารถปรับแต่ง AddAnimationClipEvent() และป้อนมันโดยตรงไปยังสถานะต่างๆ เช่น การเดินเร็วและการวิ่ง.
- เมื่อเสียงถูกนำไปใช้กับหลายสถานะการเคลื่อนไหว เสียงฝีเท้าอาจทับซ้อนกันเนื่องจากการผสมผสานการเคลื่อนไหว เพื่อแก้ไขปัญหานี้ ให้เขียนคำสั่งเงื่อนไขเพิ่มเติมเพื่อให้เสียงที่เกี่ยวข้องถูกเล่นเมื่อ AnimationEvent.animatorClipInfo.weight เท่ากับ 0.5.
❗️ ปัญหาที่ทราบ
- เมื่อดำเนินการตามสไตล์คู่มือการพัฒนา ข้อความแสดงข้อผิดพลาดต่อไปนี้อาจปรากฏขึ้น แต่จะไม่มีปัญหาในการดำเนินการ.
