はじめに

本課題は[Roblox ムービー演出の作り方(4) Scriptでの処理〜分解編〜]の続きとして、用意したアニメーションのフレームデータを再生する処理を解説します。
MoonAnimator2でのアニメーションの作成方法等については、[Roblox ムービー演出の作り方(1) MoonAnimator2][Roblox ムービー演出の作り方(2) データ構造とエクスポート]をご確認ください。

下準備

今回はSetup関数で用意したデータを元にアニメーションを再生するためのPlay関数と、マウスクリック時にPlay関数を呼ぶ処理を用意します。
Play関数にはパラメータとして、Play関数の呼び出し元がアニメーション終了を感知するためのコールバックを用意しています。
今回の処理はLocalScriptのSetup関数の呼び出し後に記載するようにします。

再生

Play関数

まずはカメラのタイプとCFrameのデータを、用意した変数に退避してからカメラのタイプを変更します。①②
これはアニメーション終了時にカメラの位置を戻したり、カメラをScriptにて操作するための処理になるため、アニメーション内でカメラの位置が変わらない場合は必要ありません。

次にRunService.RenderSteppedを使用して1フレーム毎に各ターゲットに対してCFrameのデータを適用していきます。③
RunService.RenderSteppedでは、コネクトされた処理が、フレームがレンダリングされる前に毎回実行されます。
そのため、RunService.RenderSteppedの毎実行時にパラメータとして「前のフレームから経過した時間 (秒単位)」が渡されるので、現在のフレームを算出します。④
今回は定数を60としていますが、こちらの数値はアニメーションのFPSによって変更してください。

現在のフレームが算出できたら、アニメーションの総フレーム数と比較し、上回っている場合は退避したカメラ情報を戻し、Play関数にアニメーション終了を通知し、RunService.RenderSteppedからコネクトを外します。⑤

もし、現在のフレームがアニメーションの総フレーム数に満たない場合、各ターゲットに対して現在のフレームのCFrameのデータを代入し移動します。⑥
この時に気をつけなければいけないのが、各ターゲットの種類になります。
Robloxではキャラクターやカメラ、モデルなどの種類によってCFrameの設定方法が異なります。今回のアニメーションの場合は、キャラクターとカメラだけだったので、各ターゲットの配下にHumanoidRootPartがあるかを判断していますが、もしアニメーションでモデルを使用している場合は、CFrameの設定方法を分岐する必要があります。

マウスクリック時の処理

Play関数を用意したら、それを呼び出す処理が必要です。
今回はマウスクリック時に、アニメーションが再生中でなければPlay関数を呼び出すようにしています。
今回のアニメーションを動かすと以下の様になります。

ここまでの手順のサンプルを以下に用意したので、コメントも含めて参考にしてみてください。

StartPlayer/StarterCharacterScripts/LocalScript

-- 実行関数
function Play(completed)
    -- ①カメラのTypeと、現在のカメラのCFrameを取得
    currentCameraType = workspace.CurrentCamera.CameraType
    currentCameraCFrame = workspace.CurrentCamera.CFrame

    -- ②カメラのタイプを変更
    workspace.CurrentCamera.CameraType = Enum.CameraType.Scriptable

    ------------------------------------------------------
    -- ※キャラクターのアニメーションを別途再生する場合はここに挿入
    ------------------------------------------------------

    -- RenderStepped毎にフレームを計算してアニメーションを再生
    local frameTime = 0
    -- ③レンダーステップ毎に処理を実施
    connection = RunService.RenderStepped:Connect(function(step)
        -- ④開始からの現在のフレームを計算
        frameTime += (step * 60)
        local currentFrame = tonumber(math.ceil(frameTime))

        -- ⑤現在のフレームが総フレーム数を超えたら終了
        if currentFrame > totalFrameCount then
            -- カメラタイプを元に戻す
            workspace.CurrentCamera.CameraType = currentCameraType
            -- カメラ位置を元に戻す
            workspace.CurrentCamera.CFrame = currentCameraCFrame

            -- 呼び出し元に終了を知らせる
            completed()

            -- コネクトを外す
            connection:Disconnect()
            connection = nil
        else
            -- ⑥ターゲット毎に処理
            for i, animationData in pairs(animationDataArray) do
                -- 「HumanoidRootPart」があるかで処理を分岐
                if animationData.isHaveHRP then
                    animationData.target.HumanoidRootPart.CFrame = animationData.frameArray[currentFrame]
                else
                    animationData.target.CFrame = animationData.frameArray[currentFrame]
                end
            end
        end
    end)
end

-- マウスの左クリック時の処理
mouse.Button1Down:Connect(function()
    -- アニメーション中の場合はリターン
    if isPlayingAnimation then
        return
    end

    isPlayingAnimation = true

    Play(function()
        isPlayingAnimation = false
    end)
end)

最後に

今回は3つの記事にてMoonAnimatior2で作成されたアニメーションをScriptにて再生する方法を解説しましたが、今回のサンプルでは各ターゲット自身のアニメーションは再生されず位置と向いている方向のみでした。

もし、キャラクター自身のアニメーションも再生したい場合は、[Roblox ムービー演出の作り方(2) データ構造とエクスポート]にて記載されていた各ターゲット配下のAnimSaves内のデータを編集して公開し、上記Script内の「※キャラクターのアニメーションを別途再生する場合はここに挿入」と記載された箇所で呼び出してもらえば、今回の位置情報等と一緒に再生されますので試してみてください。
キャラクターのアニメーションについては公式のドキュメントにまとめられています。