由于项目需要,要在安卓端连接蓝牙手柄,找了一个unity上专门用来处理手柄连接的插件InControl,网上找了一圈,教程都很不明确,花了一点时间研究了一下,顺便封装了一下,在这记录一下。
InControl: Introduction - Gallant Games http://www.gallantgames.com/pages/incontrol-introduction
这个是这个插件在gallantgames上面的地址,有一些介绍和入门教程,有兴趣可以去看一下,这个插件有很多适用场合,这里不多做介绍,只说安卓上面的连接。
我用的蓝牙手柄是基于HID协议的,通过一点映射对照,下面是一些简单的映射关系:
以上是基于HID协议的手柄映射情况,其他手柄可以使用插件提供的一个test测试按键的映射关系。
言归正传,直接进入代码:
按键接受类需要实现的接口
using UnityEngine;
using System.Collections;
/**
* 按键输入类接收者必须实现的接口
* */
public interface InputReciverServer{
void reciveAction(InputTool.INPUT_TYPE type);
}
简单的实现类
using UnityEngine;
using System.Collections;
using InControl;
using UnityEngine.UI;
public class Test2 : MonoBehaviour,InputReciverServer{
public Text text;
//有按键按下会执行这个方法,参数是按键的类型
public void reciveAction(InputTool.INPUT_TYPE type) {
text.text = type.ToString();
}
}
再来看一下,发送方的抽象类
using UnityEngine;
using System.Collections.Generic;
/**
* 输入抽象类
* */
public abstract class InputServer : MonoBehaviour{
// 保存订阅者列表
private List recivers = new List();
//新增对订阅号列表的维护操作
public void addRecive(InputReciverServer ob)
{
recivers.Add(ob);
}
public void removeRecive(InputReciverServer ob)
{
recivers.Remove(ob);
}
/**
* 通知所有的订阅者
* */
public void broadCast(InputTool.INPUT_TYPE type)
{
foreach (InputReciverServer ob in recivers)
{
if (ob != null)
{
ob.reciveAction(type);
}
}
}
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using InControl;//使用InControl需要导入
public class InputTool : InputServer{
//保存InputTool的唯一实例
public static InputTool inputTool;
private InputTool() {}
//保存input接收者的具体游戏对象
public List reciveGo = new List();
void Start()
{
//注册订阅者
foreach (var go in reciveGo)
{
var irs = go.GetComponents();
foreach (var ir in irs)
{
addRecive(ir);
}
}
}
//获取InputTool实例的唯一方法
public static InputTool getInstance() {
if (inputTool == null)
inputTool = new InputTool();
return inputTool;
}
void Update () {
InputDevice id = InputManager.ActiveDevice;
//左摇杆
if (id.GetControl(InputControlType.LeftStickLeft))
{
broadCast(INPUT_TYPE.LEFT_STICK_LEFT);
}
if (id.GetControl(InputControlType.LeftStickRight))
{
broadCast(INPUT_TYPE.LEFT_STICK_RIGHT);
}
if (id.GetControl(InputControlType.LeftStickUp))
{
broadCast(INPUT_TYPE.LEFT_STICK_UP);
}
if (id.GetControl(InputControlType.LeftStickDown))
{
broadCast(INPUT_TYPE.LEFT_STICK_DOWN);
}
//ABXY
if (id.GetControl(InputControlType.Button0))
{
broadCast(INPUT_TYPE.MENU_A);
}
if (id.GetControl(InputControlType.Button1))
{
broadCast(INPUT_TYPE.MENU_B);
}
if (id.GetControl(InputControlType.Button2))
{
broadCast(INPUT_TYPE.MENU_X);
}
if (id.GetControl(InputControlType.Button3))
{
broadCast(INPUT_TYPE.MENU_Y);
}
//左方向键
if (id.GetControl(InputControlType.Analog4).Value < 0)
{
broadCast(INPUT_TYPE.DIRECTION_LEFT);
}
if (id.GetControl(InputControlType.Analog4).Value > 0)
{
broadCast(INPUT_TYPE.DIRECTION_RIGHT);
}
if (id.GetControl(InputControlType.Analog5).Value < 0)
{
broadCast(INPUT_TYPE.DIRECTION_UP);
}
if (id.GetControl(InputControlType.Analog5).Value > 0)
{
broadCast(INPUT_TYPE.DIRECTION_DOWN);
}
//右摇杆
if (id.GetControl(InputControlType.Analog2).Value < 0)
{
broadCast(INPUT_TYPE.RIGHT_STICK_LEFT);
}
if (id.GetControl(InputControlType.Analog2).Value > 0)
{
broadCast(INPUT_TYPE.RIGHT_STICK_RIGHT);
}
if (id.GetControl(InputControlType.Analog3).Value < 0)
{
broadCast(INPUT_TYPE.RIGHT_STICK_UP);
}
if (id.GetControl(InputControlType.Analog3).Value > 0)
{
broadCast(INPUT_TYPE.RIGHT_STICK_DOWN);
}
if (id.GetControl(InputControlType.Button10))
{
broadCast(INPUT_TYPE.START);
}
if (id.GetControl(InputControlType.Button11))
{
broadCast(INPUT_TYPE.SELECT);
}
}
//定义所有的按键类型
public enum INPUT_TYPE {
LEFT_STICK_LEFT,
LEFT_STICK_RIGHT,
LEFT_STICK_UP,
LEFT_STICK_DOWN,
DIRECTION_LEFT,
DIRECTION_RIGHT,
DIRECTION_UP,
DIRECTION_DOWN,
RIGHT_STICK_LEFT,
RIGHT_STICK_RIGHT,
RIGHT_STICK_UP,
RIGHT_STICK_DOWN,
MENU_A,
MENU_B,
MENU_X,
MENU_Y,
START,
SELECT
}
}
一,设置InControl模式
UNITY菜单点击Edit->Project Setting->InControl->setup就可以设置好了,前提是已经导入了插件
二,创建管理器
GameObject->Create Other->InControl->Manager即可完成创建
三,使用工具,创建空物体,将前面写好的InputTool脚本挂载上去
四,注册成观察者,接收按键事件,将实现了InputReciverServer的脚本挂载到任意物体上,并将该物体托进上面InputTool的Recive Go里面即可,这了可以接受多个观察者
完成以上几步,打包到安卓手机上就可以接受蓝牙手柄的按键事件了,我这边使用了一个Text来显示按键的类型
看一下效果