1. 程式人生 > >UUNITY3D外掛InControl的簡單使用_安卓端連線藍芽手柄

UUNITY3D外掛InControl的簡單使用_安卓端連線藍芽手柄

由於專案需要,要在安卓端連線藍芽手柄,找了一個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<InputReciverServer> recivers = new List<InputReciverServer>();

	//新增對訂閱號列表的維護操作
	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);
			}
		}
	}

}

然後是主要的部分,也是唯一呼叫InControl的地方
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<GameObject> reciveGo = new List<GameObject>();

    void Start()
    {
        //註冊訂閱者
        foreach (var go in reciveGo)
        {
            var irs = go.GetComponents<InputReciverServer>();
            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中具體的使用了

一,設定InControl模式

UNITY選單點選Edit->Project Setting->InControl->setup就可以設定好了,前提是已經匯入了外掛

二,建立管理器

GameObject->Create Other->InControl->Manager即可完成建立



三,使用工具,建立空物體,將前面寫好的InputTool指令碼掛載上去


四,註冊成觀察者,接收按鍵事件,將實現了InputReciverServer的指令碼掛載到任意物體上,並將該物體託進上面InputTool的Recive Go裡面即可,這了可以接受多個觀察者


完成以上幾步,打包到安卓手機上就可以接受藍芽手柄的按鍵事件了,我這邊使用了一個Text來顯示按鍵的型別


看一下效果