I'm coding a small game on Unity to control with the Emotiv Epoc headset. However, as I'm new to Unity, I'm having some trouble setting everything up to connect the device with my game.
I downloaded the SDK from Github and tried the sample project and worked fine, but I can't translate that to my own project. I opened an issue on that github repository and I was suggested to use this new plugin.
What I see is that there's a file called EdkDll.cs that contains all the functions that I'll need in my project. I suppose that I have to build it to create the .dll that will be used on Unity, but when I try to do so on Visual Studio or MonoDevelop (and after adding the reference to UnityEngine.dll), a big part of the EdkDll.cs goes gray and I get an error on the calls to the grayed functions ("... doesn't exist in the current context"). I tried changing the .NET framework from 3.5 to other, but that didn't work either.
I think it can't be so complicated and there must be something I'm doing wrong, or maybe there's another way of getting the EdkDll.cs functions to be available from the scripts in my project.
EDIT:
In the example provided in the SDK (here), there's a script that controls the connection to the device (EmotivCtrl.cs) and another to control the player (playerCtrl.cs), and also others to control the camera and a text window, but I think I should be able to make my project work without those. The thing is that I don't understand where or how is the connection script called, because if I include it in the assets folder of my project and put a print inside the Awake method, it never shows.
My guess is that is called here (movm.cs): EmoEngine.Instance.EmoStateUpdated += new EmoEngine.EmoStateUpdatedEventHandler(engine_EmoStateUpdated);
, but the function engine_EmoStateUpdated
doesn't seem to be accessed either.
These are the scripts to control the device and the player of my project:
movm.cs (to control the player):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class movm : MonoBehaviour
{
private Rigidbody rb;
EmoEngine engine;
void engine_EmoStateUpdated(object sender, EmoStateUpdatedEventArgs e)
{
Debug.Log("empieza engine");
EmoState es = e.emoState;
Debug.Log("despues");
/*if (e.userId != 0)
return;*/
Debug.Log("Corrent action: " + es.MentalCommandGetCurrentAction().ToString());
if (es.MentalCommandGetCurrentAction() == EdkDll.IEE_MentalCommandAction_t.MC_PUSH)
{
//Vector3 movement = new Vector3(cam.transform.forward.x, cam.transform.forward.y, cam.transform.forward.z);
//rb.AddForce(movement * speed);
rb.AddForce(Vector3.up);
Debug.Log("Push");
}
}
// Start is called before the first frame update
void Start()
{
Debug.Log("empieza movm");
rb = GetComponent<Rigidbody>();
Debug.Log("rigid");
EmoEngine.Instance.EmoStateUpdated += new EmoEngine.EmoStateUpdatedEventHandler(engine_EmoStateUpdated);
Debug.Log("asdasd");
}
void FixedUpdate()
{
if (Input.GetKey("w"))
{
gameObject.transform.Translate(2f * Time.deltaTime, 0, 0);
}
}
}
EmotivCtrl.cs (to connect to the Emotiv Epoc device):
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
public class EmotivCtrl : MonoBehaviour {
public GameObject modal;
public Text message_box;
public InputField userName;
public InputField password;
public InputField profileName;
public static EmoEngine engine;
public static int engineUserID = -1;
public static int userCloudID = 0;
static int version = -1;
/*
* Create instance of EmoEngine and set up his handlers for
* user events, connection events and mental command training events.
* Init the connection
*/
void Awake ()
{
Debug.Log("awake");
engine = EmoEngine.Instance;
engine.UserAdded += new EmoEngine.UserAddedEventHandler (UserAddedEvent);
engine.UserRemoved += new EmoEngine.UserRemovedEventHandler (UserRemovedEvent);
engine.EmoEngineConnected += new EmoEngine.EmoEngineConnectedEventHandler (EmotivConnected);
engine.EmoEngineDisconnected += new EmoEngine.EmoEngineDisconnectedEventHandler (EmotivDisconnected);
engine.MentalCommandTrainingStarted += new EmoEngine.MentalCommandTrainingStartedEventEventHandler (TrainingStarted);
engine.MentalCommandTrainingSucceeded += new EmoEngine.MentalCommandTrainingSucceededEventHandler (TrainingSucceeded);
engine.MentalCommandTrainingCompleted += new EmoEngine.MentalCommandTrainingCompletedEventHandler (TrainingCompleted);
engine.MentalCommandTrainingRejected += new EmoEngine.MentalCommandTrainingRejectedEventHandler (TrainingRejected);
engine.MentalCommandTrainingReset += new EmoEngine.MentalCommandTrainingResetEventHandler (TrainingReset);
engine.Connect ();
Debug.Log("fini");
}
/*
* Init the user, password and profile name if you want it
*/
void Start(){
Debug.Log("START");
userName.text = "";
password.text = "";
profileName.text = "";
}
/*
* Call the ProcessEvents() method in Update once per frame
*/
void Update () {
engine.ProcessEvents ();
}
/*
* Close the connection on application exit
*/
void OnApplicationQuit() {
Debug.Log("Application ending after " + Time.time + " seconds");
engine.Disconnect();
}
/*
* Several methods for handling the EmoEngine events.
* They are self explanatory.
*/
void UserAddedEvent(object sender, EmoEngineEventArgs e)
{
message_box.text = "User Added";
engineUserID = (int)e.userId;
}
void UserRemovedEvent(object sender, EmoEngineEventArgs e)
{
message_box.text = "User Removed";
}
void EmotivConnected(object sender, EmoEngineEventArgs e)
{
Debug.Log ("conectado");
message_box.text = "Connected!!";
}
void EmotivDisconnected(object sender, EmoEngineEventArgs e)
{
message_box.text = "Disconnected :(";
}
public bool CloudConnected()
{
if (EmotivCloudClient.EC_Connect () == EdkDll.EDK_OK) {
message_box.text = "Connection to server OK";
if (EmotivCloudClient.EC_Login (userName.text, password.text)== EdkDll.EDK_OK) {
message_box.text = "Login as " + userName.text;
if (EmotivCloudClient.EC_GetUserDetail (ref userCloudID) == EdkDll.EDK_OK) {
message_box.text = "CloudID: " + userCloudID;
return true;
}
}
else
{
message_box.text = "Cant login as "+userName.text+", check password is correct";
}
}
else
{
message_box.text = "Cant connect to server";
}
return false;
}
public void SaveProfile(){
if (CloudConnected ()) {
int profileId = -1;
EmotivCloudClient.EC_GetProfileId(userCloudID, profileName.text);
if (profileId >= 0) {
if (EmotivCloudClient.EC_UpdateUserProfile (userCloudID, (int)engineUserID, profileId) == EdkDll.EDK_OK) {
message_box.text = "Profile updated";
} else {
message_box.text = "Error saving profile, aborting";
}
} else {
if (EmotivCloudClient.EC_SaveUserProfile (
userCloudID, engineUserID, profileName.text,
EmotivCloudClient.profileFileType.TRAINING) == EdkDll.EDK_OK) {
message_box.text = "Profiled saved successfully";
} else {
message_box.text = "Error saving profile, aborting";
}
}
}
}
public void LoadProfile(){
if (CloudConnected ()) {
int profileId = -1;
EmotivCloudClient.EC_GetProfileId(userCloudID, profileName.text);
if (EmotivCloudClient.EC_LoadUserProfile (
userCloudID, (int)engineUserID,
profileId,
(int)version) == EdkDll.EDK_OK) {
message_box.text = "Load finished";
}
else {
message_box.text = "Problem loading";
}
}
}
public void TrainPush(){
engine.MentalCommandSetTrainingAction((uint)engineUserID, EdkDll.IEE_MentalCommandAction_t.MC_PUSH);
engine.MentalCommandSetTrainingControl((uint)engineUserID, EdkDll.IEE_MentalCommandTrainingControl_t.MC_START);
}
public void TrainNeutral(){
engine.MentalCommandSetTrainingAction ((uint)engineUserID, EdkDll.IEE_MentalCommandAction_t.MC_NEUTRAL);
engine.MentalCommandSetTrainingControl((uint)engineUserID, EdkDll.IEE_MentalCommandTrainingControl_t.MC_START);
}
public void TrainingStarted(object sender, EmoEngineEventArgs e){
message_box.text = "Trainig started";
}
public void TrainingCompleted(object sender, EmoEngineEventArgs e){
message_box.text = "Training completed!!";
}
public void TrainingRejected(object sender, EmoEngineEventArgs e){
message_box.text = "Trainig rejected";
}
public void TrainingSucceeded(object sender, EmoEngineEventArgs e){
message_box.text = "Training Succeeded!!";
//modal.GetComponent<MessageBox> ().init ("Training Succeeded!!", "Do you want to use this session?", new Decision (AceptTrainig));
}
public void AceptTrainig(bool accept){
if (accept) {
engine.MentalCommandSetTrainingControl ((uint)engineUserID, EdkDll.IEE_MentalCommandTrainingControl_t.MC_ACCEPT);
} else {
engine.MentalCommandSetTrainingControl ((uint)engineUserID, EdkDll.IEE_MentalCommandTrainingControl_t.MC_REJECT);
}
}
public void TrainingReset(object sender, EmoEngineEventArgs e){
message_box.text = "Command reseted";
}
public void Close(){
Application.Quit ();
}
}