[Roblox] ゲーム内でカットシーンを入れる方法
こんにちは! Asterです!
これはIwaken Lab. Advent Calendar 2024の3日目の記事です。
本日は、ゲームをよりワクワクしてもらうための工夫「カットシーン」をどうやって入れるのかを記事にしていこうかなと思います。
カットシーンの例
今回はシンプルにPartを触ったらキャラクターの前にカメラが前に来るカットを作成します。
Partに触ってカットシーンまでの流れ
カットシーンの前のPartに触る処理を書いていきます。今回は、分かりやすいように「ProximityPrompt」という触る処理などによく使われるものを使っていきます。
Partの子にProximityPromptをいれてください。
ProximityPromptを入れた状態でPlayをして、そのPartに近づくと以下のようにPartにGuiが表示されるようになります。
Defaultでは、「E Button」を押すとイベント発火されるようになります。
また、InteractというAction Textとなっています。
これらを変更するのは、Propertiesから変更できます。
それでは、E Buttonを押したら、カットシーンに流すためのスクリプトを書いていきましょう。
以下のようにScriptを追加してください。
まずは、ProximityPromptが動くかどうかの確認です。以下のようにコードを書いてください。
追加した状態で、Partに近づき、E Buttonを押すと「Action cut scene」と出力されると思います。
ActionCutSceneにカットシーンへのつなぎを書いていきます。
local ProximityPrompt = script.Parent
local function ActionCutScene()
print("Action cut scene")
end
ProximityPrompt.Triggered:Connect(function(Player)
ActionCutScene()
end)
では、早速 ActionCutSceneにカットシーンへのつなぎを書いていきましょう。
「カットシーンということだから、カメラを移動させればいいよね?」ということで、Workspace上のカメラを呼び出して、ActionCutSceneにカメラ移動のコードを書いても動きません。
基本 Robloxでは、個々のキャラクターを動かした際にキャラクターにカメラが追従するようになっています。このカメラはClient側で追従されており、Server側からでは動きません。
先ほどのProximityPromptの処理は、Server側で行っているため、動かないということです。
そのため、Server側ではなく、Client側で処理を実行する必要があります。
ここで使うのが、「Remote Event」です。
この「Remote Event」は、Server-Client間をつなげてくれるものとなります。
ついでに話すと「Bindable Event」というものもありこれは、Server-Server間、Client-Client間をつなげてくれるものがあります。
この「Remote Event」を使って、ServerからClient側に処理を渡していきましょう。]
まず、ReplicatedStorageの中にEventsフォルダーを用意して(見やすくするため)、その下にRemoteEventを追加してください。名前は、ActionCutSceneEvent(何か分かりやすくするため)にしましょう。
次に、先ほどのコードを以下のように書き換えてください。
local ProximityPrompt = script.Parent
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Events = ReplicatedStorage.Events
local ActionCutSceneEvent = Events.ActionCutSceneEvent
local function ActionCutScene(Player)
print("Action cut scene")
ActionCutSceneEvent:FireClient(Player)
end
ProximityPrompt.Triggered:Connect(function(Player)
ActionCutScene(Player)
end)
追加した部分としては、ActionCutSceneEventを宣言する点と、そのActionCutSceneEventをProximityPromptのEventを発火させたPlayerにEventを発火させる部分を追加しました。
これで、Client側に処理を渡すことが出来ました。
次にClient側での処理を書いていきましょう。
StarterPlayer下のStarterPlayerScripts下に「local script」を追加しましょう。
名前は、ActionCutSceneとしています。
実際Client側に処理が流れているか以下のコードで確認しましょう。
追加した状態で、Partに近づき、E Buttonを押すと「Action cut scene (Client)」と出力されると思います。
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Events = ReplicatedStorage.Events
local ActionCutSceneEvent = Events.ActionCutSceneEvent
ActionCutSceneEvent.OnClientEvent:Connect(function()
print("Action cut Scene (Client)")
end)
次に実際にカメラ移動をしていきましょう。
流れとしては、カメラの追従をやめて、カメラを思い通りに動かすようにしなければならないです。
カメラはDefautだと、CameraTypeが「Custom」となっているため、それがキャラクターに対して追従させています。そのため、このCameraTypeを「Fixed」に変更して上げるとカメラがその場で止まります。
この状態で、CameraのCFrameを変更することで、Characterの前にカメラが移動します。
では、実際にCameraを動かして行きましょう。
Cameraを動かすときに、ScriptからPositionを決めて、それで移動させるのもいいですが、それだと細かい調整がめんどくさいので、別Partを作って、そのPositionを使う形で行います。
このように別Partを白いPartの前に持ってきてください。(このとき黄色PartのAnchorをTrueにしておいてください。)
白いPartはTargetPart,黄色のPartは、CutCameraという名前に変更します。
実際にカメラを動かしていきます。
以下のコードに修正してください。このようにすることで、Partの前にカメラが移動するようになりました。
--Server Script
local ProximityPrompt = script.Parent
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Events = ReplicatedStorage.Events
local ActionCutSceneEvent = Events.ActionCutSceneEvent
local CutCamera = workspace.CutCamera
local TargetPart = workspace.TargetPart
local function ActionCutScene(Player)
print("Action cut scene")
ActionCutSceneEvent:FireClient(Player,CutCamera,TargetPart)
end
ProximityPrompt.Triggered:Connect(function(Player)
ActionCutScene(Player)
end)
--Client Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Events = ReplicatedStorage.Events
local ActionCutSceneEvent = Events.ActionCutSceneEvent
local camera = workspace.CurrentCamera
local function MoveCamera(CutCamera,TargetPart)
camera.CameraType = Enum.CameraType.Fixed
camera.CFrame = CFrame.new(CutCamera.Position,TargetPart.Position)
end
ActionCutSceneEvent.OnClientEvent:Connect(function(CutCamera,TargetPart)
MoveCamera(CutCamera,TargetPart)
print("Action cut Scene (Client)")
end)
このままでは、カットシーンを入れた後にカメラがその場に残ってしまい、ゲームの続きを行うことが出来ません。そのため、CameraのTypeを戻す必要があります。また、CameraのCFrameもカットシーン前に戻しておくのがいいでしょう。
以下のコードにすると、5秒経ったら、カメラが戻るようになります。
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Events = ReplicatedStorage.Events
local ActionCutSceneEvent = Events.ActionCutSceneEvent
local camera = workspace.CurrentCamera
local function MoveCamera(CutCamera,TargetPart)
local CurrentCameraCFrame = camera.CFrame
camera.CameraType = Enum.CameraType.Fixed
camera.CFrame = CFrame.new(CutCamera.Position,TargetPart.Position)
wait(5)
camera.CameraType = Enum.CameraType.Custom
camera.CFrame = CurrentCameraCFrame
end
ActionCutSceneEvent.OnClientEvent:Connect(function(CutCamera,TargetPart)
MoveCamera(CutCamera,TargetPart)
print("Action cut Scene (Client)")
end)
これにより、ゲーム中にカットシーンを入れるための基盤が出来ました。
このMoveCameraに対して、TweenServiceを使って、カメラワークを追加するもよし、キャラクターのアニメーションを追加するもよしです。
自身にあったカットシーンを作っていただけたらと思います。
これにて、「ゲーム内でカットシーンを入れる方法」は終わりになります。
現在Asterが開発をしている「Arcadia : Rise of the Champion」にも是非遊びに来ていただけたらと思います!
Xの方でもRobloxに関して発信していますので、フォローしていただけたらと思います!
Iwaken Lab. Advent Calendar 2024の4日目は、ヘリンさん!お楽しみに!!
Discussion