mirror of
https://github.com/ConjureETS/PillowFight.git
synced 2026-03-24 17:10:59 +00:00
206 lines
6.1 KiB
C#
206 lines
6.1 KiB
C#
using UnityEngine;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System;
|
|
|
|
/*
|
|
Strongly inspired from Mike Lewis' excellent post about input handling
|
|
http://www.gamedev.net/blog/355/entry-2250186-designing-a-robust-input-handling-system-for-games/
|
|
*/
|
|
|
|
namespace InputHandler
|
|
{
|
|
public class InputMapper
|
|
{
|
|
// Right now, the only active context is the peek of the stack, but when we will need multiple contexts at once, this is going to be useful
|
|
private Dictionary<string, InputContext> _contexts;
|
|
private Stack<InputContext> _activeContexts;
|
|
|
|
private List<Action<MappedInput>> _callbacks;
|
|
|
|
private MappedInput _currentFrameMappedInput;
|
|
|
|
public InputMapper(Dictionary<string, InputContext> contexts)
|
|
{
|
|
_contexts = contexts;
|
|
_activeContexts = new Stack<InputContext>();
|
|
_callbacks = new List<Action<MappedInput>>();
|
|
_currentFrameMappedInput = new MappedInput();
|
|
}
|
|
|
|
public void Dispatch()
|
|
{
|
|
foreach (Action<MappedInput> callback in _callbacks)
|
|
{
|
|
callback(_currentFrameMappedInput);
|
|
}
|
|
}
|
|
|
|
public void PushActiveContext(string name)
|
|
{
|
|
InputContext context = _contexts[name];
|
|
|
|
if (_activeContexts.Count == 0 || _activeContexts.Peek().Name != name)
|
|
{
|
|
_activeContexts.Push(context);
|
|
}
|
|
}
|
|
|
|
public void PopActiveContext()
|
|
{
|
|
if (_activeContexts.Count != 0)
|
|
{
|
|
_activeContexts.Pop();
|
|
}
|
|
}
|
|
|
|
public void ClearActiveContexts()
|
|
{
|
|
_activeContexts.Clear();
|
|
}
|
|
|
|
public void AddCallback(Action<MappedInput> callback)
|
|
{
|
|
_callbacks.Add(callback);
|
|
}
|
|
|
|
public void SetRawButtonState(int button, bool pressed, bool previouslyPressed)
|
|
{
|
|
string action = GetActionForButton(button);
|
|
string state = GetStateForButton(button);
|
|
|
|
if (pressed)
|
|
{
|
|
if (!previouslyPressed && action != null)
|
|
{
|
|
_currentFrameMappedInput.Actions.Add(action);
|
|
return;
|
|
}
|
|
|
|
if (state != null)
|
|
{
|
|
_currentFrameMappedInput.States.Add(state);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Uncomment if we start to have problems
|
|
//RemoveButtonFromLists(button);
|
|
}
|
|
|
|
public void SetRawAxisValue(int axis, float value)
|
|
{
|
|
// TODO: Have contexts for every single player?
|
|
|
|
// TODO: Use the commented code below instead when we will want multiple contexts to be available at the same time (maybe for when the player holds a weapon?). We'll keep it simple for now.
|
|
|
|
/*
|
|
foreach (InputContext activeContext in _activeContexts)
|
|
{
|
|
InputConstants.Ranges range = activeContext.GetRangeForAxis(axis);
|
|
|
|
if (range != InputConstants.Ranges.None)
|
|
{
|
|
// We only want the first active "range behaviour" of the player to handle the ranges values, since we don't want multiple actions to react to it
|
|
_mappedInputs[playerIndex].Ranges[range] = value;
|
|
break;
|
|
}
|
|
}*/
|
|
|
|
if (value != 0f)
|
|
{
|
|
string range = null;
|
|
|
|
if (_activeContexts.Count != 0)
|
|
{
|
|
range = _activeContexts.Peek().GetRangeForAxis(axis);
|
|
}
|
|
|
|
if (range != null)
|
|
{
|
|
_currentFrameMappedInput.Ranges[range] = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void ResetInputs()
|
|
{
|
|
_currentFrameMappedInput.Clear();
|
|
}
|
|
|
|
#region Helper methods
|
|
|
|
private string GetActionForButton(int button)
|
|
{
|
|
// TODO: Have contexts for every single player?
|
|
|
|
// TODO: Use the commented code below instead when we will want multiple contexts to be available at the same time (maybe for when the player holds a weapon?). We'll keep it simple for now.
|
|
|
|
/*
|
|
foreach (InputContext activeContext in _activeContexts)
|
|
{
|
|
InputConstants.Actions action = activeContext.GetActionForButton(button);
|
|
|
|
if (action != InputConstants.Actions.None)
|
|
{
|
|
return action;
|
|
}
|
|
}*/
|
|
|
|
string action = null;
|
|
|
|
if (_activeContexts.Count != 0)
|
|
{
|
|
action = _activeContexts.Peek().GetActionForButton(button);
|
|
}
|
|
|
|
return action;
|
|
}
|
|
|
|
private string GetStateForButton(int button)
|
|
{
|
|
// TODO: Have contexts for every single player?
|
|
|
|
// TODO: Use the commented code below instead when we will want multiple contexts to be available at the same time (maybe for when the player holds a weapon?). We'll keep it simple for now.
|
|
|
|
/*
|
|
foreach (InputContext activeContext in _activeContexts)
|
|
{
|
|
InputConstants.States state = activeContext.GetStateForButton(button);
|
|
|
|
if (state != InputConstants.States.None)
|
|
{
|
|
return state;
|
|
}
|
|
}*/
|
|
|
|
string state = null;
|
|
|
|
if (_activeContexts.Count != 0)
|
|
{
|
|
state = _activeContexts.Peek().GetStateForButton(button);
|
|
}
|
|
|
|
return state;
|
|
}
|
|
|
|
private void RemoveButtonFromLists(int button)
|
|
{
|
|
string action = GetActionForButton(button);
|
|
string state = GetStateForButton(button);
|
|
|
|
if (action != null)
|
|
{
|
|
_currentFrameMappedInput.Actions.Remove(action);
|
|
}
|
|
|
|
if (state != null)
|
|
{
|
|
_currentFrameMappedInput.States.Remove(state);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|