Game Development Community

Input Mapping / RTS Camera

by Mathias Kahl · in Torque X 3D · 07/31/2009 (6:10 am) · 2 replies

Hello! I have a problem with creating my own RTS camera as described by John (http://www.garagegames.com/community/blogs/view/17655).

I know there were already a few threads with similar topics, but I couldn't find an explanation or answer there.

I implemented the RTS camera as described by John:
using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.Xna.Framework;

using GarageGames.Torque.Core;
using GarageGames.Torque.Util;
using GarageGames.Torque.Sim;
using GarageGames.Torque.T3D;
using GarageGames.Torque.SceneGraph;
using GarageGames.Torque.MathUtil;
using Microsoft.Xna.Framework.Input;
using GarageGames.Torque.Platform;

namespace BaseConflict
{
    [TorqueXmlSchemaType]
    public class RtsCameraComponent : T3DCameraComponent, ITickObject
    {
        //======================================================
        #region Static methods, fields, constructors
        #endregion

        //======================================================
        #region Constructors

        public RtsCameraComponent()
        {
            CameraMovementSpeed = 2.5f;
            CameraVerticalAngle = -45;
            CameraHorizontalAngle = 90;
        }

        #endregion

        //======================================================
        #region Public properties, operators, constants, and enums

        public float CameraVerticalAngle { get; set; }
        public float CameraHorizontalAngle { get; set; }

        public float CameraMovementSpeed { get; set; }
        public int PlayerIndex { get; set; }
        public InputMap CameraInputMap { get; set; }

        #endregion

        //======================================================
        #region Public methods

        public virtual void ProcessTick(Move move, float dt)
        {            
            if (move == null)
                return;

            if (move.Sticks.Count > 0)
            {
                Vector3 dir = new Vector3((move.Sticks[0].X * CameraMovementSpeed),
                    (move.Sticks[0].Y * CameraMovementSpeed), 0);

                SceneGroup.Position += dir;
            }
        }

        public virtual void InterpolateTick(float k)
        {
            // todo: interpolate between ticks as needed here
        }

        public override void CopyTo(TorqueComponent obj)
        {
            base.CopyTo(obj);
        }

        #endregion

        //======================================================
        #region Private, protected, internal methods

        protected override bool _OnRegister(TorqueObject owner)
        {
            if (!base._OnRegister(owner))
                return false;

            ProcessList.Instance.AddTickCallback(owner, this);
            _SetupInputMap();

            return true;
        }

        protected override void _OnUnregister()
        {
            base._OnUnregister();
        }

        protected override void _RegisterInterfaces(TorqueObject owner)
        {
            base._RegisterInterfaces(owner);
        }

        protected virtual void _SetupInputMap()
        {
            if (PlayerManager.Instance.GetPlayer(PlayerIndex).ControlObject == null)
            {
                PlayerManager.Instance.GetPlayer(PlayerIndex).ControlObject = Owner;
                CameraInputMap = PlayerManager.Instance.GetPlayer(PlayerIndex).InputMap;
            }
            else
            {
                CameraInputMap = new InputMap();
            }

            // Tastatur
            int keyboard = InputManager.Instance.FindDevice("keyboard");

            if (keyboard >= 0)
            {
                CameraInputMap.BindMove(keyboard, (int)Keys.Up, MoveMapTypes.StickDigitalUp, 0);
                CameraInputMap.BindMove(keyboard, (int)Keys.Down, MoveMapTypes.StickDigitalDown, 0);
                CameraInputMap.BindMove(keyboard, (int)Keys.Left, MoveMapTypes.StickDigitalLeft, 0);
                CameraInputMap.BindMove(keyboard, (int)Keys.Right, MoveMapTypes.StickDigitalRight, 0);
            }
        }

        protected override void _UpdateTransform()
        {
            Quaternion horizontal = Quaternion.CreateFromYawPitchRoll(0, 0, MathHelper.ToRadians(CameraHorizontalAngle));
            Quaternion vertical = Quaternion.CreateFromYawPitchRoll(0, MathHelper.ToRadians(CameraVerticalAngle), 0);

            SceneGroup.Rotation = Quaternion.Concatenate(vertical, horizontal);

            _transform = SceneGroup.Transform;
        }

        #endregion

        //======================================================
        #region Private, protected, internal fields
        #endregion
    }
}

That's how I create the camera:
GUISceneview sceneView = TorqueObjectDatabase.Instance.FindObject<GUISceneview>("DefaultSceneView");

            TorqueObject objCamera = new TorqueObject();
            objCamera.Name = "RtsCamera";

            //PlayerManager.Instance.GetPlayer(0).ControlObject = objCamera;

            T3DSceneComponent componentScene = new T3DSceneComponent();
            componentScene.SceneGroup = "RtsCamera";
            componentScene.Position = new Vector3(1024, 1024, 310);
            objCamera.Components.AddComponent(componentScene);

            RtsCameraComponent componentCamera = new RtsCameraComponent();
            componentCamera.SceneGroupName = "RtsCamera";
            objCamera.Components.AddComponent(componentCamera);

            TorqueObjectDatabase.Instance.Register(objCamera);

            sceneView.Camera = componentCamera;

However, nothing is moving at all. The parameter "move" of ProcessTick() is always zero.
After reading some threads here I added the line that is commented out above (PlayerManager...).
After that for some reason the camera moved when I pressed the WASD keys, even though I haven't even mapped them!

Can someone explain this behaviour?

About the author

I'm a student of Computer Science (Freie Universität in Berlin, Germany). Currently I'm working on a multiplayer strategy/action game based on Torque X.


#1
07/31/2009 (5:34 pm)
This should work as listed above. Do you have another camera defined somewhere, possible within your levelData.txscene file? If so, there might be a struggle for input control between the two cameras.

John K.
www.envygames.com
#2
08/01/2009 (2:56 am)
Thanks a lot, John! There was another camera defined in the standard levelData.txscene. Now that I removed it, my camera is working as it should. :)