<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.bci2000.org/mediawiki/index.php?action=history&amp;feed=atom&amp;title=User_Tutorial%3AUnityBCI2000_Barebones</id>
	<title>User Tutorial:UnityBCI2000 Barebones - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://www.bci2000.org/mediawiki/index.php?action=history&amp;feed=atom&amp;title=User_Tutorial%3AUnityBCI2000_Barebones"/>
	<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=User_Tutorial:UnityBCI2000_Barebones&amp;action=history"/>
	<updated>2026-06-27T12:45:51Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=User_Tutorial:UnityBCI2000_Barebones&amp;diff=11527&amp;oldid=prev</id>
		<title>Tytbutler at 02:31, 16 August 2024</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=User_Tutorial:UnityBCI2000_Barebones&amp;diff=11527&amp;oldid=prev"/>
		<updated>2024-08-16T02:31:14Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 02:31, 16 August 2024&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l3&quot;&gt;Line 3:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 3:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;This tutorial goes over how to use BCI2000 as a logging service for an existing Unity project. For a more comprehensive tutorial on integrating Unity with BCI2000, see [User Tutorial:UnityBCI2000]. This tutorial will use a sample Unity project, the same as the full tutorial.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;This tutorial goes over how to use BCI2000 as a logging service for an existing Unity project. For a more comprehensive tutorial on integrating Unity with BCI2000, see &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[&lt;/ins&gt;[User Tutorial:UnityBCI2000&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;]&lt;/ins&gt;]. This tutorial will use a sample Unity project, the same as the full tutorial.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;===Download Unity===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;===Download Unity===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key wikidb-bci_:diff:1.41:old-11526:rev-11527:php=table --&gt;
