Open Albond87 opened 4 years ago
For me it's an interesting issue, as I want to connect Joy cons to Android and raspberry pi enabled device's
@TheBricktop So I actually found a (kind of) solution. Instead of connecting the Joy Con to my phone, I made a simple exe for my laptop which takes input from them, and then sends the data I need in packets to a receiver application on my phone, where I can then use the input. It works pretty well with not much latency (and I never tried to optimise it as I never went any further with that project). The only downside is you need to have a pc/laptop so it's not exactly a portable solution. I can give you the code if you want (not sure how to incorporate a raspi though, maybe by connecting that to the laptop as well?)
Yea i was thinking about osc or some kind of a translator from hid to raw data, but intended way of using this was to make some kind of a better daydream controller out of existing superior joystics (and far cheaper in comparision)
@TheBricktop So I actually found a (kind of) solution. Instead of connecting the Joy Con to my phone, I made a simple exe for my laptop which takes input from them, and then sends the data I need in packets to a receiver application on my phone, where I can then use the input. It works pretty well with not much latency (and I never tried to optimise it as I never went any further with that project). The only downside is you need to have a pc/laptop so it's not exactly a portable solution. I can give you the code if you want (not sure how to incorporate a raspi though, maybe by connecting that to the laptop as well?)
Heya! Can you drop a download link to the code?
@TheBricktop So I actually found a (kind of) solution. Instead of connecting the Joy Con to my phone, I made a simple exe for my laptop which takes input from them, and then sends the data I need in packets to a receiver application on my phone, where I can then use the input. It works pretty well with not much latency (and I never tried to optimise it as I never went any further with that project). The only downside is you need to have a pc/laptop so it's not exactly a portable solution. I can give you the code if you want (not sure how to incorporate a raspi though, maybe by connecting that to the laptop as well?)
Heya! Can you drop a download link to the code?
Hi, sorry for the late response but here is some code you might find useful! (Modified from https://forum.unity.com/threads/simple-udp-implementation-send-read-via-mono-c.15900/ to send Joycon data)
Sending packets of data (for the desktop application):
/*
-----------------------
UDP-Send
-----------------------
// [url]http://msdn.microsoft.com/de-de/library/bb979228.aspx#ID0E3BAC[/url]
CODE TAKEN FROM: https://forum.unity.com/threads/simple-udp-implementation-send-read-via-mono-c.15900/
// > gesendetes unter
// 127.0.0.1 : 8050 empfangen
// nc -lu 127.0.0.1 8050
// todo: shutdown thread at the end
*/
using UnityEngine;
using UnityEngine.UI;
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using System.Linq;
using System.Collections;
public class IPManager
{
public static string GetIP(ADDRESSFAM Addfam)
{
//Return null if ADDRESSFAM is Ipv6 but Os does not support it
if (Addfam == ADDRESSFAM.IPv6 && !Socket.OSSupportsIPv6)
{
return null;
}
string output = "";
foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
{
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
NetworkInterfaceType _type1 = NetworkInterfaceType.Wireless80211;
NetworkInterfaceType _type2 = NetworkInterfaceType.Ethernet;
if ((item.NetworkInterfaceType == _type1 || item.NetworkInterfaceType == _type2) && item.OperationalStatus == OperationalStatus.Up)
#endif
{
foreach (UnicastIPAddressInformation ip in item.GetIPProperties().UnicastAddresses)
{
//IPv4
if (Addfam == ADDRESSFAM.IPv4)
{
if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
{
output = ip.Address.ToString();
}
}
//IPv6
else if (Addfam == ADDRESSFAM.IPv6)
{
if (ip.Address.AddressFamily == AddressFamily.InterNetworkV6)
{
output = ip.Address.ToString();
}
}
}
}
}
return output;
}
}
public enum ADDRESSFAM
{
IPv4, IPv6
}
public class UDPSend : MonoBehaviour
{
private static int localPort;
// prefs
private string IP; // define in init
public int port; // define in init
// "connection" things
IPEndPoint remoteEndPoint;
UdpClient client;
[Serializable]
public class DataPacket
{
public Quaternion lo; // left orientation
public Quaternion ro; // right orientation
public bool zl;
public bool zr;
}
public DataPacket sendPacket = new DataPacket();
public InputField input;
public JoyconController joyconL;
public JoyconController joyconR;
// start from unity3d
public void Start()
{
Init();
Debug.Log(IPManager.GetIP(ADDRESSFAM.IPv4));
}
public void Update()
{
sendPacket.lo = joyconL.orientation;
sendPacket.ro = joyconR.orientation;
sendPacket.zl = joyconL.joycon.GetButton(Joycon.Button.SHOULDER_2);
sendPacket.zr = joyconR.joycon.GetButton(Joycon.Button.SHOULDER_2);
string json = JsonUtility.ToJson(sendPacket);
SendString(json);
}
// init
public void Init()
{
// Endpunkt definieren, von dem die Nachrichten gesendet werden.
print("UDPSend.init()");
// define
IP = input.text;
port = 8051;
// ----------------------------
// Senden
// ----------------------------
remoteEndPoint = new IPEndPoint(IPAddress.Parse(IP), port);
client = new UdpClient();
// status
print("Sending to " + IP + " : " + port);
print("Testing: nc -lu " + IP + " : " + port);
}
// sendData
private void SendString(string message)
{
try
{
//if (message != "")
//{
// Daten mit der UTF8-Kodierung in das Binärformat kodieren.
byte[] data = Encoding.UTF8.GetBytes(message);
// Den message zum Remote-Client senden.
client.Send(data, data.Length, remoteEndPoint);
//}
}
catch (Exception err)
{
print(err.ToString());
}
}
}
Receiving packets of data (for the mobile application):
/*
-----------------------
UDP-Receive (send to)
-----------------------
// [url]http://msdn.microsoft.com/de-de/library/bb979228.aspx#ID0E3BAC[/url]
CODE TAKEN FROM: https://forum.unity.com/threads/simple-udp-implementation-send-read-via-mono-c.15900/
// > receive
// 127.0.0.1 : 8051
// send
// nc -u 127.0.0.1 8051
*/
using UnityEngine;
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
public class UDPReceive : MonoBehaviour
{
// receiving Thread
Thread receiveThread;
// udpclient object
UdpClient client;
// public
//public string IP = "127.0.0.1";
public int port; // define > init
// infos
public string lastReceivedUDPPacket = "";
//public string allReceivedUDPPackets = ""; // clean up this from time to time!
[Serializable]
public class DataPacket
{
public Quaternion lo; // left orientation
public Quaternion ro; // right orientation
public bool zl;
public bool zr;
}
public bool isAlive = false;
public Transform joyconL;
public Transform joyconR;
public Transform zl;
public Transform zr;
public Vector3 unpressedPos;
public Vector3 pressedPos;
// start from shell
private static void Main()
{
UDPReceive receiveObj = new UDPReceive();
receiveObj.Init();
string text = "";
do
{
text = Console.ReadLine();
}
while (!text.Equals("exit"));
}
// start from unity3d
public void Start()
{
Init();
}
public void Update()
{
string packet = GetLatestUDPPacket();
DataPacket receivePacket = JsonUtility.FromJson<DataPacket>(packet);
joyconL.localRotation = receivePacket.lo;
joyconR.localRotation = receivePacket.ro;
if (receivePacket.zl)
{
zl.localPosition = pressedPos;
}
else
{
zl.localPosition = unpressedPos;
}
if (receivePacket.zr)
{
zr.localPosition = pressedPos;
}
else
{
zr.localPosition = unpressedPos;
}
}
// OnGUI
/*void OnGUI()
{
Rect rectObj = new Rect(40, 10, 200, 400);
GUIStyle style = new GUIStyle();
style.alignment = TextAnchor.UpperLeft;
GUI.Box(rectObj, "# UDPReceive\n127.0.0.1 " + port + " #\n"
+ "shell> nc -u 127.0.0.1 : " + port + " \n"
+ "\nLast Packet: \n" + lastReceivedUDPPacket
+ "\n\nAll Messages: \n" + allReceivedUDPPackets
, style);
}*/
// init
private void Init()
{
// Endpunkt definieren, von dem die Nachrichten gesendet werden.
print("UDPSend.init()");
// define port
port = 8051;
// status
print("Sending to 127.0.0.1 : " + port);
print("Test-Sending to this Port: nc -u 127.0.0.1 " + port + "");
// ----------------------------
// Abhören
// ----------------------------
// Lokalen Endpunkt definieren (wo Nachrichten empfangen werden).
// Einen neuen Thread für den Empfang eingehender Nachrichten erstellen.
isAlive = true;
receiveThread = new Thread(
new ThreadStart(ReceiveData));
receiveThread.IsBackground = true;
receiveThread.Start();
}
private void OnApplicationQuit()
{
isAlive = false;
receiveThread.Abort();
}
// receive thread
public void ReceiveData()
{
client = new UdpClient(port);
//client.Client.Blocking = false;
while (isAlive)
{
try
{
// Bytes empfangen.
IPEndPoint anyIP = new IPEndPoint(IPAddress.Any, 0);
byte[] data = client.Receive(ref anyIP);
// Bytes mit der UTF8-Kodierung in das Textformat kodieren.
string text = Encoding.UTF8.GetString(data);
// Den abgerufenen Text anzeigen.
//print(">> " + text);
// latest UDPpacket
lastReceivedUDPPacket = text;
// ....
//allReceivedUDPPackets = allReceivedUDPPackets + text;
}
catch (Exception err)
{
print(err.ToString());
}
}
}
// getLatestUDPPacket
// cleans up the rest
public string GetLatestUDPPacket()
{
//allReceivedUDPPackets = "";
return lastReceivedUDPPacket;
}
}
After much annoyance with Unity complaining about various things, and after digging through other issues, I managed to get a simple scene working, with two cuboids representing Joycon that rotate to match my two Joycon connected to my laptop. I then built the scene for android and ran it on my phone, with my two Joycon already connected and working, and... nothing. Just two lifeless cuboids staring back at me. Tried disconnecting and reconnecting the Joycon, tried restarting the app... nothing. I noticed someone else already raised an issue about android support, but it got no response. Is there some other plugin needed to be able to use this on android? (like a BLE plugin) Or is there some other way to get Unity to recognise them when they are connected to Android? (when connected to my phone the names are the exact same as on my Laptop (Joy-Con (L) and Joy-Con (R)) and they show the same controller icon)