Let's build a modest interactive installation in a few steps. We are going to create a farm in a box, our little farm creatures will live inside of a carboard box.
For the physical part we will need:
To recreate our digital farm we will be using Unity, so install Unity Hub and when you have that working and you have a license to use Unity, install Unity 2019.2.10f1
.
Asset store
and search for Ardity
, that will show the plugin, install and import everything. This is the repo: https://github.com/DWilches/ArdityAPI compatibility Level
to NET 4.x
(see below)DemoScene_UserPoll_JustRead.unity
Assets/Ardity/Scripts/SerialThread.cs(9,17): error CS0234: The type or namespace name 'Ports' does not >exist in the namespace 'System.IO'. Are you missing an assembly reference?
If you get that error, check the current "API Compatibility Level" of your Unity project. Go to Edit
-> Project Settings
-> Player
, and under Other Settings
find an option that reads API Compatibility Level
and change it to .NET 4.0
(or .NET 2.0 if you have a version older than Unity 2018).
To create our little farm I got these assets from Google Poly. But if you feel inspired feel free to create your own.
A somewhat detailed barn:
A low-detail barn:
In the Unity scene I created a directional light to be the sun that lights the entire scene, there's only once source of light in this case. I then added a scripted behaviour to that sun and entered this code. When a new value is read from the Arduino, the method OnMessageArrived
gets a call, we can use the code in that method to process the data that is pumped from Arduino. In the case of the light sensor circuit, our Arduino is just pumping one number containing the light level, that number has a range between 0
and 1024
. It is important to study the signal before we commit to any particular threshold, it might be that in our current light conditions in the room the sensor never reads anything above 800, and that's the maximum brightness we can read.
What this script does is to regulate the behaviour of the light depending on sensor readings from Arduino. Adjusting the light levels of the physical room where we are in will have an effect in our tiny digital world.
using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine;
public class SunBehaviour : MonoBehaviour
{
public float minIntensity = 0.15f;
public float maxIntensity = 0.95f;
float duration = 1.0f;
[Tooltip("Choose a color tint for the morning light")]
public Color morning = Color.yellow;
[Tooltip("Choose a color tint for the evening light")]
public Color evening = Color.magenta;
[Tooltip("Choose a sound to play at sunrise")]
public AudioSource sunrise;
[Tooltip("Choose a sound to play at sunset")]
public AudioSource sunset;
float random;
float dayprogress;
Light lt;
void Start()
{
lt = GetComponent<Light>();
random = UnityEngine.Random.Range(0.0f, 65535.0f);
}
void Update()
{
// determine the color of the light depending on the time of the day
lt.color = Color.Lerp(morning, evening, dayprogress);
// if we are in the "morning" part of the day and the sunrise sound isn't playing yet
// play a sound that signifies sunrise
if((dayprogress < 0.1) && (!sunrise.isPlaying)) {
sunrise.Play(0);
}
// if we are in the night part of the day and the sunset sound isn't playing
// play the sunset sound
if((dayprogress > 0.9) && (!sunset.isPlaying)) {
sunset.Play(0);
}
}
// ///////////////////////////////////////////////////////////////////////
// Arduino callbacks
// ///////////////////////////////////////////////////////////////////////
public void OnMessageArrived(string msg)
{
int sensorValue = 0;
try {
// we convert the incoming string, to a number
sensorValue = System.Convert.ToInt32(msg);
// we divide that number by 1024, to get it in the range of 0 to 1
// which is easier to work with in Unity
dayprogress = sensorValue/1024f;
// log the number to monitor what's going on in the communication
// between Unity and Arduino
Debug.Log(">>> Dayprogress: " + dayprogress);
} catch(FormatException ex) {
// handle the situation if somethign goes wrong
// (like for example, getting garbage from Arduino)
Debug.LogException(ex, this);
Debug.Log("Something went wrong in the number conversion");
}
}
/**
* this just handle `connected` and `disconnected` events when
* Unity detects a new Arduino has been (un)plugged
*/
public void OnConnectionEvent(bool success)
{
if (success)
Debug.Log("Connection with light established");
else
Debug.Log("Connection with light failed or disconnection detected");
}
}