[뇌파 VR게임] #4 Unity 앱에서 뇌파값 읽기 테스트

in kr •  6 years ago 

이전글 - [뇌파 VR게임] #3 뇌파 Headset 연결2 - Android 라이브러리 만들기


[게임 화면]


이전글에서 Android 라이브러리 파일을 만들었습니다. 이제 이것을 Unity로 불러들여서 동작하는지 테스트 해보겠습니다. 이번에 다루려고 하는 것은 이런 겁니다.

  • 2D Unity 테스트 앱 생성
  • Android 라이브러리 import
  • Unity 앱에서 뇌파 센서 연결 및 Meditation 값 읽기 코딩
  • 앱 빌드

2D Unity 앱

아래와 같이 2D로 Unity 앱을 하나 생성합니다.
image.png

여기서는 간단히 Canvas를 하나 만들고 그 위에 Message(Text) 하나와 버튼(Button)을 만들었습니다. 만드는 방법은 간단하기 때문에 생략하겠습니다. VR용 UI 만드는 법은 아래 내용을 참고하세요.
[Unity VR과 Android BLE] #4 Unity 메뉴 만들기

Android 라이브러리 import

아래와 같은 위치에 이전글에서 생성한 aar 파일을 import 합니다. 파일을 폴더 위로 드래그 앱 드랍해도 됩니다. 중요한 것은 저장되는 위치입니다. 반드시 Assets->Plugins->Android 폴더 밑에 있어야 합니다.
image.png

위 그림을 보면 해당 폴더에 AndroidManifest.xml 파일이 보입니다. 이건 원래는 없습니다. Unity 앱에서 안드로이드 폰의 블루투스 장치를 사용할 것이기 때문에 권한 설정이 필요합니다. 이를 위해 AndroidManifest.xml 파일이 필요합니다. Unity 자체적으로 AndroidManifest.xml파일을 가지고 있고, 위 폴더에 있는 AndroidManifest.xml 파일의 내용을 병합해서 안드로이드 앱을 빌드하게 되어 있습니다. 이와 관련하여 자세한 내용은 아래를 참고하세요.
[Unity VR과 Android BLE] #9 Unity에서 BLE 장치 제어

아래 코드는 Unity의 AndroidManifest.xml파일을 복사해서 블루투스 관련 권한 부분만 추가한 것입니다.

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.unity3d.player"
    xmlns:tools="http://schemas.android.com/tools"
    android:installLocation="preferExternal">
    <supports-screens
        android:smallScreens="true"
        android:normalScreens="true"
        android:largeScreens="true"
        android:xlargeScreens="true"
        android:anyDensity="true"/>


  <uses-permission android:name="android.permission.BLUETOOTH"/>
  <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
  
    <application
        android:theme="@style/UnityThemeSelector"
        android:icon="@mipmap/app_icon"
        android:label="@string/app_name">
        <activity android:name="com.unity3d.player.UnityPlayerActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
        </activity>
    </application>
</manifest>

Android Plugin 코딩

위에서 import 한 Android 라이브러리를 이용해서 Unity에서 뇌파 센서를 연결하고 값을 읽어 오는 부분을 코딩합니다.
여기서는 Hierarchy창에 NeuroskyPlugin이라는 GameObject를 만들어서 아래와 같이 Message UI를 연결했습니다.
image.png
위 그림을 보면 AndroidWrapper라는 스크립트를 사용하고 있습니다. 이 스크립트에 대한 자세한 설명은 아래 내용을 참고하세요. 아래 소스 코드에 대한 설명은 따로 하지 않겠습니다.
[Unity VR과 Android BLE] #8 안드로이드 Plugin

이 스크립트에서 Android 라이브러리를 불러들여서 뇌파 센서에 연결하고 값을 읽어오게 합니다.
코드는 다음과 같습니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class AndroidWrapper : MonoBehaviour {

    // android object
    private AndroidJavaObject AndroidObject= null;
    // text 
    public Text Message;
    //
    private bool connected_=false;

    private AndroidJavaObject GetJavaObject()
    {
        if (AndroidObject == null)
        {
            AndroidObject = new AndroidJavaObject("club.etain.neuroskymodule.NeuroskyControl");
        }
        return AndroidObject;
    }

    // Use this for initialization
    void Start () {
        Debug.Log("Start");

        // Retrieve current Android Activity from the Unity Player
        AndroidJavaClass jclass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject activity = jclass.GetStatic<AndroidJavaObject>("currentActivity");

        // Pass reference to the current Activity into the native plugin,
        GetJavaObject().Call("setActivity", activity);

        Message.text = GetJavaObject().Call<string>("init");

        OnConnect();
    }

    public void OnConnect()
    {
        Debug.Log("OnConnect");
        GetJavaObject().Call("connect");
        Message.text = "connecting...";
    }

    private void CheckConnection()
    {
        Debug.Log("OnCheckConnection");
        connected_ = GetJavaObject().Call<bool>("isConnected");
        if (connected_)
            Message.text = "connected";
        else
            Message.text = "check connection...";
    }

    // Update is called once per frame
    void Update () {
        if (!connected_)
        {
            CheckConnection();
        }
        else
        {
            Message.text = GetJavaObject().Call<int>("getMeditationValue").ToString();
        }
        
    }
}

