# Script chuyển động

> Tạo chuyển động mà thư viện chưa có bằng một đoạn mã nhỏ — nảy, rung, lắc, bay vòng, đám đông lệch nhịp, người thở, gật đầu. AI viết script từ một câu tả, kéo thanh trượt để chỉnh, đổi thành keyframe khi cần.
Nguồn: https://studio.adayroi.online/docs/script-chuyen-dong

Thư viện hành động có sẵn rất nhiều, nhưng luôn có những chuyển động nó chưa có: **đèn nhấp nháy theo nhịp**, **hộp nảy 3 lần rồi nhỏ dần**, **mười quả bóng xoay lệch pha nhau**. Làm tay từng keyframe cho những thứ đó rất mệt. **Script chuyển động** cho bạn tả chuyển động bằng một đoạn mã nhỏ — hoặc nhờ AI viết hộ — rồi app tự tính ra chuyển động.

Mở bằng nút **Script** trên thanh công cụ, biểu tượng **{ }** ở cột phải, hoặc menu **Render → Script chuyển động…**.

## Cách dùng nhanh

1. **Chọn vật** trên sân khấu. Chọn nhiều vật (giữ Ctrl) nếu muốn cả nhóm cùng chuyển động; thứ tự bạn chọn là thứ tự script đếm chúng.
2. Đặt **đầu đọc** ở giây muốn chuyển động bắt đầu.
3. Chọn một **mẫu có sẵn** rồi bấm **Thêm**, hoặc gõ vào ô **AI viết script** một câu như *"các hộp nảy 3 lần rồi nhỏ dần, lệch nhịp nhau"* rồi bấm **Viết script mới**.
4. Script chạy ngay. Trạng thái **Đã lưu** nghĩa là chuyển động đã sẵn sàng; bấm phát để xem.
5. Kéo các **thanh trượt tham số** (độ cao, tốc độ, số lần…) — script tự chạy lại sau mỗi lần chỉnh.

Trên dòng thời gian, mỗi vật có script sẽ có một **dải xanh ngọc** chạy từ lúc script bắt đầu đến lúc kết thúc. Dải **nét đứt** là script chưa chạy. Bấm vào dải để mở lại cửa sổ Script.

## Mẫu có sẵn

| Mẫu | Dùng cho |
|---|---|
| Nảy rồi dừng | Vật nảy vài lần, thấp dần rồi đứng yên |
| Rung | Rung lắc mạnh rồi tắt dần — động đất, va chạm |
| Lắc qua lại | Biển hiệu, đèn treo đung đưa |
| Phập phồng | Phình to rồi thu nhỏ theo nhịp |
| Bay vòng tròn | Bay quanh một điểm |
| Lơ lửng | Trôi nhẹ lên xuống như bay trong không khí |
| Sóng đám đông | Nhiều vật nhấp nhô lần lượt như làn sóng |
| Bật xuất hiện | Từ nhỏ xíu bật lên kích thước thật |
| Thở (người) | Ngực và vai nhô nhẹ theo nhịp thở |
| Gật đầu (người) | Gật đầu vài lần |

## Chỉnh một script

Bấm tên script trong danh sách để mở phần chỉnh:

- **Vật được di chuyển** — bấm **Dùng … vật đang chọn** để đổi sang các vật đang chọn.
- **Bắt đầu** và **Độ dài** tính bằng giây; nút đồng hồ đặt điểm bắt đầu ở đầu đọc.
- **Hạt ngẫu nhiên** — đổi số này để có một biến thể khác của cùng script (ví dụ một kiểu rung khác). Cùng một số thì kết quả luôn giống hệt nhau.
- **Giữ vị trí cuối** — bật thì hết script vật vẫn ở chỗ script để lại; tắt thì vật trở về chuyển động gốc của nó.
- **Bật** — tắt tạm script mà không xoá.
- **Mã script** — sửa trực tiếp rồi bấm **Áp dụng mã** (hoặc Ctrl+Enter).
- **Sửa script đang mở** (trong ô AI) — tả điều muốn đổi, AI sửa script hiện tại.

## Thành keyframe

