项目场景:
试想一下,在商场进行产品推广过程中,一般的大屏/宣传板/传单已经远远不能满足当前年轻人的需求,那么我们是不是可以通过一些小创意来增加用户的体验呢?
本文我们将使用Unity3D 配合Arduino硬件开发,创作一个互动程序,用户通过风车与大屏上的动画进行交互。
技术点:
- Unity 3D与Arduino串口通信
- Arduino与主机串口通信
- 风车数据读取
硬件清单:
- 风车一个(需改造):tb地址
- Arduino Nano 一个;
- USB线一条;
- 跳线若干;
- 烙铁等;
接线图 :
风车尺寸:风车到手需要进行改造,将正负极引出。这个需要一丢丢动手操作(建议多买几个备用~)。
此处黑色按钮位置,替换为上面引出的两极~如果发现没有效果,可能是接反了。
Arduino 代码:
Arduino硬件侧需要读取风车的实时电讯号,并将其转换为数值即(0-1023)发送到串口,Unity 3D程序读取串口数据,并根据不同数值,在程序中呈现不同效果。void setup() {
// 初始化串行通信速率为115200bit/s:
Serial.begin(115200);
}
void loop() {
// 读取模拟引脚A0的输入数据
int sensorValue = analogRead(A0);
// 将模拟信号转换成电压
float voltage = sensorValue * (5.0 / 1023.0);
// 打印到串口监视器,可以根据实际需要,改成各种形式
Serial.println(voltage);
}
Unity 3D效果:
- Unity 3D模块需要连接计算机串口,对数据进行解析
关键代码:
using UnityEngine;
using System.Collections;
using System.IO;
using System.IO.Ports;
using System.Threading;
using System.Collections.Generic;
using LitJson;
using System;
public class SerialControl : MonoBehaviour {
public static SerialControl instance;
//处理实时上传的数据
public delegate void DataIn(string text);
public SerialPort serialPort = null;
public string strIn;
//创建线程,监听数据
Thread myThr;
//创建线程,检查串口状态
Thread myCheck;
string portName;
bool run = false;
public DataIn dataHandle;
void Awake()
{
instance = this;
}
void Start()
{
//场景跳转不销毁
DontDestroyOnLoad(gameObject);
//此处根据项目需要可以配置,测试时候可以直接写死
portName = "COM3";//File.ReadAllText("Data/config.txt");
OpenConnection();
myCheck = new Thread(new ThreadStart(CheckConnect));
myCheck.Start();
}
void Update()
{
/* if (serialPort.IsOpen)
{
}*/
}
void CheckConnect()
{
while (true)
{
string[] portNames = SerialPort.GetPortNames();
bool connect = false;
// bool needConn=false;
for (int i = 0; i < portNames.Length; i++)
{
if (portName == portNames[i])
{
connect = true;
break;
}
}
if (!run && connect||!connect)
{
serialPort.Dispose();
serialPort = null;
run = false;
try
{
OpenConnection();
}
catch (Exception e)
{
Debug.Log(e.Message);
}
}
Thread.Sleep(3000);
}
}
void ReadThread()
{
while (run)
{
if (serialPort.IsOpen)
{
string dataLine = serialPort.ReadLine();
JsonData data = JsonMapper.ToObject(new JsonReader(dataLine));
string rate = data["rate"].ToString();
dataHandle.Invoke(rate);
// Debug.Log(id);
// Debug.Log(dataLine);
}
// Debug.Log("dataLine");
Thread.Sleep(50);
}
}
public void OpenConnection()
{
serialPort = new SerialPort(portName, 115200, Parity.None, 8, StopBits.One);
if (serialPort != null)
{
if (serialPort.IsOpen)
{
// serialPort.Close();
Debug.Log("Closing port, because it was already open!");
}
else
{
try{
serialPort.Open();
// serialPort.ReadTimeout = 50;
run = true;
Thread myThr = new Thread(new ThreadStart(ReadThread));
myThr.Start();
Debug.Log("Port Opened!");
}catch(Exception e){
}
}
}
else
{
if (serialPort.IsOpen)
{
print("Port is already open");
}
else
{
print("Port == null");
}
}
}
void OnApplicationQuit()
{
//结束记得清理
if(serialPort!=null)
serialPort.Close();
myCheck.Abort();
Debug.Log("Port closed!");
}
}
最终效果:
互动展示1:
互动展示2:
启动,通过吹气来触发操作
Unity动效:
互动拓展:
1、Unity 3D种的动效可以进行扩展,比如吹动柳絮、控制模型等可以进行更多的拓展; 2、Arduino硬件设备,在量产的情况下,可以通过专业设计,替换成更便宜的单片机; 3、输入设备,可以替换为压力传感器、声音传感器、滑动电阻、测距模块等相关硬件:
可以进行互动的硬件设备还有很多,如果有好玩的应用想法,欢迎交流。