この手順では、リソース パッケージを作成および使用してメモリ内外の異なるレベルのコンテンツを切り替えるプロセスについて説明します。
最終的にはパッケージへのリソースの分割に異なる方法を使用することを計画している場合でも、まずこの手順に従い、パッケージ化システムがどのように機能するかに慣れておくこともできます。
この手順では、ゲーム内で交互に切り替える 2 つの新しいレベルを作成します。
empty テンプレートから新しいプロジェクトを開始します。
content_level_1 という名前のルート レベルに新しいフォルダを作成します。
この content_level_1 フォルダにいくつかの新しいアセットを読み込みます。
新しいレベルを作成し、content_level_1 フォルダに追加するいくつかのアセットをそのレベルに配置して、content_level_1/level_1.level という名前でレベルを保存します。
2 番目のレベルに手順 2 ~ 4 を繰り返します。ただし、名前は content_level_2 にします。異なるレベルがいつロードされたかが分かるように、異なるコンテンツのセットを読み込んで配置します。より大きなユニットを含めることで片方のレベルをもう片方のレベルよりも著しく重くした場合、後でリソースの切り替えが機能していることが確認しやすくなります。
script/lua/project.lua ファイルを編集します。行 12 で、
basic = "content/levels/basic"
を次のように変更します
basic = "content_level_1/level_1"
これにより、プロジェクトを実行してメイン メニューから START を選択したときに、テンプレートに付属する既製の基本レベルの代わりにメイン メニューに新しい level_1 が読み込まれるようになりました。
この手順では、プレイヤーに応じて 2 つのレベルを切り替えるために基本的なレベル フローを設定します。分かりやすくするために、これらの指示はプレイヤーが[l]キーを押したときに変更をトリガするようにします。必要であれば他のトリガを使用することもできます。
level_1 を開き、Level Flow Editor を開きます。
グラフに Input > Keyboard Button ノードを追加します。Button Name 値を、変更をトリガするキーに設定します。たとえば、上の画像では l を使用してします。
グラフに Level > Change Level ノードを追加します。Name 値を、content_level_2/level_2.level を示すように設定します。
Keyboard Button ノードの Pressed 出力を、Change Level ノードの In ポートに接続します。
レベルを保存します。
上記のすべての手順を level_2 に繰り返します。ただし、Change Level ノードは level_1 に戻るように設定します。
レベルをテストするか、プロジェクトを実行してメイン メニューから START を選択します。[l]キーを押すことで 2 つのコンテンツ レベルを切り替えられるようになっています。
設定して機能している 2 つのレベルが用意できたので、次はすべてのプロジェクト リソースの自動ロードを停止して、他のリソース パッケージをこの組み合わせに導入できるようにします。
Script Editor パネル、または好みのテキスト エディタでプロジェクトの boot.package を開きます。ファイル上部にある自動ロードの行、
* = ["*"]
を次のように変更します
* = ["core/*"]
これで、プロジェクトを実行したときに、コア リソースのみが起動時にロードされるようになりました。レベルとそのコンテンツはメモリ内にありません。プロジェクトを実行してメイン メニューの START を押そうとすると、次のようなエラーが表示されます。
basic_project_for_packages / Lua: core/appkit/lua/simple_project.lua:101: Level not loaded: content_level_1/level_1
エディタで Test Level を実行すると、レベルが正常にロードされることに注意してください。Test Level モードでは、リソースは必要になったときに常に自動ロードされます。リソース パッケージのロードを実際にテストするには、Run Project を使用する必要があります。
この手順では、各コンテンツ レベルで使用されるリソースを収集する 2 つのパッケージを作成します。
content_level_1/level_1.package という名前の新しいテキスト ファイルを作成します。
ファイルに次の行を配置します。
* = ["content_level_1/*"]
この行により、プロジェクトの content_level_1/ フォルダ内にあるすべてのタイプのすべてのリソースがこのパッケージに含まれるようになります。
content_level_2 に同じ手順を繰り返します。
boot.package に戻り、新しい .package リソース ファイルへの参照を追加します。
package = [ "content_level_1/level_1" "content_level_2/level_2" ]
.package ファイル形式の詳細については、「リソース パッケージを定義する」を参照してください。
それぞれ独自のリソース パッケージを持つ 2 つのレベルが作成されました。この手順では、このレベルのリソース パッケージをメモリに最初にロードするようレベル ロード コードを更新します。また、レベルとそのリソースが不要になった場合に、リソース パッケージをメモリからロード解除するよう、レベルの「ロード解除」も更新します。
empty テンプレート プロジェクトでは Appkit の SimpleProject Lua クラスが使用されます。既定では、SimpleProject はロード レベルとロード解除レベルを処理しますが、必要なリソースはメモリ内に既に存在していて使用できることが前提となります。パッケージのロードおよびロード解除のサポートを組み込むには、SimpleProject コードを拡張する必要があります。
Appkit および SimpleProject クラスの背景については、「テンプレートから Lua を開始する: Appkit を使用する」のトピックも参照してください。
core/appkit/lua/simple_project.lua ファイルを、プロジェクトのソース フォルダにある script/lua/simple_project.lua にコピーします。
コア リソース内でこのファイルを直接修正することができますが、ファイルのコピーを作成してプロジェクト内に持ち込む方が安全です。「コア リソースを使用する」および「Appkit をカスタマイズする」の説明も参照してください。
プロジェクトの script/lua/project.lua ファイルを開き、simple_project.lua ファイルの新しい場所を指すように require ステートメントを変更します。
SimpleProject = require 'script/lua/simple_project'
script/lua/simple_project.lua ファイルを開きます。
現在のレベルのリソース パッケージ オブジェクトを格納する新しい変数を宣言します。
SimpleProject.resource_package = SimpleProject.resource_package or nil
他の SimpleProject メンバー変数が初期化される行 47 周辺に追加します。
次のコードの関数の最初に追加して load_level 関数を更新します。
if stingray.Application.can_get("package", resource_name) then SimpleProject.resource_package = stingray.Application.resource_package(resource_name) stingray.ResourcePackage.load(SimpleProject.resource_package) stingray.ResourcePackage.flush(SimpleProject.resource_package) end
レベルがロードされるたびに、このコードは同じ名前を持つ .package リソースを検索します。リソースが検出されると、メモリ内にロードされ、SimpleProject.resource_package 変数がそのリソースを指すように設定されます。
次のコードの関数の最後に追加して unload_level 関数を更新します。
if SimpleProject.resource_package ~= nil then stingray.ResourcePackage.unload(SimpleProject.resource_package) stingray.Application.release_resource_package(SimpleProject.resource_package) SimpleProject.resource_package = nil end
レベルがロード解除されるたびに、このコードはそのレベルにロードされているリソース パッケージを破棄します(存在する場合)。
すべてのファイルを保存します。
上記のコードはパッケージを直ちにロードし、リソースがすべてロードされるまで更新ループが継続されないようブロックすることにご注意ください。リソース パッケージが非常に大きくなった場合、または非常に低速なメディアからデータを読み取っている場合は、「非同期」ロード モデルを代用しなければならない可能性があります。その他のサンプル コードについては、「パッケージのロードとロード解除」も参照してください。
この手順では、ゲームで実際に消費されるメモリがランタイムで期待どおりに変化するか確認するためのテストを行います。
プロジェクトを実行します。
Stingray エディタのステータス バーで、ドロップダウン リストから実行中のプロジェクトを選択し、ゲームに perfhud memory コマンドを発行します。「ステータス バーからコマンドを送信する」も参照してください。
ゲームの UI は、現在のメモリ使用量の概要でオーバーレイされる必要があります。
ゲームに移動し、メイン メニューの START を押して最初のレベルをロードします。
[l]キーを押すとレベル間で交互に切り替わります。レベルが切り替わるたびに、メモリの消費量が上下するのが確認できます。これは、リソースが期待どおりにメモリ内外にロードされていることを示しています。
また、memory_resources list unit コマンドを発行して現在メモリにある全ユニットのリストを出力することでも、システムが期待どおりに機能していることを確認できます。level_1 がロードされているときは、このコマンドからの出力には core、content、content_level_1 フォルダのリソースのみが含まれ、content_level_2 フォルダからのリソースは含まれません。
すべてのコンソール コマンドのリストも参照してください。