&lt;/table&gt;</summary>
		<author><name>Tytbutler</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=User_Tutorial:UnityBCI2000_Barebones&amp;diff=11526&amp;oldid=prev</id>
		<title>Tytbutler: Created page with &quot;&lt;pre style=&quot;color:red&quot;&gt; Red text blocks contain detailed instructions for the higher-level instructions preceding them. &lt;/pre&gt;  This tutorial goes over how to use BCI2000 as a logging service for an existing Unity project. For a more comprehensive tutorial on integrating Unity with BCI2000, see [User Tutorial:UnityBCI2000]. This tutorial will use a sample Unity project, the same as the full tutorial.  ===Download Unity===  Download Unity Hub from [https://unity3d.com Uni...&quot;</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=User_Tutorial:UnityBCI2000_Barebones&amp;diff=11526&amp;oldid=prev"/>
		<updated>2024-08-16T02:30:12Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;&amp;lt;pre style=&amp;quot;color:red&amp;quot;&amp;gt; Red text blocks contain detailed instructions for the higher-level instructions preceding them. &amp;lt;/pre&amp;gt;  This tutorial goes over how to use BCI2000 as a logging service for an existing Unity project. For a more comprehensive tutorial on integrating Unity with BCI2000, see [User Tutorial:UnityBCI2000]. This tutorial will use a sample Unity project, the same as the full tutorial.  ===Download Unity===  Download Unity Hub from [https://unity3d.com Uni...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;pre style=&amp;quot;color:red&amp;quot;&amp;gt;&lt;br /&gt;
Red text blocks contain detailed instructions for the higher-level instructions preceding them.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This tutorial goes over how to use BCI2000 as a logging service for an existing Unity project. For a more comprehensive tutorial on integrating Unity with BCI2000, see [User Tutorial:UnityBCI2000]. This tutorial will use a sample Unity project, the same as the full tutorial.&lt;br /&gt;
&lt;br /&gt;
===Download Unity===&lt;br /&gt;
&lt;br /&gt;
Download Unity Hub from [https://unity3d.com Unity].&lt;br /&gt;
&lt;br /&gt;
===Setting Up BCI2000===&lt;br /&gt;
&lt;br /&gt;
Follow the instructions starting with [https://www.bci2000.org/mediawiki/index.php/Programming_Howto:Install_Prerequisites] to download BCI2000. &lt;br /&gt;
&lt;br /&gt;
===Setting Up UnityBCI2000===&lt;br /&gt;
Download UnityBCI2000 from its GitHub page, [https://github.com/neurotechcenter/UnityBCI2000]. &lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:red&amp;quot;&amp;gt;&lt;br /&gt;
Click on the &amp;quot;Releases&amp;quot; section on the right side of the page. This tutorial is intended to be used with UnityBCI2000 version 2.0.0, so scroll to that release and click on the files BCI2000RemoteNETStandard.dll and UnityBCI2000.cs to download them.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Download Tutorial Project===&lt;br /&gt;
Download the CursorTask3 repository from [https://github.com/Personator01/CursorTask3 GitHub].&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:red&amp;quot;&amp;gt;&lt;br /&gt;
Either:&lt;br /&gt;
	-Clone the git repository&lt;br /&gt;
	-Download the respository directly from GitHub&lt;br /&gt;
		-&amp;gt; Click the green &amp;quot;Code&amp;quot; button &lt;br /&gt;
		-&amp;gt; Select &amp;quot;Download ZIP&amp;quot;&lt;br /&gt;
		-&amp;gt; Extract the zip file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The download directory contains two versions of the CursorTask3 project. One, CursorTask3-BCI2K, contains an example implementation of the task with BCI2000 integration. The other, CursorTask3-NoBCI2K, contains the same task without BCI2000 integration. This tutorial is a step by step guide on turning that second project into the first. &lt;br /&gt;
&lt;br /&gt;
===Opening the project===&lt;br /&gt;
Open the project in the Unity Editor, and open the CursorTask scene.&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:red&amp;quot;&amp;gt;&lt;br /&gt;
Open Unity Hub.&lt;br /&gt;
Click the &amp;quot;Add&amp;quot; button in the top right corner.&lt;br /&gt;
Navigate to the CursorTask3 directory downloaded previously.&lt;br /&gt;
Select the CursorTask3-NoBCI2K directory to add it to Unity Hub.&lt;br /&gt;
Click the CursorTask3-NoBCI2K project in the Unity Hub.&lt;br /&gt;
If prompted to select a version of Unity to use or install, select Unity 2022.3. The specific release number of Unity 2022.3 should not matter, so select the one labeled &amp;quot;LTS&amp;quot; for consistency.&lt;br /&gt;
The lower panel (the asset browser) should already show the Assets/Scenes directory, which contains a single scene called SampleScene.&lt;br /&gt;
Double-click SampleScene. This should open a scene with a box containing various lights and objects.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
If you wish to view the completed implementation, repeat these steps, but instead open the CursorTask3-BCI2K-Barebones directory. Note that in order to use the completed implementation, you will still need to set the Operator Path value of the UnityBCI2000 component of the BCI2000 game object.&lt;br /&gt;
&lt;br /&gt;
===Adding UnityBCI2000 to the project===&lt;br /&gt;
Add BCI2000RemoteNETStandard.dll and UnityBCI2000.cs to your project&amp;#039;s assets.&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:red&amp;quot;&amp;gt;&lt;br /&gt;
In the Unity Editor&amp;#039;s menu bar, click Assets &amp;gt; Open Containing Folder to open your project directory.&lt;br /&gt;
Place the BCI2000RemoteNETStandard.dll and UnityBCI2000.cs files in the Assets folder.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add an empty GameObject called &amp;#039;BCI2000&amp;#039;. This will hold the scripts for controlling BCI2000. &lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:red&amp;quot;&amp;gt;&lt;br /&gt;
In the Unity Editor&amp;#039;s menu bar, click GameObject &amp;gt; Create Empty to create an empty GameObject, and name it &amp;#039;BCI2000&amp;#039;. (The object&amp;#039;s specific name does not actually matter, it is only needed in order to reference it within other scripts)&lt;br /&gt;
You will notice that it now appears in the Scene Hierarchy panel, on the left side of the screen.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the UnityBCI2000 component to the object.&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:red&amp;quot;&amp;gt;&lt;br /&gt;
Click on the object in the Hierarchy panel. This will open it in the Inspector panel (the panel on the right side of the screen)&lt;br /&gt;
In the inspector, below the new object&amp;#039;s Transform component, click the &amp;quot;Add Component&amp;quot; button, which will open up a small window for adding components.&lt;br /&gt;
Within this window, select Scripts &amp;gt; Unity BCI2000 to add the UnityBCI2000 component.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Configuring UnityBCI2000===&lt;br /&gt;
The inspector panel now contains the configuration options for UnityBCI2000. Set the options as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Start Local Operator&amp;lt;/code&amp;gt;: Checked&lt;br /&gt;
&lt;br /&gt;
This will start the operator on your computer when the Unity scene initializes. If we were instead connecting to an already-running instance of BCI2000, or an instance on another computer, this box would be deselected.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Operator Path&amp;lt;/code&amp;gt;: The path to the Operator executable. This will look something like this on Windows (C://path/to/bci2000/prog/Operator.exe)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Operator Address&amp;lt;/code&amp;gt;: 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
This is the address of the machine on which BCI2000 is running. Since we are running BCI2000 on the same computer as Unity, we leave it as 127.0.0.1, the loopback address.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Operator Port&amp;lt;/code&amp;gt;: 3999&lt;br /&gt;
&lt;br /&gt;
This is the port on which BCI2000 is listening for commands. By default, it is 3999.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Start Modules&amp;lt;/code&amp;gt;: Checked&lt;br /&gt;
&lt;br /&gt;
This tells BCI2000 to start the requested Signal Source, Signal Processing, and Application modules when the Unity scene initializes. Similarly to Start Local Operator, we would deselect this box if connecting to an already-running instance. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Start With Scene&amp;lt;/code&amp;gt;: Checked&lt;br /&gt;
&lt;br /&gt;
This tells BCI2000 to start a data collection run when the scene starts. Since we will be using BCI2000 itself to set experiment parameters, we will instead wait for BCI2000 to start from Unity, and thus will leave the box unchecked. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Stop With Scene&amp;lt;/code&amp;gt;: Checked&lt;br /&gt;
&lt;br /&gt;
This tells BCI2000 to stop collecting data when the scene stops. Since we will be controlling BCI2000 directly, rather than entirely through Unity, we will leave this unchecked.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Shutdown With Scene&amp;lt;/code&amp;gt;: Unchecked&lt;br /&gt;
&lt;br /&gt;
This tells BCI2000 to shut down alongside the Unity scene. Whether or not this value is set ultimately doesn&amp;#039;t matter much, especially if Start Local Operator is checked. The data will be saved whether or not BCI2000 shuts down. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Module 1&amp;lt;/code&amp;gt;: SignalGenerator&lt;br /&gt;
&lt;br /&gt;
The signal source module to start. We will use SignalGenerator, which generates a signal without any connected hardware.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Module 2&amp;lt;/code&amp;gt;: DummySignalProcessing&lt;br /&gt;
&lt;br /&gt;
The signal processing module to start. We will use DummySignalProcessing, as there is no processing to do.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Module 3&amp;lt;/code&amp;gt;: DummyApplication&lt;br /&gt;
&lt;br /&gt;
The Application module to start. Since we are using Unity, we will use DummyApplication.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Setting References===&lt;br /&gt;
In order for the game&amp;#039;s scripts to communicate with BCI2000, they need to hold a reference to the UnityBCI2000 component.&lt;br /&gt;
There are three scripts which will need to communicate with BCI2000. They are &amp;lt;code&amp;gt;GameControl.cs, BallControl.cs, and MCursorControl.cs&amp;lt;/code&amp;gt;.&lt;br /&gt;
These scripts are each located within the Assets directory of the Unity project. &lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:red&amp;quot;&amp;gt;&lt;br /&gt;
As before, select Assets &amp;gt; Open Containing Folder to open the project directory, then open the Assets folder. &lt;br /&gt;
For each script, open it in a text editor.&lt;br /&gt;
Add a data member of type UnityBCI2000 to the class, like so:&lt;br /&gt;
	UnityBCI2000 bci;&lt;br /&gt;
Place the member definition above the Awake() method, for readability.&lt;br /&gt;
Within the Awake() method, set this reference to the UnityBCI2000 component.&lt;br /&gt;
	bci = GameObject.Find(&amp;quot;BCI2000&amp;quot;).GetComponent&amp;lt;UnityBCI2000&amp;gt;();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Each of the three scripts should contain a section like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	...&lt;br /&gt;
	UnityBCI2000 bci;&lt;br /&gt;
	void Awake() {&lt;br /&gt;
		bci = GameObject.Find(&amp;quot;BCI2000&amp;quot;).GetComponent&amp;lt;UnityBCI2000&amp;gt;();&lt;br /&gt;
		...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Adding Events===&lt;br /&gt;
[https://www.bci2000.org/mediawiki/index.php/Programming_Reference:Events Events] are the primary way that non-signal experiment data is recorded in BCI2000. They are timestamped integer values which are encoded alongside the signal data in BCI2000 output files. Due to BCI2000&amp;#039;s design, events must be added during a very specific part of its startup sequence, which is immediately after the BCI2000 operator starts, and before any of the modules start. As such, we cannot simply call &amp;lt;code&amp;gt;AddEvent()&amp;lt;/code&amp;gt; whenever we want. Furthermore, the order in which Unity objects initialize is undefined, so it cannot even be guaranteed that calling &amp;lt;code&amp;gt;AddEvent&amp;lt;/code&amp;gt; at a specific time will be consistent across multiple projects. As such, UnityBCI2000 provides a couple of methods for sending commands at well-defined points within the startup sequence. These two methods, &amp;lt;code&amp;gt;OnIdle&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;OnIdle&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;OnConnected&amp;lt;/code&amp;gt; allow BCI2000 commands to be sent while the operator is in the state Idle (immediately before starting its modules) and when the operator is in the state Connected (after starting and connecting to the modules. Below is an example of using those methods to add and show an event in BCI2000.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Script : MonoBehaviour {&lt;br /&gt;
    UnityBCI2000 bci;&lt;br /&gt;
    void Awake() {&lt;br /&gt;
	bci = GameObject.Find(&amp;quot;BCI2000Object&amp;quot;).GetComponent&amp;lt;UnityBCI2000&amp;gt;();&lt;br /&gt;
	bci.OnIdle(remote =&amp;gt; {&lt;br /&gt;
	    remote.AddEvent(&amp;quot;AnEvent&amp;quot;, 32);&lt;br /&gt;
	});&lt;br /&gt;
    }&lt;br /&gt;
    void Start() {&lt;br /&gt;
	bci.OnConnected(remote =&amp;gt; {&lt;br /&gt;
	    remote.Visualize(&amp;quot;AnEvent&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As seen above, &amp;lt;code&amp;gt;OnIdle&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;OnConnected&amp;lt;/code&amp;gt; take a delegate (C#&amp;#039;s term for a callback/closure/functor/etc.) with a single parameter of type &amp;lt;code&amp;gt;BCI2000Remote&amp;lt;/code&amp;gt; (in this case called &amp;quot;remote&amp;quot;). The lambda expression given to the call to &amp;lt;code&amp;gt;OnIdle&amp;lt;/code&amp;gt; uses the method &amp;lt;code&amp;gt;BCI2000Remote.AddEvent()&amp;lt;/code&amp;gt; to add an event called &amp;quot;AnEvent&amp;quot; with a bit width of 32 bits. The call to &amp;lt;code&amp;gt;OnConnected&amp;lt;/code&amp;gt; tells BCI2000 to show the event&amp;#039;s value in a graphical window. A description of the BCI2000Remote class can be found [https://www.bci2000.org/mediawiki/index.php/Contributions:BCI2000RemoteNET here], and API documentation can be found [https://bci2000.org/BCI2000RemoteNET/netstandard2/classBCI2000RemoteNET_1_1BCI2000Remote.html here].&lt;br /&gt;
&lt;br /&gt;
We will now add the events relevant to the Cursor Task. Open the &amp;lt;code&amp;gt;GameControl.cs&amp;lt;/code&amp;gt; script, and modify its &amp;lt;code&amp;gt;Awake()&amp;lt;/code&amp;gt; to add the events &amp;lt;code&amp;gt;PreFeedback&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Feedback&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;PostFeedback&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;TargetHit&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;Timeout&amp;lt;/code&amp;gt; with bit width 1. Additionally, add the events &amp;lt;code&amp;gt;TrialNumber&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;TargetPositionX&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;TargetPositionY&amp;lt;/code&amp;gt; with width 16. These will encode the task state and number of trials.&lt;br /&gt;
We also need to set a parameter value so that the signal will be set to the mouse position. Using &amp;lt;code&amp;gt;BCI2000Remote.SetParameter()&amp;lt;/code&amp;gt;, we will set the &amp;lt;code&amp;gt;ModulateAmplitude&amp;lt;/code&amp;gt; parameter to 1.&lt;br /&gt;
&lt;br /&gt;
Open the &amp;lt;code&amp;gt;BallControl.cs&amp;lt;/code&amp;gt; script, and within the &amp;lt;code&amp;gt;Awake()&amp;lt;/code&amp;gt; function, add events &amp;lt;code&amp;gt;CursorPositionX&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;CursorPositionY&amp;lt;/code&amp;gt;, with width 16. Show these events in a visualization window with &amp;lt;code&amp;gt;Visualize&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Your two scripts should now look like this: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; GameControl.cs &lt;br /&gt;
    ...&lt;br /&gt;
    void Awake() {&lt;br /&gt;
	...&lt;br /&gt;
	bci.OnIdle(remote =&amp;gt; {&lt;br /&gt;
	    remote.AddEvent(&amp;quot;PreFeedback&amp;quot;, 1);&lt;br /&gt;
	    remote.AddEvent(&amp;quot;Feedback&amp;quot;, 1);&lt;br /&gt;
	    remote.AddEvent(&amp;quot;PostFeedback&amp;quot;, 1);&lt;br /&gt;
	    remote.AddEvent(&amp;quot;TargetHit&amp;quot;, 1);&lt;br /&gt;
	    remote.AddEvent(&amp;quot;Timeout&amp;quot;, 1);&lt;br /&gt;
	    remote.AddEvent(&amp;quot;TrialNumber&amp;quot;, 16);&lt;br /&gt;
	    remote.AddEvent(&amp;quot;TargetPositionX&amp;quot;, 16);&lt;br /&gt;
	    remote.AddEvent(&amp;quot;TargetPositionY&amp;quot;, 16);&lt;br /&gt;
	    remote.SetParameter(&amp;quot;ModulateAmplitude&amp;quot;, &amp;quot;1&amp;quot;);&lt;br /&gt;
	    });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; BallControl.cs&lt;br /&gt;
    ...&lt;br /&gt;
    void Awake() {&lt;br /&gt;
	bci.OnIdle(remote =&amp;gt; {&lt;br /&gt;
	    remote.AddEvent(&amp;quot;CursorPositionX&amp;quot;, 16);&lt;br /&gt;
	    remote.AddEvent(&amp;quot;CursorPositionY&amp;quot;, 16);&lt;br /&gt;
	    });&lt;br /&gt;
	bci.OnConnected(remote =&amp;gt; {&lt;br /&gt;
	    remote.Visualize(&amp;quot;CursorPositionX&amp;quot;);&lt;br /&gt;
	    remote.Visualize(&amp;quot;CursorPositionY&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Reading the control signal===&lt;br /&gt;
We will be using the control signal to control the cursor. Open the &amp;lt;code&amp;gt;MCursorControl.cs&amp;lt;/code&amp;gt; script.&lt;br /&gt;
&lt;br /&gt;
The commented out section of the &amp;lt;code&amp;gt;GetPos()&amp;lt;/code&amp;gt; method contains the code required to turn the control signal waveform coming from the Signal Source and Signal Processing modules into screen coordinates. &lt;br /&gt;
Uncomment the commented part and delete the line &amp;lt;code&amp;gt;Ray r = camera.ScreenPointToRay(Input.MousePosition);&amp;lt;/code&amp;gt;.&lt;br /&gt;
Change the &amp;lt;code&amp;gt;double signalX = 0;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;double signalY = 0;&amp;lt;/code&amp;gt; to. &lt;br /&gt;
&lt;br /&gt;
Your &amp;lt;code&amp;gt;GetPos()&amp;lt;/code&amp;gt; method should look like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    Vector3 GetPos() {&lt;br /&gt;
	double signalX = bci.Control.GetSignal(1, bci.CurrentSampleOffset());&lt;br /&gt;
	double signalY = bci.Control.GetSignal(2, bci.CurrentSampleOffset());&lt;br /&gt;
	signalsX[signalIndex] = signalX;&lt;br /&gt;
	signalsY[signalIndex] = signalY;&lt;br /&gt;
	&lt;br /&gt;
	signalIndex = signalIndex + 1 &amp;gt;= rollingMaximumAmount ? 0 : signalIndex + 1;&lt;br /&gt;
	double max_x = signalsX.Max();&lt;br /&gt;
	double max_y = signalsY.Max();&lt;br /&gt;
	Ray r = camera.ScreenPointToRay(new Vector3((float) max_x * Screen.width, (float) max_y * Screen.height, 0));&lt;br /&gt;
	float p;&lt;br /&gt;
	if (!plane.Raycast(r, out p)) {&lt;br /&gt;
	   throw new Exception(&amp;quot;error casting ray to plane, invalid mouse position?&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	return r.GetPoint(p);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the use of the &amp;lt;code&amp;gt;UnityBCI2000.CurrentSampleOffset()&amp;lt;/code&amp;gt; method. This is a special method which gets the offset into the current block such that the sample is exactly one block length later than when it was collected by the hardware. This is to normalize the latency between when the hardware collects the signal and the software receives the signal, due to how BCI2000 processes data in blocks.&lt;br /&gt;
&lt;br /&gt;
===Sending events back to BCI2000===&lt;br /&gt;
&lt;br /&gt;
The primary way to communicate game state back to BCI2000 is via the use of Events, which are integer values encoded alongside the signal data.&lt;br /&gt;
&lt;br /&gt;
We will send the events that we added in a previous section.&lt;br /&gt;
&lt;br /&gt;
First, we will send back the current position of the cursor. Within the &amp;lt;code&amp;gt;BallControl.cs&amp;lt;/code&amp;gt; script, within the &amp;lt;code&amp;gt;Update()&amp;lt;/code&amp;gt; method, immediately after &amp;lt;code&amp;gt;Move()&amp;lt;/code&amp;gt; is called, set the &amp;lt;code&amp;gt;CursorPositionX&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;CursorPositionY&amp;lt;/code&amp;gt; events. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; BallControl.cs&lt;br /&gt;
void Update() {&lt;br /&gt;
    ...&lt;br /&gt;
    if (isTrialRunning) {&lt;br /&gt;
	...&lt;br /&gt;
	Move();&lt;br /&gt;
	bci.Control.SetEvent(&amp;quot;CursorPositionX&amp;quot;, (uint) ((transform.position.x + 7) * 1000));&lt;br /&gt;
	bci.Control.SetEvent(&amp;quot;CursorPositionY&amp;quot;, (uint) ((transform.position.y + 4.5) * 1000));&lt;br /&gt;
    }&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that we transform the value of the cursor&amp;#039;s position. This is because events in BCI2000 are represented as unsigned integers, so, for example, the cursor&amp;#039;s range of movement in the x axis, -7 to 7, would not be directly representable within a BCI2000 event, so we add 7 so it is positive, and multiply by 1000 so that we have a more precise measure of the cursor&amp;#039;s position. The range of [-7,7] becomes [0,14000].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We will also set the events corresponding to the game state within &amp;lt;code&amp;gt;GameControl.cs&amp;lt;/code&amp;gt;. First we will set &amp;lt;code&amp;gt;PreFeedback&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Feedback&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;PostFeedback&amp;lt;/code&amp;gt; to represent when the game is in these states. To do this, at the beginning and end of &amp;lt;code&amp;gt;PreTrial()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Trial()&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;PostTrial()&amp;lt;/code&amp;gt;, we will set the corresponding event values to 1 and 0, respectively.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; GameControl.cs&lt;br /&gt;
IEnumerator PreTrial() {&lt;br /&gt;
    bci.Control.SetEvent(&amp;quot;PreFeedback&amp;quot;, 1);&lt;br /&gt;
    ...&lt;br /&gt;
    bci.Control.SetEvent(&amp;quot;PreFeedback&amp;quot;, 0);&lt;br /&gt;
}&lt;br /&gt;
IEnumerator Trial() {&lt;br /&gt;
    bci.Control.SetEvent(&amp;quot;Feedback&amp;quot;, 1);&lt;br /&gt;
    ...&lt;br /&gt;
    bci.Control.SetEvent(&amp;quot;Feedback&amp;quot;, 0);&lt;br /&gt;
}&lt;br /&gt;
IEnumerator PostTrial() {&lt;br /&gt;
    bci.Control.SetEvent(&amp;quot;PostFeedback&amp;quot;, 1);&lt;br /&gt;
    ...&lt;br /&gt;
    bci.Control.SetEvent(&amp;quot;PostFeedback&amp;quot;, 0);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We will also set the events which happen at the end of each trial. The &amp;lt;code&amp;gt;TargetHit&amp;lt;/code&amp;gt; event is activated when the subject hits the target, and the &amp;lt;code&amp;gt;Timeout&amp;lt;/code&amp;gt; event is activated when the subject runs out of time.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; GameControl.cs&lt;br /&gt;
IEnumerator Trial() {&lt;br /&gt;
    ...&lt;br /&gt;
    bci.Control.SetEvent(&amp;quot;Feedback&amp;quot;, 0);&lt;br /&gt;
    if (lastTrialSucceeded) {&lt;br /&gt;
	bci.Control.PulseEvent(&amp;quot;TargetHit&amp;quot;, 1);&lt;br /&gt;
    } else {&lt;br /&gt;
	bci.Control.PulseEvent(&amp;quot;Timeout&amp;quot;, 1);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Notice that we use &amp;lt;code&amp;gt;BCI2000Remote.PulseEvent()&amp;lt;/code&amp;gt; rather than &amp;lt;code&amp;gt;BCI2000Remote.SetEvent()&amp;lt;/code&amp;gt;. This results in the event being set to the value &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; for exactly one sample duration, then returning to zero.&lt;br /&gt;
&lt;br /&gt;
We will also record the position of the target. Similarly to the cursor, we will transform the target&amp;#039;s coordinates to be a positive integer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; GameControl.cs&lt;br /&gt;
IEnumerator PreTrial() {&lt;br /&gt;
    ...&lt;br /&gt;
    target.SetActive(true);&lt;br /&gt;
    bci.Control.SetEvent(&amp;quot;TargetPositionX&amp;quot;, (uint) ((target.transform.position.x + 7) * 1000));&lt;br /&gt;
    bci.Control.SetEvent(&amp;quot;TargetPositionY&amp;quot;, (uint) ((target.transform.position.y + 4.5) * 1000));&lt;br /&gt;
    ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The last event we need to set is the trial number.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
IEnumerator ControlLoop() {&lt;br /&gt;
    ...&lt;br /&gt;
    while (IsContinue() &amp;amp;&amp;amp; trials &amp;lt; n_trials) {&lt;br /&gt;
	bci.Control.SetEvent(&amp;quot;TrialNumber&amp;quot;, trials + 1);&lt;br /&gt;
	...&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Unity Player Settings===&lt;br /&gt;
Additionally, due to how Unity detects changes in BCI2000 state, it must be allowed to run in the background.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:red&amp;quot;&amp;gt;&lt;br /&gt;
In the Unity menu bar:&lt;br /&gt;
    Edit &amp;gt; Project Settings &amp;gt; Player &amp;gt; Resolution and Presentation&lt;br /&gt;
Check the &amp;quot;Run In Background&amp;quot; box.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Usage===&lt;br /&gt;
&lt;br /&gt;
Now, when the Unity application runs, BCI2000 will open and start collecting data.&lt;/div&gt;</summary>
		<author><name>Tytbutler</name></author>
	</entry>
</feed>