Adam's Lair Forum

game development and casual madness
It is currently 2017/04/24, 09:19

All times are UTC + 1 hour [ DST ]




Post new topic Reply to topic  [ 25 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
PostPosted: 2016/10/23, 18:50 
Member
Member

Joined: 2016/06/30, 03:38
Posts: 58
Location: Portugal
Role: Hobbyist
Hi, this is really neat but it doesn't seem to work for me :(

using MFEP.Duality.Plugins.InputPlugin;, doesn't work, a red line appears and the ide tells me "using directive is unnecessary" and I can't access the plugin's methods, nothing regarding the plugin appears on autocomplete when i type in using

I have installed the plugin and even set up keys in the visual editor.
I'm using Xamarin Studio if it helps.

Any idea on how can this be?


Top
 Profile  
 
PostPosted: 2016/10/23, 19:23 
Member
Member

Joined: 2015/12/27, 00:33
Posts: 76
Role: Hobbyist
Add it as a dependency in you plugin project. (just refer to the DLL)


Top
 Profile  
 
PostPosted: 2016/10/23, 20:11 
Veteran Member
Veteran Member
User avatar

Joined: 2016/01/10, 10:56
Posts: 144
Location: Budapest
Role: Hobbyist
Yes, thanks, ChatPion for the reply. ^^
Here's a quickly made guide, how to do it in Xamarin Studio:

Enjoy, and if you encounter any problems or bugs, feel free to ask! ^^


Top
 Profile  
 
PostPosted: 2016/10/23, 21:16 
Member
Member

Joined: 2016/06/30, 03:38
Posts: 58
Location: Portugal
Role: Hobbyist
loeller wrote:
Yes, thanks, ChatPion for the reply. ^^
Here's a quickly made guide, how to do it in Xamarin Studio:

Enjoy, and if you encounter any problems or bugs, feel free to ask! ^^


Thanks for the guide :D


Top
 Profile  
 
PostPosted: 2016/11/20, 19:49 
Veteran Member
Veteran Member
User avatar

Joined: 2016/01/10, 10:56
Posts: 144
Location: Budapest
Role: Hobbyist
I've updated the plugin to version 1.1. No big changes, but under the hood, major refactoring took place. The editor felt a little buggy here and there, that's been resolved. The new version is compatible with the existing keyMapping.xml files, and the basic API remained untouched. The functions for adding buttons programatically have changed, but I suppose not a lot of people used them, and it's easy to update your code.

The new API:
Code:
using ButtonTuple = System.Tuple<string, Duality.Input.Key[]>;

namespace MFEP.Duality.Plugins.InputPlugin
{
   public static class InputManager
   {

      public static ButtonTuple[] Buttons;
      public static event Action<ButtonTuple> ButtonAdded;
      public static event Action<string> ButtonRemoved;
      public static event Action<string, string> ButtonRenamed;
      public static event Action<string, Key> KeyAddedToButton;
      public static event Action<string, Key> KeyRemovedFromButton;

      public static void RegisterButton ();

      public static bool RegisterButton (ButtonTuple newButton);

      public static bool RemoveButton (string name);

      public static bool AddKeyToButton (string name, Key newKey);

      public static bool RemoveKeyFromButton (string name, Key key);

      public static bool RenameButton (string originalName, string newName);

      public static bool IsButtonPressed (string name);

      public static bool IsButtonHit (string name);

      public static bool IsButtonReleased (string name);
   }
}


I hope is clear enough. If it's not, please make your suggestions! Feedback is always appreciated.


Top
 Profile  
 
PostPosted: 2017/01/02, 03:18 
Member
Member

Joined: 2016/06/30, 03:38
Posts: 58
Location: Portugal
Role: Hobbyist
Oh dear, I updated the plugin and now my code broke, that'll teach me to read patchnotes :/
I'm not getting how to fix the stuff so imma need some help.

I can't use Virtualbutton anymore, it gives me a "inaccessible due to protection level" error, but RegisterButton still works fine and there are no errors when i check if they (buttons i make in the bellow code) are being pressed.
Code:
public class InputMaster : Component, ICmpInitializable, ICmpUpdatable
   {

      public VirtualButton mForward { get; set; }
      public VirtualButton mBackwards { get; set; }
      public VirtualButton strafeRight { get; set; }
      public VirtualButton strafeLeft { get; set; }
      public VirtualButton rotateRight { get; set; }
      public VirtualButton rotateLeft { get; set; }

      public VirtualButton mainAttack { get; set; }
      public VirtualButton shipAbility { get; set; }
      public VirtualButton item { get; set; }

      public bool customSet { get; set;} = false;

      public void OnInit(InitContext context)
      {
         if (context == InitContext.Activate)
         {
            if (!customSet)
            {

               mForward = new VirtualButton("Fly Forward", Key.W);
               mBackwards = new VirtualButton("Fly Backwards", Key.S);
               strafeRight = new VirtualButton("Strafe Right", Key.D);
               strafeLeft = new VirtualButton("Strafe Left", Key.A);
               rotateRight = new VirtualButton("Rotate Right", Key.E);
               rotateLeft = new VirtualButton("Rotate Left", Key.Q);

               mainAttack = new VirtualButton("Fire", Key.J);
               shipAbility = new VirtualButton("Ship Ability", Key.O);
               item = new VirtualButton("Use Item", Key.P);



            }
            InputManager.RegisterButton(mForward);
            InputManager.RegisterButton(mBackwards);
            InputManager.RegisterButton(strafeRight);
            InputManager.RegisterButton(strafeLeft);
            InputManager.RegisterButton(rotateRight);
            InputManager.RegisterButton(rotateLeft);

            InputManager.RegisterButton(mainAttack);
            InputManager.RegisterButton(shipAbility);
            InputManager.RegisterButton(item);



         }
      }


And, GetVirtualButton also kicked the bucket,
Code:
   public void OnInit(InitContext context)
      {
         text = this.GameObj.GetComponent<TextRenderer>();
         tutorial = string.Format("[{0}{1}{2}{3}] To Fly! /n" +
                            "[{4}] To Light'em Up!",
                                  InputManager.GetVirtualButton("Fly Forward").AssociatedKeys[0].ToString(),
                                  InputManager.GetVirtualButton("Strafe Left").AssociatedKeys[0].ToString(),
                                  InputManager.GetVirtualButton("Fly Backwards").AssociatedKeys[0].ToString(),
                                  InputManager.GetVirtualButton("Strafe Right").AssociatedKeys[0].ToString(),
                                  InputManager.GetVirtualButton("Fire").AssociatedKeys[0].ToString(),
                                  InputManager.);
         

         opacity = 180;
      }

How do i go about replacing my code so it works the same with the new plugin version?


Top
 Profile  
 
PostPosted: 2017/01/02, 15:14 
Veteran Member
Veteran Member
User avatar

Joined: 2016/01/10, 10:56
Posts: 144
Location: Budapest
Role: Hobbyist
Hey!
Thank you for the report on your problems, it made me realize several issues with the plugin.
  1. The documentation is out of date. Version 1.1 broke your code, but since then, there is a version 1.2, which convoluted things even more, and is completely undocumented, I even missed to write a post here. (insert lazyness, exams & other excuses here)
  2. As I mocked up your logic with the new API, I found that using the new API is nothing but intuitive.

That means that it can be be done what you need, it's just ugly. However, if you don't change the mapping at runtime, I strongly recommend adding the buttons statically via the Input Mapping menu. It's available under the View menu (if you don't have it, the Editor Plugin is probably not installed). If you change the buttons runtime, you need to write code for that of course. The following sample demonstrates it: I assumed that you only need one Key for a Button.
Code:
public class InputMaster : Component, ICmpInitializable
{
    public bool CustomSet { get; set; } = false;

    public Key FlyForwardKey { get; set; }
    public Key FlyBackwardsKey { get; set; }

    public void OnInit (InitContext context)
    {
        if (context == InitContext.Activate) {
            InputManager.RemoveButton ("Fly Forward");
            InputManager.RemoveButton ("Fly Backwards");
            if (!CustomSet) {
                InputManager.RegisterButton (new Tuple<string, KeyValue[]> ("Fly Forward", new[] { new KeyValue (Key.M) }));
                InputManager.RegisterButton (new Tuple<string, KeyValue[]> ("Fly Backwards", new[] { new KeyValue (Key.S) }));
            } else {
                InputManager.RegisterButton (new Tuple<string, KeyValue[]> ("Fly Forward", new [] {new KeyValue (FlyForwardKey)}));
                InputManager.RegisterButton (new Tuple<string, KeyValue[]> ("Fly Backwards", new [] {new KeyValue(FlyBackwardsKey)}));
            }
        }
    }
}

Some important points here:
  1. Before registering the buttons, they need to be removed. This is not the nicest solution, because at first, there's none to remove, which yields an error message. On the other hand, without removing the existing buttons, they won't be overwritten if the properties change between runs. (bad design decision?)
  2. By version 1.2, the KeyValue struct is introduced, to handle mouse buttons and keyboard keys uniformly.

Because of VirtualButton is not accessible now, you can only get the list of names associated to keys by the InputManager.Buttons property. Getting the first Key associated to a button name is like this (using LINQ):
Code:
string flyForwardKeyName = InputManager.Buttons.First (button => button.Item1 == "Fly Forward").Item2[0].Key.ToString ();


Sure, that is awful. I ought to get rid of these System.Tuples too.
To sum it up, even though v1.1 and v1.2 is a significant step forward if only static mapping is used, it's not very intuitive, when it's about dynamically changing the buttons.


Top
 Profile  
 
PostPosted: 2017/01/04, 21:57 
Member
Member

Joined: 2016/06/30, 03:38
Posts: 58
Location: Portugal
Role: Hobbyist
I was looking to allow remaping at runtime that's why i didnt use the visual editor.

loeller wrote:

Because of VirtualButton is not accessible now, you can only get the list of names associated to keys by the InputManager.Buttons property. Getting the first Key associated to a button name is like this (using LINQ):
Code:
string flyForwardKeyName = InputManager.Buttons.First (button => button.Item1 == "Fly Forward").Item2[0].Key.ToString ();



what. :/

I don't understand how would i go about detecting if the keys are pressed?


Top
 Profile  
 
PostPosted: 2017/01/04, 23:53 
Veteran Member
Veteran Member
User avatar

Joined: 2016/01/10, 10:56
Posts: 144
Location: Budapest
Role: Hobbyist
Eldir wrote:
what. :/

As I said, it's awful, sorry about that. It'll probably change soon, I just finished my exams, and finally have time to clean things up a little.

Let's break up that expression a bit: InputManager.Buttons is an array of System.Tuple types, which contains a string, the button name at Item1, and a KeyValue array on Item2, which are the keyboard keys and mouse buttons associated to the particular name.

Now we want to select an item from that Buttons array, the one which holds "Fly Forward" in its Item1. We do this using LINQ, a very useful C# tool, which enables a functional style of handling of collections. The First LINQ function selects the first entry in the collection, which fulfills the predicate, in our case, the predicate is a lambda expression (a so called anonymous function) which returns true if the Item1, the name of the button is "Fly Forward".

With Item2 we select the array of KeyValues associated to that virtual button. Of them, select the first (0th), cast it to Key and ToString.

Again. that's an awful lot of shit to get the the buttons associated. If you'd like to skip this hassle, and get back the previous version of the plugin, edit the PackageConfig.xml file directly. However, the new release is due in a week.
Code:
<Package id="MFEP.Duality.Plugins.InputPlugin" version="1.0.4.0" />
<Package id="MFEP.Duality.Editor.Plugins.InputPlugin" version="1.0.4.0" />

Eldir wrote:
I don't understand how would i go about detecting if the keys are pressed?

This is because I intended to do all the work through the InputManager, thus you don't need to carry references of the VirtualButtons.
This is how you do it:
Code:
if (InputManager.IsButtonPressed("Fly Forward")) {
    ...
}


Top
 Profile  
 
PostPosted: 2017/01/06, 15:14 
Veteran Member
Veteran Member
User avatar

Joined: 2016/01/10, 10:56
Posts: 144
Location: Budapest
Role: Hobbyist
OK, some progress has been made to clean up stuff a bit. A new branch on GitHub's been made, containing the changes. Before merging and releasing it as a package, I'd like to ask for opinions - any critisism is appreciated.

These commits only change how the input mapping can be modified by code. The way static mappings work, and the user interface is not affected. Once the decisions are finalized, a new user guide is going to be written too.

The philosophy of the plugin is to do every related operation via the InputManager static class.

The list of changes with some explanations:
  • Replaced System.Tuple<string, KeyValue[]> with custom class - Internally, the Virtual Buttons are stored in a dictionary with a key of their name (a string), thus they don't know their own name. However, when interfacing with the InputManager, a container class is needed, which contains both the name of the button, and the keys associated with it. Originally, it was done by System.Tuple<string, KeyValue[]>, but calling its Item1 and Item2 property all the time worsened the readability of the code. The new class ButtonTuple solves this issue by having its properties named correctly. It also has multiple overloaded constructors, to make its creation easier.
  • InputManager.Buttons is IEnumerable - Before, it was an array, but since its purpose is to enumerate through all the buttons, it's better be an IEnumerable. In some cases this improves performance, but I doubt that it's noticable with a reasonable amount of buttons.
  • AddToButton and RemoveFromButton names are uniform - There were multiple, similarly named functions in InputManager, such as AddKeyToButton, AddMouseButtonToButton, etc. It's more elegant to have the same function to be overloaded with multiple argument types.
  • Can overwrite existing buttons with RegisterButton - It's possible now, although a warning message is printed.
  • GetKeysOfButton (string) fn - It was particulary difficult to get the keys associated with a button name before (see my former post). This function just makes it easy, returns the array of KeyValues associated with the button name.
  • Use cast operators in KeyValue instead of properties - The KeyValue struct was introduced in order to handle keyboard keys and mouse buttons uniformly. It could have been done via inheritance, but it seemed a bit overkill for the task. Instead, the struct has an integer field, which it can convert to Duality.Input.Key or Duality.Input.MouseButton. The conversion was done by properties, but I think using casting operators is more straightforward for that. The conversions can throw InvalidCastException if a KeyValue containing a Duality.Input.Key is casted to Duality.Input.MouseButton and vice versa.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 25 posts ]  Go to page Previous  1, 2, 3  Next

All times are UTC + 1 hour [ DST ]


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Jump to:  
Powered by phpBB® Forum Software © phpBB Group