I have an interface (ICamera) which is implemented by 2 classes (FreeCamera, StaticCamera). The classes are inheriting from GameComponent.
Example definiton:
public class FreeCamera : GameComponent, ICamera
{
...
}
Now I'm adding the classes to the Game Components and register one of the components to a game service
private FreeCamera freeCam;
private StaticCamera staticCam;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
freeCam = new FreeCamera(this) { Enabled = true };
staticCam = new StaticCamera(this) { Enabled = false };
Services.AddService(typeof(ICamera, freeCam);
Components.Add(freeCam);
Components.Add(staticCam);
...
}
Then I want to change the provider for the service during the application flow with help of a toggle function
namespace Game1
{
protected override void Update(GameTime gameTime)
{
var keyboard = Keyboard.GetState();
if(keyboard.IsKeyDown(Keys.C))
{
if(freeCam.Enabled)
{
Services.RemoveService(typeof(ICamera));
Services.AddService(typeof(ICamera, staticCam);
freeCam.Enabled = !freeCam.Enabled;
staticCam.Enabled = !staticCam.Enabled;
}
else
{
Services.RemoveService(typeof(ICamera));
Services.AddService(typeof(ICamera, freeCam);
freeCam.Enabled = !freeCam.Enabled;
staticCam.Enabled = !staticCam.Enabled;
}
}
base.Update(gameTime);
}
}
The StaticCamera takes only input by mouse (you can rotate the camera), the FreeCamera can also moved by keyboard input. When I call the method above (by pressing C on the keyboard) the FreeCamera class gets deactivated but the viewport seems frozen and does not react to any input. When I call the method again after a short time the FreeCamera gets activated again and everything works as expected.
Now I have 2 questions regarding this:
Thanks in advance for any help.
Like you answered, use a camera manager. It acts as both a factory and a container for the current camera. The manager you can register as a service. Manager would look something like this:
public class CameraManager
{
private Dictionary<Type, ICamera> _cameras;
private ICamera _current;
public ICamera Current
{
get
{
return _current;
}
}
// Sets the current cammera to the internal instance of the camera type
public void SetCurrent<T>() where T : ICamera
{
if (!_cameras.ContainsKey(typeof(T)))
{
// TODO: Instantiate a new camera class here...
}
_current = _cameras[typeof(T)];
}
}
This is just rough code - would need to be filled in more. One limitation is you can only have one camera per type. Giving cameras a string name, or an enum flag would let you toggle between an arbitrary number of cameras.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With