Arduino+Unity3D做自己的游戏世界
本帖最后由 maker_王 于 2016-12-9 19:47 编辑看了好长一段时间的U3D,尝试用Arduino和Unity进行通信
http://v.youku.com/v_show/id_XMT ... m=a2hzp.8253869.0.0
http://v.youku.com/v_show/id_XMTg1NjQzNTUwNA==.html
虽然能够通信了,不过延时的感觉还是有的
如果时间来得及的话,我还会放一个第三人称的游戏视频{:5_159:}
下面是U3D的串口通信脚本,用C#写的,结合了网上还有资料书写的
using UnityEngine;
using System.Collections;
using System.IO;
using System;
using System.IO.Ports;
using System.Threading;
using System.Collections.Generic;
public class SerialPortTest : MonoBehaviour
{
private SerialPort _serialport;
private Queue<string> queueDataPool;
private Thread tPort;
private Thread tPortDeal;
private string strOutPool = string.Empty;
bool _start;
private float Arduino_X;
private float Arduino_Y;
private float Arduino_Z;
public float AX { get { return (Arduino_X-512)>5? Mathf.Clamp01((float)Arduino_X / 512.0f - 1.0f): -Mathf.Clamp01(1.0f - (float)Arduino_X / 512.0f); } }
public float AY { get { return (Arduino_Y-512)>5? Mathf.Clamp01((float)Arduino_Y / 512.0f - 1.0f) : -Mathf.Clamp01(1.0f - (float)Arduino_Y / 512.0f); } }
public float AZ { get { return Arduino_Z; } }
void Start()
{
queueDataPool = new Queue<string>();
_serialport = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
try
{
_serialport.Open();
}
catch (Exception _ex)
{
Debug.Log(_ex);
}
tPort = new Thread(DealData);
tPort.Start();
tPortDeal = new Thread(ReceiveData);
tPortDeal.Start();
_start = false;
}
private void FixedUpdate()
{
if (Time.frameCount % 120 == 0) System.GC.Collect();
if (!tPort.IsAlive)
{
tPort = new Thread(DealData);
tPort.Start();
}
if (!tPortDeal.IsAlive)
{
tPortDeal = new Thread(ReceiveData);
tPortDeal.Start();
}
}
private void ReceiveData()
{
try
{
Byte[] buf = new Byte;
string sbReadline2str = string.Empty;
if (_serialport.IsOpen)
{
_serialport.Read(buf, 0, 1);
//Debug.Log(System.Text.Encoding.Default.GetString(buf));
}
if (buf.Length == 0) return;
if (buf != null)
{
for (int i = 0; i < buf.Length; i++)
{
string str = System.Text.Encoding.Default.GetString(buf);
if (str == "(") _start = true;
else sbReadline2str += str;
queueDataPool.Enqueue(sbReadline2str);
//Debug.Log(sbReadline2str);
}
}
}
catch (Exception _ex)
{
Debug.Log(_ex);
}
}
private void DealData()
{
while (queueDataPool.Count != 0)
{
if (_start)
{
for (int i = 0; i < queueDataPool.Count; i++)
{
string str = queueDataPool.Dequeue();
if (str == ")")
{
//Debug.Log(strOutPool);
string[] sArray = strOutPool.Split(',');
Arduino_X = float .Parse(sArray);
Arduino_Y = float.Parse(sArray);
Arduino_Z = float.Parse(sArray);
Debug.Log("X:" + Arduino_X + "," + "Y:" + Arduino_Y + "," + "Z:" + Arduino_Z);
strOutPool = string.Empty;
_start = false;
}
else strOutPool += str;
}
}
}
}
private void SendSerialPortData(string Data)
{
if (_serialport.IsOpen)
{
_serialport.WriteLine(Data);
}
}
private void OnApplicationQuit()
{
_serialport.Close();
}
}
下面是Arduino的程序:
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
Serial.print("(");
Serial.print(analogRead(A0));
Serial.print(",");
Serial.print(analogRead(A1));
Serial.print(",");
Serial.print(analogRead(A2));
Serial.println(")");
delay(380);
}
Arduino和U3D的串口通信有三种方法实现(都是基于C#中的SerialPort),一个是使用unity自身Updata()(这个方法和Arduino的loop()有点类似),另外一个是用协程Coroutines(这个传输速度稍快),随后一个是使用线程Theard(速度是最快的)。
我上面的脚本中使用的线程,可是需要延时才能接收到正确的数据(这个线程的工作原理还得再看看){:5_177:},不过确实比使用协程方法来的快一些。
最后要说的是这个脚本好像很容易把Unity卡死,第一次运行正常,之后就有可能不能运行了。{:5_182:}(有可能是我心太急了还没等Arduino串口通信结束就开始运行游戏)
感谢楼主的认真分享 哇可以做游戏手柄了 请问这个程序总是使Unity死机的问题解决了吗
大佬,请问有详细教程吗 大佬,请问有详细教程吗
页:
[1]