You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
213 lines
7.3 KiB
C#
213 lines
7.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
|
|
using Duality;
|
|
using Duality.Input;
|
|
using Duality.Components;
|
|
using Duality.Drawing;
|
|
|
|
namespace CameraController
|
|
{
|
|
/// <summary>
|
|
/// This class is in control of the example scene. It draws some debug information
|
|
/// and makes sure that users can select a camera controller to use, etc.
|
|
/// </summary>
|
|
public class ExampleSceneController : Component, ICmpUpdatable, ICmpRenderer
|
|
{
|
|
private GameObject mainCameraObj = null;
|
|
private GameObject targetObj = null;
|
|
|
|
[DontSerialize] private List<ICameraController> cameraControllers = null;
|
|
[DontSerialize] private int activeCamController = -1;
|
|
[DontSerialize] private FormattedText infoText = null;
|
|
[DontSerialize] private FormattedText stateText = null;
|
|
[DontSerialize] private bool movementHistoryActive = false;
|
|
[DontSerialize] private float movementHistoryTimer = 0.0f;
|
|
|
|
/// <summary>
|
|
/// [GET / SET] The main camera, on which sample camera controllers will be installed.
|
|
/// </summary>
|
|
public GameObject MainCameraObject
|
|
{
|
|
get { return this.mainCameraObj; }
|
|
set { this.mainCameraObj = value; }
|
|
}
|
|
/// <summary>
|
|
/// [GET / SET] The target object, which sample camera controllers will be configured to follow.
|
|
/// </summary>
|
|
public GameObject TargetObject
|
|
{
|
|
get { return this.targetObj; }
|
|
set { this.targetObj = value; }
|
|
}
|
|
/// <summary>
|
|
/// [GET / SET] The index of the currently active camera controller.
|
|
/// </summary>
|
|
public int ActiveCameraController
|
|
{
|
|
get { return this.activeCamController; }
|
|
set
|
|
{
|
|
// Normalize the index
|
|
if (value < -1) value = this.cameraControllers.Count - 1;
|
|
if (value >= this.cameraControllers.Count) value = -1;
|
|
|
|
// Apply the index
|
|
this.activeCamController = value;
|
|
|
|
// Remove the old camera controller
|
|
ICameraController oldController = this.mainCameraObj.GetComponent<ICameraController>();
|
|
if (oldController != null)
|
|
{
|
|
this.mainCameraObj.RemoveComponent(oldController as Component);
|
|
}
|
|
|
|
// Add the new camera controller, if one is selected
|
|
ICameraController newController = null;
|
|
if (this.activeCamController != -1)
|
|
{
|
|
newController = this.cameraControllers[this.activeCamController];
|
|
newController.TargetObject = this.targetObj;
|
|
this.mainCameraObj.AddComponent(newController as Component);
|
|
}
|
|
}
|
|
}
|
|
|
|
float ICmpRenderer.BoundRadius
|
|
{
|
|
get { return float.MaxValue; }
|
|
}
|
|
bool ICmpRenderer.IsVisible(IDrawDevice device)
|
|
{
|
|
return
|
|
(device.VisibilityMask & VisibilityFlag.ScreenOverlay) != VisibilityFlag.None &&
|
|
(device.VisibilityMask & VisibilityFlag.AllGroups) != VisibilityFlag.None;
|
|
}
|
|
|
|
void ICmpUpdatable.OnUpdate()
|
|
{
|
|
// Prepare a list of camera controllers, if we don't already have one
|
|
if (this.cameraControllers == null)
|
|
{
|
|
this.cameraControllers = new List<ICameraController>();
|
|
|
|
// Use Reflection to get a list of all ICameraController classes
|
|
TypeInfo[] availableCameraControllerTypes = DualityApp.GetAvailDualityTypes(typeof(ICameraController)).ToArray();
|
|
foreach (TypeInfo camControllerType in availableCameraControllerTypes)
|
|
{
|
|
// Create an instance of each class
|
|
ICameraController camController = camControllerType.CreateInstanceOf() as ICameraController;
|
|
if (camController != null)
|
|
{
|
|
this.cameraControllers.Add(camController);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Allow the user to select which camera controller to use
|
|
if (DualityApp.Keyboard.KeyHit(Key.Number1))
|
|
this.ActiveCameraController--;
|
|
if (DualityApp.Keyboard.KeyHit(Key.Number2))
|
|
this.ActiveCameraController++;
|
|
if (DualityApp.Keyboard.KeyHit(Key.M))
|
|
this.movementHistoryActive = !this.movementHistoryActive;
|
|
|
|
// Is there a Gamepad we can use?
|
|
GamepadInput gamepad = DualityApp.Gamepads.FirstOrDefault(g => g.IsAvailable);
|
|
if (gamepad != null)
|
|
{
|
|
if (gamepad.ButtonHit(GamepadButton.A))
|
|
this.ActiveCameraController--;
|
|
if (gamepad.ButtonHit(GamepadButton.B))
|
|
this.ActiveCameraController++;
|
|
if (gamepad.ButtonHit(GamepadButton.X))
|
|
this.movementHistoryActive = !this.movementHistoryActive;
|
|
}
|
|
|
|
// Every 100 ms, draw one visual log entry to document movement
|
|
if (this.movementHistoryActive)
|
|
{
|
|
this.movementHistoryTimer += Time.MsPFMult * Time.TimeMult;
|
|
if (this.movementHistoryTimer > 100.0f)
|
|
{
|
|
this.movementHistoryTimer -= 100.0f;
|
|
Vector2 targetPos = this.targetObj.Transform.Pos.Xy;
|
|
Vector2 cameraPos = this.mainCameraObj.Transform.Pos.Xy;
|
|
VisualLog.Default.DrawPoint(
|
|
targetPos.X,
|
|
targetPos.Y,
|
|
0.0f)
|
|
.WithColor(new ColorRgba(255, 128, 0))
|
|
.KeepAlive(3000.0f);
|
|
VisualLog.Default.DrawPoint(
|
|
cameraPos.X,
|
|
cameraPos.Y,
|
|
0.0f)
|
|
.WithColor(new ColorRgba(0, 255, 0))
|
|
.KeepAlive(3000.0f);
|
|
}
|
|
}
|
|
}
|
|
void ICmpRenderer.Draw(IDrawDevice device)
|
|
{
|
|
Canvas canvas = new Canvas(device);
|
|
|
|
Vector2 screenSize = device.TargetSize;
|
|
ICameraController activeController = this.mainCameraObj.GetComponent<ICameraController>();
|
|
Transform camTransform = this.mainCameraObj.Transform;
|
|
Transform targetTransform = this.targetObj.Transform;
|
|
|
|
float camDist = (camTransform.Pos.Xy - targetTransform.Pos.Xy).Length;
|
|
string activeControllerName = activeController != null ? activeController.GetType().Name : "None";
|
|
activeControllerName = activeControllerName.Replace("CameraController", "");
|
|
|
|
// Draw the screen center, so we know what exactly our camera controller is pointing at
|
|
canvas.State.ColorTint = ColorRgba.Green.WithAlpha(0.5f);
|
|
canvas.FillCircle(screenSize.X * 0.5f, screenSize.Y * 0.5f, 8.0f);
|
|
|
|
// Draw the camera distance around the screen center
|
|
canvas.State.ColorTint = ColorRgba.Green.WithAlpha(0.25f);
|
|
canvas.DrawCircle(screenSize.X * 0.5f, screenSize.Y * 0.5f, camDist);
|
|
|
|
// Draw the camera velocity (movement per second) around the screen center
|
|
canvas.State.ColorTint = ColorRgba.Green.WithAlpha(0.5f);
|
|
canvas.DrawLine(
|
|
screenSize.X * 0.5f,
|
|
screenSize.Y * 0.5f,
|
|
screenSize.X * 0.5f + camTransform.Vel.X / Time.SPFMult,
|
|
screenSize.Y * 0.5f + camTransform.Vel.Y / Time.SPFMult);
|
|
|
|
// Draw some info text
|
|
if (this.infoText == null)
|
|
{
|
|
this.infoText = new FormattedText();
|
|
this.infoText.MaxWidth = 350;
|
|
}
|
|
this.infoText.SourceText = string.Format(
|
|
"Camera Controller Sample/n/n" +
|
|
"Use /c44AAFFFFarrow keys/cFFFFFFFF // /c44AAFFFFleft thumbstick/cFFFFFFFF to move./n" +
|
|
"Use /c44AAFFFFnumber keys 1, 2/cFFFFFFFF // /c44AAFFFFbuttons A, B/cFFFFFFFF to select a Camera Controller./n" +
|
|
"Use the /c44AAFFFFM key/cFFFFFFFF // /c44AAFFFFbutton X/cFFFFFFFF to toggle movement history./n/n" +
|
|
"Active Camera Controller:/n/cFF8800FF{0}/cFFFFFFFF",
|
|
activeControllerName);
|
|
|
|
canvas.State.ColorTint = ColorRgba.White;
|
|
canvas.DrawText(this.infoText, 10, 10, 0.0f, null, Alignment.TopLeft, true);
|
|
|
|
// Draw state information on the current camera controller
|
|
if (this.stateText == null) this.stateText = new FormattedText();
|
|
this.stateText.SourceText = string.Format(
|
|
"Camera Distance: {0:F}/n" +
|
|
"Camera Velocity: {1:F}, {2:F}",
|
|
camDist,
|
|
camTransform.Vel.X,
|
|
camTransform.Vel.Y);
|
|
|
|
canvas.State.ColorTint = ColorRgba.White;
|
|
canvas.DrawText(this.stateText, 10, screenSize.Y - 10, 0.0f, null, Alignment.BottomLeft, true);
|
|
}
|
|
}
|
|
}
|