戦略パターンは私には良い賭けのようです。さらに一歩進めるために、カメラマネージャーは具体的なカメラタイプを知らないままにしておく必要があります。たとえば、IDを使用してカメラの実装を外部で登録および変更します(柔軟性を高めるために文字列を使用しましたが、enumまたはintでもかまいません)。例(エラーチェックなし):
public interface ICamera
{
void Update(float dt);
Matrix View { get; }
}
public class CameraManager
{
private Dictionary<string, ICamera> cameras;
private ICamera currentCamera;
public void RegisterCamera(string id, ICamera camera) { cameras[id] = camera; }
public void SetCamera(string id) { currentCamera = cameras[id]; }
public void Update(float dt) { currentCamera.Update(dt); }
public Matrix View { get { return currentCamera.View; } }
}
public class DebugCamera : ICamera {}
public class PlayerCamera : ICamera {}
public class ScriptedCamera : ICamera {}
void Test()
{
// Create camera manager
CameraManager cameraManager = new CameraManager();
// Register cameras
cameraManager.RegisterCamera("Debug", new DebugCamera());
cameraManager.RegisterCamera("Player", new PlayerCamera());
cameraManager.RegisterCamera("Scripted", new ScriptedCamera());
// Change active camera
cameraManager.SetCamera("Player");
}
編集する
追加情報:反射など、複数のカメラをアクティブにする必要があるという現実の可能性があります。つまり、私もそのことを考慮しなければなりません。
追加するのは簡単です。次のように変更currentCamera
してください:
List<ICamera> activeCameras = new List<ICamera>();
SetCamera
ToggleCameraに変更します(またはブール値をSetCameraに追加します)。
void ToggleCamera(string id)
{
ICamera camera = cameras[id];
if(activeCameras.Contains(camera))
activeCameras.Remove(camera);
else
activeCameras.Add(camera);
}
またUpdate
、現在のカメラだけでなく、アクティブなすべてのカメラを更新するようにメソッドを変更します。
void Update(float dt) { activeCameras.ForEach(c => c.Update(dt)); }
私の例では、View
プロパティをGetView
カメラのIDをパラメーターとして取るメソッドに置き換える必要もあります。しかし、それはとにかくあなたのカメラインターフェースに依存する詳細です:
// You could optionally add a check to see if the camera is active
Matrix GetView(string id) { return cameras[id].View; }