How to unbind inputmapped controls.
by Scott Zarnke · in Torque X 2D · 07/17/2009 (5:25 pm) · 10 replies
***EDIT*** This has been added to the TDN TX Tutorial page under Community Links.
It occurred to me a while back that while you have the ability to map input to controls through the inputmap class, there is no "unbind" method for ending a particular mapping. I looked at the source code, and based on that figured some ways to do that. It's a little different based on whether you used BindCommand, BindAction, or BindMove, so I wrote a few general purpose methods as catch-alls. Feel free to use these if they seem useful. They are based roughly on the different versions of the above mentioned Bind* methods, but in reverse. These would go in the InputMap class, of course.
It occurred to me a while back that while you have the ability to map input to controls through the inputmap class, there is no "unbind" method for ending a particular mapping. I looked at the source code, and based on that figured some ways to do that. It's a little different based on whether you used BindCommand, BindAction, or BindMove, so I wrote a few general purpose methods as catch-alls. Feel free to use these if they seem useful. They are based roughly on the different versions of the above mentioned Bind* methods, but in reverse. These would go in the InputMap class, of course.
/// <summary>
/// Undoes any previous call to BindCommand, BindAction, and/or BindMove for
/// the passed combination of deviceNumber, objectId, and modifier.
/// </summary>
/// <param name="deviceNumber">e.g. InputManager.Instance.FindDevice("keyboard")</param>
/// <param name="objectId">e.g. (int)Keys.S</param>
/// <param name="modifier">e.g. TorqueInputDevice.Action.Shift</param>
/// <returns>Whether deviceNumber and objectId are valid.</returns>
public bool UnbindInput(int deviceNumber, int objectId, TorqueInputDevice.Action modifier)
{
TorqueInputDevice device = InputManager.Instance.GetDevice(deviceNumber);
if (device == null || !device.IsValidObject(objectId))
return false;
int index = _FindInputNode(deviceNumber, objectId, modifier);
if (index < 0)
return true; //no binding, yet, for that combination
InputNode node = _inputNodes[index];
node.Flags = InputNode.ActionFlags.None;
node.MakeDelegate = null;
node.BreakDelegate = null;
node.ActionDelegate = null;
node.Modifier = TorqueInputDevice.Action.None;
node.MoveIndex = -1;
_inputNodes[index] = node;
return true;
}
#region UnbindInput variants for convenience
/// <summary>
/// Undoes any previous call to BindCommand, BindAction, and/or BindMove for
/// the passed combination of deviceName, objectName, and modifier.
/// </summary>
/// <param name="deviceName">e.g. "keyboard"</param>
/// <param name="objectName">e.g. "S"</param>
/// <param name="modifier">e.g. TorqueInputDevice.Action.Shift</param>
/// <returns>Whether deviceNumber and objectId are valid.</returns>
public bool UnbindInput(String deviceName, String objectName, TorqueInputDevice.Action modifier)
{
int deviceNumber = InputManager.Instance.FindDevice(deviceName);
if (deviceNumber == -1)
return false;
TorqueInputDevice device = InputManager.Instance.GetDevice(deviceNumber);
int objectId = device.GetObjectId(objectName);
if (objectId == -1)
return false;
return UnbindInput(deviceNumber, objectId, modifier);
}
/// <summary>
/// Undoes any previous call to BindCommand, BindAction, and/or BindMove for
/// the passed combination of deviceName and objectName.
/// </summary>
/// <param name="deviceName">e.g. "keyboard"</param>
/// <param name="objectName">e.g. "S"</param>
/// <returns>Whether deviceNumber and objectId are valid.</returns>
public bool UnbindInput(String deviceName, String objectName)
{
return UnbindInput(deviceName, objectName, TorqueInputDevice.Action.None);
}
/// <summary>
/// Undoes any previous call to BindCommand, BindAction, and/or BindMove for
/// the passed combination of deviceNumber and objectId.
/// </summary>
/// <param name="deviceNumber">e.g. InputManager.Instance.FindDevice("keyboard")</param>
/// <param name="objectId">e.g. (int)Keys.S</param>
/// <returns>Whether deviceNumber and objectId are valid.</returns>
public bool UnbindInput(int deviceNumber, int objectId)
{
return UnbindInput(deviceNumber, objectId, TorqueInputDevice.Action.None);
}
#endregionIf you want a more direct way, I believe you can, for instance, undo BindCommand by passing null for the make and break functions, undo BindAction also by passing null, and undo BindMove by passing -1 for the moveIdx.
#2
if I use
inputMap = PlayerManager.Instance.GetPlayer(playerIndex).InputMap;
thats the wrong one
thanks
07/18/2009 (8:04 am)
How can I get an instance reference to the input map within the current GUI?if I use
inputMap = PlayerManager.Instance.GetPlayer(playerIndex).InputMap;
thats the wrong one
thanks
#3
07/18/2009 (8:33 am)
Every class derived from GUIControl has a accessor property named InputMap, so you would use your handle to the mainplay gui like mainplay.InputMapor whatever you called that GUI object.
#4
I can't access the Accessor because it's not static.
is there a current content control finder? :)
once you do this
GUICanvas.Instance.SetContentControl(GuiPlay);
how can you access that instance of GuiPlay from another class?
07/18/2009 (3:19 pm)
I need to find the instance of it, because i do one of these:class GuiPlay : GUISceneview, IGUIScreen
new GuiPlay()I can't access the Accessor because it's not static.
is there a current content control finder? :)
once you do this
GUICanvas.Instance.SetContentControl(GuiPlay);
how can you access that instance of GuiPlay from another class?
#5
Ahh that's how.
Works!
07/18/2009 (9:31 pm)
GuiPlay gp = TorqueObjectDatabase.Instance.FindObject<GuiPlay>("guiPlay");Ahh that's how.
Works!
#6
If I wanted to just check if a certain binding is currently setup, would I just use the _FindInputNode() function inside the InputMap?
I haven't had a second to really look at it thoroughly, but at a quick glance this seems to be the answer.
07/21/2009 (3:32 pm)
Hey Scott,If I wanted to just check if a certain binding is currently setup, would I just use the _FindInputNode() function inside the InputMap?
I haven't had a second to really look at it thoroughly, but at a quick glance this seems to be the answer.
#7
If _FindInputNode returns negative, then that means there's no node, yet, and thus no binding. If there is a node, you might want to then check its delegates as well as the move index. A non-null delegate means its mapped to a method, and a non-negative move index is mapped to a move object.
Also, the property "node.Flags" gets set to certain ActionFlags when a call to some of the Bind* methods are used, though I don't remember the specifics of that off hand.
07/21/2009 (4:57 pm)
@Lucas:If _FindInputNode returns negative, then that means there's no node, yet, and thus no binding. If there is a node, you might want to then check its delegates as well as the move index. A non-null delegate means its mapped to a method, and a non-negative move index is mapped to a move object.
Also, the property "node.Flags" gets set to certain ActionFlags when a call to some of the Bind* methods are used, though I don't remember the specifics of that off hand.
#8
I'm exited to get this in but I don't have the source code. I've tried extending the class and adding methods in a class of my own, but there are some variables that can't get access due to protection level.
Is there any other way to work this without the source?
In case there's an easier way, I'm trying to pause the game. The only way I can see to stop player movement is to either unbind all the buttons and re-call the button init method after unpause, or store the current inputmap in a variable, make the active one a clean slate with no binds and then put the stored one back when the game gets unpaused.
10/08/2009 (3:11 pm)
Hey Scott,I'm exited to get this in but I don't have the source code. I've tried extending the class and adding methods in a class of my own, but there are some variables that can't get access due to protection level.
Is there any other way to work this without the source?
In case there's an easier way, I'm trying to pause the game. The only way I can see to stop player movement is to either unbind all the buttons and re-call the button init method after unpause, or store the current inputmap in a variable, make the active one a clean slate with no binds and then put the stored one back when the game gets unpaused.
#9
As far as implementing the changes, I'm not sure if it is possible without the source. Otherwise,
Regarding the pause, there may be better ways, but something I had used was done for individual objects because I wanted some things to still be active (like a sprite serving as a mouse cursor).
For every component which was on an object that I wanted to pause and which used the ProcessTick() method, I added a bool "Pause" property. When it was set to true, I used
If you wanted it to continue with its former motion, I suppose you could save its velocity when it is paused, stop it, then restore the velocity when it is unpaused.
Maybe with some luck in searching, someone has a more comprehensive solution.
Good luck; I hope Cosmic Lacrosse is coming along nicely, if not already finished.
P.S. Regarding your question about changing sprite colors, I'm surprised Christopher Perkins didn't suggest his own thread about doing so through the use of a shader, and which also has a link to my idea about changing the material's data in memory. You could probably use either one.
10/08/2009 (7:28 pm)
CM:As far as implementing the changes, I'm not sure if it is possible without the source. Otherwise,
Quote:If you want a more direct way, I believe you can, for instance, undo BindCommand by passing null for the make and break functions, undo BindAction also by passing null, and undo BindMove by passing -1 for the moveIdx.
Regarding the pause, there may be better ways, but something I had used was done for individual objects because I wanted some things to still be active (like a sprite serving as a mouse cursor).
For every component which was on an object that I wanted to pause and which used the ProcessTick() method, I added a bool "Pause" property. When it was set to true, I used
_sceneObject.Physics.Velocity = Vector2.Zero; _sceneObject.Physics.AngularVelocity = 0;to stop its motion, and stopped the sound that was playing as it moved. Then, inside the ProcessTick() method, if _isPaused is true, it simply stops the motion again (to be safe) then exits, so no controls are responded to for that object. When it is unpaused, the ProcessTick() method runs as normal.
If you wanted it to continue with its former motion, I suppose you could save its velocity when it is paused, stop it, then restore the velocity when it is unpaused.
Maybe with some luck in searching, someone has a more comprehensive solution.
Good luck; I hope Cosmic Lacrosse is coming along nicely, if not already finished.
P.S. Regarding your question about changing sprite colors, I'm surprised Christopher Perkins didn't suggest his own thread about doing so through the use of a shader, and which also has a link to my idea about changing the material's data in memory. You could probably use either one.
#10
I'm getting the source code soon so this little function will just have to wait I think.
I've got the bool "IsPaused" in my game for everything, it stops player movement but the button binds still work.
I think I'm going to just add that check to all my button methods as well, for now at least.
**Edit** The check in each method works swimmingly, and I'm sure performance wise it's better than unbinding/rebinding every time I pause. Thanks for the insight :D When this is all said and done I should get you a free copy of this game you've helped so much.
As for the changing colours, I've yet to dabble into lighting and shading yet. That might wait for the next game or the finishing touches. Especially since I'm not sure if you can actually only change specific colours as opposed to the whole sprite. I want just the character's jersey tinted if that's possible.
Thanks for the hope :) It's definatley coming along nicely, albiet slowly. The 40 hour/week job doesn't leave a lot of free time for game work. Once I get rich off of Cosmic Lacrosse it will be smooooth sailing for the next game though ;)
10/09/2009 (3:16 am)
Thanks for the tips.I'm getting the source code soon so this little function will just have to wait I think.
I've got the bool "IsPaused" in my game for everything, it stops player movement but the button binds still work.
I think I'm going to just add that check to all my button methods as well, for now at least.
**Edit** The check in each method works swimmingly, and I'm sure performance wise it's better than unbinding/rebinding every time I pause. Thanks for the insight :D When this is all said and done I should get you a free copy of this game you've helped so much.
As for the changing colours, I've yet to dabble into lighting and shading yet. That might wait for the next game or the finishing touches. Especially since I'm not sure if you can actually only change specific colours as opposed to the whole sprite. I want just the character's jersey tinted if that's possible.
Thanks for the hope :) It's definatley coming along nicely, albiet slowly. The 40 hour/week job doesn't leave a lot of free time for game work. Once I get rich off of Cosmic Lacrosse it will be smooooth sailing for the next game though ;)
Torque Owner Dan Pascal