はじめに
本課題は[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内の「※キャラクターのアニメーションを別途再生する場合はここに挿入」と記載された箇所で呼び出してもらえば、今回の位置情報等と一緒に再生されますので試してみてください。
キャラクターのアニメーションについては公式のドキュメントにまとめられています。