Rung máy quay
Thuộc phần Vật lý và lối chơi trong hành trình Unity của Coddy. Bài học 50 trên 71.
Rung lắc là một đợt dịch chuyển ngẫu nhiên ngắn: trong vài phần mười giây, camera ở một vị trí ngẫu nhiên gần vị trí nghỉ, mỗi khung hình lại có một vị trí mới, rồi trở về. Coroutine rất phù hợp vì nó chạy qua nhiều khung hình và tự kết thúc. Camera này rung lắc khi một tảng đá rơi xuống, một script khác gọi BoulderLanded(); tệp bắt đầu bằng using System.Collections; để dùng IEnumerator:
public float strength = 0.2f;
public float duration = 0.4f;
Vector3 rest;
void Start()
{
rest = transform.localPosition;
}
public void BoulderLanded()
{
StartCoroutine(Shake());
}
IEnumerator Shake()
{
float elapsed = 0f;
while (elapsed < duration)
{
transform.localPosition = rest + Random.insideUnitSphere * strength;
elapsed += Time.deltaTime;
yield return null;
}
transform.localPosition = rest;
}Random.insideUnitSphere * strength là một độ lệch ngẫu nhiên có độ dài tối đa bằng strength theo mọi hướng, còn yield return null chọn một độ lệch mới ở khung hình tiếp theo. Cộng Time.deltaTime ở mỗi lượt sẽ tính thời gian thực bằng giây, nên hiệu ứng rung lắc kéo dài duration bất kể tốc độ khung hình. Dòng cuối đưa camera trở lại vị trí cũ; nếu thiếu dòng này, camera sẽ nằm yên tại vị trí mà độ lệch cuối cùng đưa nó đến.
Ở mỗi khung hình, Unity chạy mọi Update(), sau đó chạy các coroutine đang chờ yield return null, rồi chạy mọi LateUpdate(). Vì vậy, camera bám theo đặt vị trí trong LateUpdate() sẽ ghi đè mọi thay đổi do hiệu ứng rung lắc tạo ra. Rung lắc localPosition sẽ tránh được điều này nếu camera là con của một đối tượng rỗng đảm nhiệm việc bám theo: đối tượng cha di chuyển, còn camera rung lắc quanh vị trí của nó bên dưới đối tượng cha.
Thử thách
Trung bìnhLàm camera rung khi nhấn Space.
- Thêm trường
Vector3 shake;và đặttransform.position = player.position + offset + shake;trongLateUpdate(). - Trong
Shake(), khielapsed < duration:shake = Random.insideUnitSphere * strength;, cộngTime.deltaTimevàoelapsed, rồi dùngyield return null;. - Sau vòng lặp, đặt
shake = Vector3.zero;.
Nhấn Chơi, chạy và nhấn Space: góc nhìn rung khi bám theo. Sau đó nhấn Kiểm tra.
Tự làm thử
using System.Collections;
using UnityEngine;
public class ShakeFollow : MonoBehaviour
{
public Transform player;
public Vector3 offset = new Vector3(0, 4, -8);
public float strength = 0.3f;
public float duration = 0.4f;
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
StartCoroutine(Shake());
}
}
void LateUpdate()
{
transform.position = player.position + offset;
}
IEnumerator Shake()
{
// Rung camera trong duration giây, lệch tối đa strength so với vị trí bám theo.
yield return null;
}
}
Tất cả bài học trong Vật lý và lối chơi
1Rigidbody
Trọng lực và khối lượngĐẩy bằng AddForceNhảy bằng xung lựcFixedUpdate cho vật lýVận tốcVật thể động họcÔn tập: Bệ phóng4Coroutine
InvokeInvokeRepeating, CancelInvokeCoroutine đầu tiên của bạnVòng lặp trong CoroutineDừng CoroutineÔn tập: đếm ngược10Dự án: Thoát khỏi đấu trường
Đấu trườngThợ săn2Va chạm
OnCollisionEnterMình đã va chạm với gì?Vỡ khi va chạmĐứng trên mặt đấtĐộ nảy và ma sátHình dạng colliderÔn tập: Tường có thể phá vỡ5Dự án: Cuộc đua thu thập xu
Quả bóng lănThu thập xuTự luyện tập: Playground Unity