Máy trạng thái Animator
Assets/
Scenes/
Arena.unity
Scripts/
Animations/
đã có sẵnbài này thêm
Knight giờ đã đi được bằng PlayerMovement, nhưng nó trượt đi trong tư thế dang tay cứng đờ. Bài này cho nó đôi chân.
Code của bạn không bao giờ phát clip trực tiếp. Nó chỉ đặt giá trị cho tham số; Animator tự quyết định đó là clip nào và pha trộn giữa các clip.
Nhìn nhân vật bên trái diễn đúng trạng thái đang sáng bên phải — và ba tham số ở dưới cùng là tất cả những gì code của bạn đụng tới.
Dựng Animator Controller
- 1
Project: , đặt tên AC_Knight.
- 2
Chọn Knight, thêm component Animator, kéo AC_Knight vào ô Controller và Avatar của model vào ô Avatar.
- 3
Mở cửa sổ rồi kéo clip Idle vào — nó thành trạng thái mặc định màu cam.
- 4
Ở tab Parameters, thêm: Speed (Float), IsGrounded (Bool), Attack (Trigger).
Blend Tree tốt hơn tách riêng đi/chạy
- 1
Chuột phải trong Animator → Create State → From New Blend Tree. Đặt tên Locomotion và cho làm mặc định.
- 2
Bấm đúp vào nó. Đặt Blend parameter là Speed, rồi thêm ba clip: Idle ở 0, Walk ở 2, Run ở 6.
- 3
Giờ chỉ một số float là chuyển mượt idle → walk → run. Không cần mũi tên chuyển tiếp nào cho phần di chuyển.
Điều khiển từ code
using UnityEngine;
[RequireComponent(typeof(Animator))]
public class PlayerAnimator : MonoBehaviour
{
private Animator anim;
private CharacterController cc;
//dùng mã băm nhanh hơn chuỗi
private static readonly int SpeedHash = Animator.StringToHash("Speed");
private static readonly int GroundedHash = Animator.StringToHash("IsGrounded");
private static readonly int AttackHash = Animator.StringToHash("Attack");
void Awake()
{
anim = GetComponent<Animator>();
cc = GetComponent<CharacterController>();
}
void Update()
{
// chỉ lấy tốc độ ngang — rơi xuống không được trông như đang chạy
Vector3 flat = new Vector3(cc.velocity.x, 0f, cc.velocity.z);
anim.SetFloat(SpeedHash, flat.magnitude, 0.1f, Time.deltaTime); // độ làm mượt
anim.SetBool(GroundedHash, cc.isGrounded);
if (Input.GetMouseButtonDown(0))
anim.SetTrigger(AttackHash);
}
}Tham số thứ ba và tư của SetFloat là thời gian làm mượt và delta time: giá trị chuyển từ từ nên blend không bị giật.
Trigger là biến bool tự reset sau khi được dùng — đúng cho các hành động một lần như Attack.
Gọi StringToHash một lần trong trường static: tra cứu bằng chuỗi mỗi khung hình là lãng phí.
Thiết lập chuyển tiếp xử lý 90% chuyện hoạt ảnh bị khựng
Bỏ tick Has Exit Time ở mọi chuyển tiếp cần phản ứng theo người chơi (đánh, nhảy). Giữ tick cho hoạt ảnh bắt buộc chạy hết.
Transition Duration 0.1–0.2 giây cho cảm giác nhạy. Trên 0.3 giây thì nhân vật trông như say rượu.
Interruption Source → Current State cho phép đòn đánh mới cắt ngang đòn cũ thay vì xếp hàng chờ.
Animation Event — trúng đúng lúc vung tay
Sát thương không nên tính lúc bấm nút; nó phải tính lúc kiếm thật sự vung tới. Animation Event gọi một hàm tại đúng khung hình bạn chọn trong clip.
//đặt cùng GameObject với Animator
public void OnAttackHit() // chọn tên này ở hàng Events của clip
{
Debug.Log("khung trúng đòn");
//gây sát thương cho địch trong tầm
}