위 코드를 보면, Start() 함수에서 OnConnect()함수를 바로 호출하고 있습니다. 즉 버튼으로 구현하지 않고 그냥 앱을 시작하자마자 뇌파 센서에 연결을 시도하는 것입니다. 왜 이렇게 했냐면, Neurosky 뇌파 센서에 연결하는데만 약 30초가 걸립니다. 실제 동작하는 앱을 만들 때는 이렇게 앱 실행하자마자 연결을 시도해야지만 앱이 시작하는 시간을 단축시킬 수 있습니다.

이제 다음은 Unity 앱을 빌드하는 것입니다.

Build Setting

Unity에서 플랫폼을 안드로이드로 바꾸고 Build Settings을 아래와 같이 합니다. 참고로 Build Settings 화면에 안드로이드 Build System을 선택하는 옵션이 보입니다. Internal과 gradle 있는데, 그 차이는 아래 내용을 참고하세요.
https://stackoverflow.com/questions/46798774/unity-build-systems-internal-vs-gradle
요약하면 Gradle 옵션을 사용하면 추가적인 빌드 옵션을 선택할 수 있다고 합니다. 왜 이걸 여기서 설명하냐면, 나중에 Gradle로 선택하고 앱을 빌드하면 종종 에러(java heap memory)가 발생합니다. 주로 앱 사이즈가 큰 것일 때 발생하는 거 같습니다. 이 때, Build System을 Internal로 하면 이 문제가 없어집니다.

여기서 Player Setting도 기본적으로 해줍니다. Player Setting은 Package Name과 Android SDK 버전 등을 설정해야 합니다. 나중에 VR앱을 만들 것인데 이때는 XR Settings도 필요합니다.
image.png

자. 이제 빌드해 봅니다. 앗! 아래와 같은 에러가 발생합니다.
image.png

pre-dex 할 수 없다는 메시지가 보입니다. 이유는 정확히 모르겠지만 Player Settings에서 Android SDK 버전을 24에서 26으로 하면 에러가 사라집니다.
image.png

그럼, 안드로이드 폰을 연결하고 Build and Run을 실행합니다. 그리고 뇌파 센서 전원을 켜고 머리에 착용하고 연결을 기다립니다. 앱이 안드로이드 폰에 설치되고 나면 아래와 같이 연결화면이 나옵니다.
image.png
위 그림을 보면 아래쪽에 Toast 메시지도 잘 나타나는 걸 볼 수 있습니다. 참고로 VR에서는 Toast 메시지가 안됩니다. (평면에 표시하는 메시지이기 때문. VR에서는 3차원 공간에 표시해야 함)

그런 후 약 30초 후에 아래와 같이 값이 나옵니다. 여기서 나타나는 값은 Meditation값입니다. 얼마나 명상을 잘하고 있는지, 뇌에서 알파파가 잘 나오는지 알려주는 수치입니다.
image.png


우여곡절 끝에 Unity에서 뇌파값을 읽게 됐습니다. Android 라이브러리로 만들었기 때문에, 뇌파 센서말고 안드로이드 폰의 기능들을 라이브러리에 추가하여 같이 사용할 수 있습니다. 그런데 안드로이드 볼륨 컨트롤을 추가해봤는데, 에러가 발생했습니다. 이건 일단 넘어갑니다. 나중에 필요하면 방법을 찾아봐야 겠습니다.

지금까지는 매우 지루한 내용이었죠? 뇌파센서도 없어서 테스트도 못하는데, 장황하게 뇌파값을 읽는 부분을 설명했으니 말이죠. 이렇게 글을 쓰는 것은 비슷한 문제때문에 고생하는 분들을 위한 것이고요, 한편으로는 제가 다시 사용하기 위해 기록으로 남기기 위함입니다.

다음부터는 조금 재미난 내용들이 나오겠네요. 바로 뇌파를 이용해서 초능력 게임을 만들어 보겠습니다.


오늘의 실습: 뇌파로 초능력을 사용하는 걸까요? 초능력을 사용하면 뇌파가 바뀌는 걸까요?

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!