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