Bấm **Thành keyframe** để đổi kết quả của script thành keyframe thường trên dòng thời gian, rồi bỏ script. Sau đó bạn chỉnh tay từng keyframe như bình thường. Script cử động **khớp người hoặc nét mặt** (Thở, Gật đầu…) được giữ dạng script vì những chuyển động đó không phải là keyframe vị trí.

## Script và vật lý

Chuyển động của script được tính **trước** vật lý, nên vật lý "thấy" được nó: một hộp được script quay vòng sẽ va thật vào những vật đang mô phỏng xung quanh. Khi bạn đổi script, vật lý tự mô phỏng lại.

## Chia sẻ script

- Nút **tải về** trong phần chỉnh lưu script ra một tệp **.json** (chỉ mã và tham số, không kèm cảnh).
- Nút **mở tệp** cạnh **Thêm** nhập tệp script người khác gửi.

## Lưu script lên tài khoản

Script có thể lưu trên tài khoản adayroi studio để dùng lại ở máy khác hoặc quản lý trên web:

- Trong app, mở một script rồi bấm **Đưa lên tài khoản**. Gửi lại cùng một đoạn mã thì app chỉ cập nhật, không tạo bản trùng.
- Mục **Trên tài khoản** trong cửa sổ Script liệt kê các script đã lưu. Chọn vật rồi bấm **Thêm** để đưa một script vào cảnh.
- Trên web, vào cổng tài khoản → **adayroi studio → Script chuyển động** để **tải tệp .json lên** (một hoặc nhiều tệp), **viết script ngay trên trang**, xem mã, tải về hoặc xoá. Nút **Mở trên web** trong app mở thẳng trang này.

Script lấy từ tài khoản chưa chạy trên máy này thì vẫn chờ bạn bấm **Đã xem, chạy**, giống tệp của người khác — vì bất kỳ ai biết mật khẩu đều có thể tải tệp lên tài khoản.

## An toàn

Script chạy trong một **hộp cát** riêng: không vào được mạng, không đọc được tệp trên máy, không thấy giờ hệ thống, và bị dừng nếu chạy quá 8 giây. Kết quả được **lưu lại**, nên khi phát, tua hay xuất video app không chạy lại mã.

Script đến từ **phim hoặc tệp của người khác** không bao giờ tự chạy trên máy bạn. Phim vẫn phát kết quả đã lưu sẵn; script hiện nhãn **Cần xem lại** kèm cảnh báo. Đọc mã, nếu tin thì bấm **Đã xem, chạy**.

## Viết script bằng tay

Script là JavaScript có một hàm `motion(ctx)`, được gọi cho **mỗi khung hình** (30 khung/giây) và **mỗi vật**:

```js
var params = {
  height: { label: 'Độ cao (m)', min: 0.1, max: 3, default: 0.8, step: 0.05 },
};
function motion(ctx) {
  return { position: { y: Math.abs(Math.sin(ctx.progress * Math.PI * 3)) * ctx.params.height * (1 - ctx.progress) } };
}
```

- `ctx.t` giây từ lúc script bắt đầu, `ctx.progress` từ 0 đến 1, `ctx.index` số thứ tự vật, `ctx.count` số vật, `ctx.phase` thứ tự vật đổi ra 0–1 (dùng để lệch nhịp), `ctx.target` tên, loại và vị trí ban đầu của vật, `ctx.params` giá trị các thanh trượt.
- Trả về `position` (mét, cộng thêm), `rotation` (radian, cộng thêm), `scale` (nhân), với người còn có `pose` (góc khớp) và `face` (biểu cảm 0–1). Trả về `null` để không làm gì ở khung đó.
- Khai báo `var params = { … }` để có thanh trượt.
- Có sẵn các hàm `clamp`, `lerp`, `smoothstep`, `easeOutBack`, `easeOutElastic`, `bounce`, `spring`, `noise` và `log(...)` (in ra mục **Nhật ký**). `Math.random()` đi theo **hạt ngẫu nhiên** nên kết quả lặp lại được.

Trợ lý AI ngoài app (qua MCP) cũng thêm, sửa, xoá script được bằng trường `motionScripts` của lệnh `director.update`.
