Unity Recorder 360 圖片腳本

https://chatgpt.com/c/6a105596-2d3c-83a6-ba70-bf42ac44b975



Unity C# Script
using UnityEngine;
using System.Collections;

/// <summary>
/// UnityRecorderTurntable
/// 
/// 功能說明:
/// 配合 Unity Recorder 截圖工具,讓指定物件像「轉盤」一樣,每一幀旋轉固定角度,方便輸出 360 度物件旋轉連續圖片。
/// 1. 輸出商品 360 度旋轉圖
/// 2. 輸出角色或模型的環繞展示圖
/// 3. 製作 36 張、72 張等固定角度的圖片序列
/// 4. 搭配 Unity Recorder 輸出 PNG Sequence
/// 
/// 使用說明:
/// 1. 將此腳本檔案命名為:UnityRecorderTurntable.cs
/// 2. 將腳本掛在要旋轉的物件上,也可以建立一個空物件作為旋轉中心,再把模型放到空物件底下,然後把腳本掛在空物件。
/// 3. 在 Inspector 中設定:
///    - Total Images:總共要輸出的圖片張數,例如 36。
///    - Start Y:第一張圖片的 Y 軸角度,例如 180。
///    - Turn Direction:旋轉方向,-1 代表反向,1 代表正向。
///    - Wait Frames:開始旋轉前等待幾個 Frame,讓 Unity Recorder 進入錄製狀態。
/// 4. 建議 Unity Recorder 設定為輸出 Image Sequence,例如 PNG。
/// 5. 建議 Recorder 的錄製幀數與 Total Images 對應,避免錄到多餘畫面。
/// 
/// 注意事項:
/// 1. Total Images 不可以小於或等於 0。
/// 2. Turn Direction 如果設定為 0,物件將不會旋轉。
/// 3. 本腳本只負責旋轉物件,不會自動啟動或停止 Unity Recorder。
/// 4. 如果第一張角度沒有對準,可以調整 Wait Frames。
/// </summary>
public class UnityRecorderTurntable : MonoBehaviour
{
    [Header("1. 旋轉規格")]

    [Tooltip("總共要輸出的圖片張數。例如 36 代表每 10 度輸出一張。")]
    public int totalImages = 36;

    [Tooltip("第一張圖片的 Y 軸起始角度。例如 180 代表從 Y 軸 180 度開始拍攝。")]
    public float startY = 180f;

    [Tooltip("旋轉方向。-1 代表反向旋轉,1 代表正向旋轉。請避免設定為 0。")]
    [Range(-1, 1)]
    public int turnDirection = -1;

    [Header("2. 同步校準")]

    [Tooltip("開始旋轉前等待幾個 Frame,讓 Unity Recorder 先進入錄製狀態。若第一張沒有對準,可嘗試調整此數值。")]
    public int waitFrames = 2;

    [Header("3. 錄製設定")]

    [Tooltip("鎖定 Unity 的擷取幀率。搭配 Unity Recorder 輸出圖片序列時,可以讓每一幀穩定對應一張圖片。")]
    public int captureFramerate = 30;

    // 每一張圖片之間要旋轉的角度。
    // 例如 totalImages = 36,則每張間隔為 360 / 36 = 10 度。
    private float _stepSize;

    void Start()
    {
        // 檢查圖片數量是否正確。
        // 如果 totalImages 小於或等於 0,會造成 360 / totalImages 的除法錯誤。
        if (totalImages <= 0)
        {
            Debug.LogError("<color=red>【錯誤】Total Images 必須大於 0。</color>");
            return;
        }

        // 檢查旋轉方向。
        // turnDirection 為 0 時,雖然不會報錯,但物件會完全不旋轉。
        if (turnDirection == 0)
        {
            Debug.LogWarning("<color=orange>【警告】Turn Direction 目前是 0,物件將不會旋轉。</color>");
        }

        // 計算每一張圖片之間的旋轉角度。
        _stepSize = 360f / totalImages;

        // 設定物件的起始角度。
        // 第一張圖片理論上會使用這個角度。
        transform.eulerAngles = new Vector3(0f, startY, 0f);

        // 鎖定 Unity 的擷取幀率。
        // 這對 Unity Recorder 輸出圖片序列很重要,
        // 可以讓每一個 yield return null 對應到穩定的一幀。
        Time.captureFramerate = captureFramerate;

        // 啟動逐幀旋轉流程。
        StartCoroutine(RecordSequence());

        Debug.Log(
            $"<color=cyan>【初始化】Total Images: {totalImages}, Start Y: {startY}, " +
            $"Turn Direction: {turnDirection}, Wait Frames: {waitFrames}, Step: {_stepSize}</color>"
        );
    }

    /// <summary>
    /// 逐幀旋轉流程。
    /// 
    /// 流程說明:
    /// 1. 先等待 waitFrames,讓 Unity Recorder 進入錄製狀態。
    /// 2. 保持起始角度一幀,讓 Recorder 拍下第一張。
    /// 3. 從第 2 張開始,每一幀旋轉一次。
    /// 4. 直到完成 totalImages 張角度。
    /// </summary>
    IEnumerator RecordSequence()
    {
        // A. 熱身階段:
        // 等待 Unity Recorder 或截圖系統準備好。
        // 如果第一張圖片不是你想要的角度,可以調整 waitFrames。
        for (int i = 0; i < waitFrames; i++)
        {
            yield return null;
        }

        // B. 捕捉第一張:
        // 此時物件仍維持在 startY 角度。
        // yield return null 代表等待一幀,
        // 讓 Recorder 有機會拍下目前這個起始角度。
        yield return null;

        Debug.Log("<color=green>【第一張已拍完,開始旋轉】</color>");

        // C. 旋轉階段:
        // 從 i = 1 開始,因為 i = 0 已經是第一張起始角度。
        for (int i = 1; i < totalImages; i++)
        {
            // 計算目前這一張的目標 Y 軸角度。
            // 例如:
            // totalImages = 36
            // _stepSize = 10
            // startY = 180
            // turnDirection = -1
            // i = 1 時,targetY = 170
            // i = 2 時,targetY = 160
            float targetY = startY + (i * _stepSize * turnDirection);

            // 直接設定物件角度。
            // 這種方式比使用 Time.deltaTime 旋轉更適合逐幀輸出圖片,
            // 因為每一張圖片的角度都是固定且可預測的。
            transform.eulerAngles = new Vector3(0f, targetY, 0f);

            // 等待一幀,讓 Recorder 拍下這個角度。
            yield return null;
        }

        Debug.Log("<color=yellow>【完成】Turntable 圖片序列旋轉流程已結束。</color>");

        // 注意:
        // 本腳本不會自動停止 Unity Recorder,也不會自動停止 Play Mode。
        // 建議在 Unity Recorder 中設定固定錄製幀數,
        // 或在需要時自行加入停止 Play Mode 的程式。
    }
}