🕹️

【Roblox】ステートマシンを使って状態遷移を管理する

2024/07/03に公開

はじめに

こんにちは、まつさこ です。

今回は、Roblox Studio でゲームの中での状態遷移を管理するための ステートマシン について紹介します。
RoduxRoblox State Machine など、ステートを管理するプラグインやライブラリはいくつか存在しますが、今回は簡単なステートマシンの仕組みを自作してみます。

ステートマシンとは

ステートマシン(State Machine)は、プログラムの中で状態を管理するための仕組みです。ゲーム開発においては、プレイヤーの状態(立ち、歩き、走り、ジャンプなど)や、ゲームの状態(タイトル画面、ゲーム中、リザルト画面など)を管理するために利用されます。

ステートマシンは、以下の要素で構成されます。

  • 状態(State):ゲーム内の状態を表す。例えば、Idle(アイドル状態)、Walk(歩行状態)、Run(走行状態)など。
  • 遷移(Transition):状態間の移り変わりを表す。例えば、IdleからWalkへの遷移、WalkからRunへの遷移など。

今回紹介するステートマシンはかなり簡易的なものです。オブジェクトやゲーム進行の状態を管理・遷移させ、それに応じて処理を行うための基本的な仕組みを実装します。

ステートマシンについて詳しくは以下の記事も参考にしてみてください。

ステートマシンの実装

それでは実際にRoblox Studioでステートマシンを実装していきます。

まず、ステートマシンの基盤は Module Script として作成します。以下のようなスクリプトを作成しましょう。

local StateMachine = {}
StateMachine.__index = StateMachine

function StateMachine.new(states)
	local self = setmetatable({}, StateMachine)
	self.states = states or {}
	self.currentState = nil
	self.stateChangedCallbacks = {}
	return self
end

function StateMachine:changeState(newState)
	if not table.find(self.states, newState) then
		error("Invalid state: " .. newState)
	end
	self.currentState = newState
	self:_onStateChanged(newState)
end

function StateMachine:_onStateChanged(newState)
	if self.stateChangedCallbacks[newState] then
		for _, callback in ipairs(self.stateChangedCallbacks[newState]) do
			callback()
		end
	end
end

function StateMachine:onStateChanged(state, callback)
	if not self.stateChangedCallbacks[state] then
		self.stateChangedCallbacks[state] = {}
	end
	table.insert(self.stateChangedCallbacks[state], callback)
end

return StateMachine

このスクリプトでは、StateMachine クラスを定義しています。StateMachine.new(states) で新しいステートマシンを作成し、StateMachine:changeState(newState) で状態を変更します。また、StateMachine:onStateChanged(state, callback) で状態が変更された際に実行するコールバック関数を登録します。

この Module Script は、Replicated Storage 内に配置しておきます。

次に、ステートマシンを使って状態を管理するスクリプトを作成します。例として、ゲーム進行の状態を管理するスクリプトを作成してみましょう。

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local StateMachine = require(ReplicatedStorage:WaitForChild("StateMachine"))

local gameStates = {
    "Title",
    "Playing",
    "Result"
}

local gameStateMachine = StateMachine.new(gameStates)

gameStateMachine:onStateChanged("Title", function()
    print("Game state changed to Title")
end)

gameStateMachine:onStateChanged("Playing", function()
    print("Game state changed to Playing")
end)

gameStateMachine:onStateChanged("Result", function()
    print("Game state changed to Result")
end)

gameStateMachine:changeState("Title")
gameStateMachine:changeState("Playing")
gameStateMachine:changeState("Result")

このスクリプトでは、StateMachine を使ってゲーム進行の状態を管理しています。gameStates にはゲームの状態を表す文字列が格納されており、gameStateMachine にはこの状態を管理するステートマシンが作成されます。

gameStateMachine:onStateChanged(state, callback) で、各状態に対するコールバック関数を登録し、gameStateMachine:changeState(newState) で状態を変更します。状態が変更されると、登録されたコールバック関数が実行されます。

スクリプトを実行すると、以下のような出力が得られるはずです。

Game state changed to Title
Game state changed to Playing
Game state changed to Result

実際に使用する際は、 changeState メソッドを呼び出すタイミングや、コールバック関数内で行う処理を適切に設計してください。

これで、簡単なステートマシンの実装が完了しました。ゲーム進行の状態遷移を管理するだけでなく、プレイヤーやオブジェクトの状態管理にも応用できるので、ぜひ活用してみてください。

まとめ

今回は、Roblox Studio でステートマシンを使って状態遷移を管理する方法について紹介しました。ステートマシンを使うことで、ゲーム内の状態を効率的に管理し、処理を行うことができます。

ぜひ、自分のゲームに取り入れてみてください。

読んでくださりありがとうございました🤗

moze テックブログ

Discussion