ヘッドレスサーバー
往々にして、より少ないリソースを用いるサーバーを起動したいこともあるでしょう。このような場合には、ゲームのインスタンスをグラフィックインターフェースや人為的な反復をなくして実行する必要があります。これを実現するため、Unityには特殊な引数があり、これらの引数をゲームに渡すことで様々な挙動を実現することが可能です。
Boltはこの点を念頭に置いて構築されているため、ホスティングサービス上にあるゲームの複数のサーバーを実行でき、結果的にプレイヤーはゲームに参加することができます。 これを実現するスクリプトのサンプルを作成済みですので、この点についてはすぐに確認可能です。サンプルスクリプトはbolt_samples/HeadlessServer
フォルダ内を確認してください。
ヘッドレスサーバー
を起動し、実行するには以下の手順にしたがってください:
- デフォルトの設定を変更するには、エディターの
HeadlessServer/Scenes/BoltHeadlessServer
シーンを開きます。HeadlessServerHolder
ゲームオブジェクトをクリックします。Map
(サーバーによってローディングされるシーン名)、Game Type
(カスタムプロパティの例) とRoom ID
(作成したルームの名前。空白のままの場合にはランダムな名前が作成されます)の値を更新します。
BoltHeadlessServer
シーンをインデックス0
のシーンとして使用して、ゲームのバージョンを構築します。必ず Bolt Compiler (Assets/Bolt/Compile Assembly
)を実行してください。Command Line
から実行ファイルを開いて実行します:<path/to/your executable>.exe -batchmode -nographics -logFile [-map <other scene>] [-gameType <other game type>] [-room <other room name>]
;- 例:
myGame.exe -batchmode -nographics -map Level1
これによって、シーンLevel1
向けにサーバーが起動します。
- メインシーンでゲームを構築し、クライアントピアとして起動して、通常どおりルームに接続します。
これによって、実際のHeadlessServerManagerクラスのトランスクリプトを開くことができます。このトランスクリプトによってサーバーが起動されゲームが実行されます:
C#
using System;
using Bolt.Matchmaking;
using Bolt.Photon;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace Bolt.Samples.HeadlessServer
{
public class HeadlessServerManager : Bolt.GlobalEventListener
{
public string Map = "";
public string GameType = "";
public string RoomID = "";
public override void BoltStartBegin()
{
// Register any Protocol Token that are you using
BoltNetwork.RegisterTokenClass<PhotonRoomProperties>();
}
public override void BoltStartDone()
{
if (BoltNetwork.IsServer)
{
// Create some room custom properties
PhotonRoomProperties roomProperties = new PhotonRoomProperties();
roomProperties.AddRoomProperty("t", GameType); // ex: game type
roomProperties.AddRoomProperty("m", Map); // ex: map id
roomProperties.IsOpen = true;
roomProperties.IsVisible = true;
// If RoomID was not set, create a random one
if (RoomID.Length == 0)
{
RoomID = Guid.NewGuid().ToString();
}
// Create the Photon Room
BoltMatchmaking.CreateSession(
sessionID: RoomID,
token: roomProperties,
sceneToLoad: Map
);
}
}
// Use this for initialization
void Start()
{
// Get custom arguments from command line
Map = GetArg("-m", "-map") ?? Map;
GameType = GetArg("-t", "-gameType") ?? GameType; // ex: get game type from command line
RoomID = GetArg("-r", "-room") ?? RoomID;
// Validate the requested Level
var validMap = false;
foreach (string value in BoltScenes.AllScenes)
{
if (SceneManager.GetActiveScene().name != value)
{
if (Map == value)
{
validMap = true;
break;
}
}
}
if (!validMap)
{
BoltLog.Error("Invalid configuration: please verify level name");
Application.Quit();
}
// Start the Server
BoltLauncher.StartServer();
DontDestroyOnLoad(this);
}
/// <summary>
/// Utility function to detect if the game instance was started in headless mode.
/// </summary>
/// <returns><c>true</c>, if headless mode was ised, <c>false</c> otherwise.</returns>
public static bool IsHeadlessMode()
{
return Environment.CommandLine.Contains("-batchmode") && Environment.CommandLine.Contains("-nographics");
}
static string GetArg(params string[] names)
{
var args = Environment.GetCommandLineArgs();
for (int i = 0; i < args.Length; i++)
{
foreach (var name in names)
{
if (args[i] == name && args.Length > i + 1)
{
return args[i + 1];
}
}
}
return null;
}
}
}
もちろん、さらに引数チェックを作成してこのトランスクリプトをカスタマイズすれば、入るポートや異なるゲームモードなどを使用できます。
ゲームでカーソルのロックやプレイヤーのスポーン、音楽などの挙動を、ヘッドレスモードで実行中に無効にしたい場合もあるでしょう。
チュートリアルでは、PlayerCamera.cs
内にScreen.lockCursor = true
があります。ヘッドレスモードでない場合には、カーソルのロックだけを行うよう、スクリプトの編集が可能です。同様のことが、ServerCallbacks.cs
内のPlayer.serverPlayer.InstantiateEntity()
にも該当します。これを実現するため、ユーティリティ機能であるHeadlessServerManager.IsHeadlessMode()
が追加されており、ゲームインスタンスがヘッドレスモードで開始されたかを確認できます。