■
影とブーストエフェクト追加。結局パーティクルじゃなくてプリミティブを組み合わせた方が早そう、という結論に。手裏剣かゆいところに手が届かなくて嫌い
YEIから返答が。Unityのサンプル
using UnityEngine; using System; using System.Collections; using System.IO.Ports; public class cube_rotator : MonoBehaviour{ // Connect to the serial port the 3-Space Sensor is connected to public static SerialPort sp = new SerialPort("\\\\.\\COM13"); // Command packet for getting the filtered tared orientation as a quaternion // {header byte, command byte, [data bytes], checksum byte} // checksum = (command byte + data bytes) % 256 public static byte[] send_bytes = {0xf7, 0x00, 0x00}; public static byte[] button_bytes = {0xf7, 0xfa, 0xfa}; public static byte[] tare_bytes = {0xf7, 0x60, 0x60}; public int counter = 0; // Use this for initialization void Start(){ // Allow the user to set the appropriate properties. sp.BaudRate = 115200; sp.Parity = Parity.None; sp.DataBits = 8; sp.StopBits = StopBits.One; // Set the read/write timeouts sp.WriteTimeout = 500; sp.ReadTimeout = 500; sp.Open(); sp.Write(send_bytes,0,3); } // Helper function for taking the bytes read from the 3-Space Sensor and converting them into a float float bytesToFloat(byte[] raw_bytes, int offset){ byte[] big_bytes = new byte[4]; big_bytes[0] = raw_bytes[offset+3]; big_bytes[1] = raw_bytes[offset+2]; big_bytes[2] = raw_bytes[offset+1]; big_bytes[3] = raw_bytes[offset+0]; return BitConverter.ToSingle(big_bytes,0); } void getButtonState(){ sp.Write(button_bytes, 0, 3); byte[] read_bytes = new byte[1]; int fail_counter = 0; // Mono, for some reason, seems to randomly fail on the first read after a wirte so we must loop // through to make sure the bytes are read while (true){ try{ sp.Read(read_bytes, 0, 1); break; } catch{ ++fail_counter; // Failed to read from serial port } if (fail_counter > 100){ throw new System.Exception("Failed to read from port too many times." + " This could mean the port is not open or the Mono serial read is not responding."); } } if (read_bytes[0] == 0){ print("No buttons are pressed."); } else if (read_bytes[0] == 1){ print("Right button is pressed."); } else if (read_bytes[0] == 2){ print("Left button is pressed."); } else if (read_bytes[0] == 3){ print("Left and Right buttons are pressed."); } } void tareSensor(){ sp.Write(tare_bytes, 0, 3); } // Update is called once per frame void Update(){ counter++; // A quaternion consists of 4 floats which is 16 bytes byte[] read_bytes = new byte[16]; // Mono, for some reason, seems to randomly fail on the first read after a wirte so we must loop // through to make sure the bytes are read and Mono also seems not to always read the amount asked // so we must also read one byte at a time int read_counter = 100; int byte_idx = 0; while (read_counter > 0){ try{ byte_idx += sp.Read(read_bytes, byte_idx, 1); } catch{ // Failed to read from serial port } if (byte_idx == 16){ break; } if (read_counter <= 0){ throw new System.Exception("Failed to read quaternion from port too many times." + " This could mean the port is not open or the Mono serial read is not responding."); } --read_counter; } // Convert bytes to floats float x = bytesToFloat(read_bytes,0); float y = bytesToFloat(read_bytes,4); float z = bytesToFloat(read_bytes,8); float w = bytesToFloat(read_bytes,12); // Create a quaternion Quaternion quat = new Quaternion(x,y,z,w); // Perform rotation transform.rotation = quat; if ((counter % 25) == 0){ getButtonState(); } else if (counter > 150){ tareSensor(); counter = 1; } // Send command sp.Write(send_bytes,0,3); } }
using UnityEngine; using System; using System.Collections; using System.IO.Ports; public class cube_rotator_wireless : MonoBehaviour{ // Connect to the serial port the 3-Space Dongle is connected to public static SerialPort sp = new SerialPort("\\\\.\\COM3"); // Wireless Command packet for getting the filtered tared orientation as // a quaternion // {header byte, id byte + command byte, [data bytes], checksum byte} // checksum = (id byte + command byte + data bytes) % 256 public static byte[] send_bytes = {0xf8, 0x00, 0x00, 0x00}; public static byte[] button_bytes = {0xf8, 0x00, 0xfa, 0xfa}; public static byte[] tare_bytes = {0xf8, 0x00, 0x60, 0x60}; public int counter = 0; // Use this for initialization void Start(){ // Allow the user to set the appropriate properties. sp.BaudRate = 115200; sp.Parity = Parity.None; sp.DataBits = 8; sp.StopBits = StopBits.One; // Set the read/write timeouts sp.WriteTimeout = 500; sp.ReadTimeout = 5; sp.Open(); sp.Write(send_bytes, 0, 4); } // Helper function for taking the bytes read from the 3-Space Sensor and // converting them into a float float bytesToFloat(byte[] raw_bytes, int offset){ byte[] big_bytes = new byte[4]; big_bytes[0] = raw_bytes[offset + 3]; big_bytes[1] = raw_bytes[offset + 2]; big_bytes[2] = raw_bytes[offset + 1]; big_bytes[3] = raw_bytes[offset + 0]; return BitConverter.ToSingle(big_bytes, 0); } void getButtonState(){ sp.Write(button_bytes, 0, 4); // Wireless packets always have a confirm and id byte pre-appened to the data byte[] confirm_byte = new byte[1]; byte[] id_byte = new byte[1]; int fail_counter = 0; // Mono, for some reason, seems to randomly fail on the first read after a wirte so we must loop // through to make sure the bytes are read while (true){ try{ sp.Read(confirm_byte, 0, 1); sp.Read(id_byte, 0, 1); break; } catch{ ++fail_counter; // Failed to read from serial port } if (fail_counter > 100){ throw new System.Exception("Failed to read from port too many times." + " This could mean the port is not open or the Mono serial read is not responding."); } } if (confirm_byte[0] == 0){ // Read data length of packet byte[] length_byte = new byte[1]; sp.Read(length_byte, 0, 1); byte length = length_byte[0]; // Read the length of the data in the packet byte[] read_bytes = new byte[length]; sp.Read(read_bytes, 0, length); if (read_bytes[0] == 0){ print("No buttons are pressed."); } else if (read_bytes[0] == 1){ print("Right button is pressed."); } else if (read_bytes[0] == 2){ print("Left button is pressed."); } else if (read_bytes[0] == 3){ print("Left and Right buttons are pressed."); } } } void tareSensor(){ sp.Write(tare_bytes, 0, 4); // Wireless packets always have a confirm and id byte pre-appened to the data byte[] confirm_byte = new byte[1]; byte[] id_byte = new byte[1]; int fail_counter = 0; // Mono, for some reason, seems to randomly fail on the first read after a wirte so we must loop // through to make sure the bytes are read while (true){ try{ sp.Read(confirm_byte, 0, 1); sp.Read(id_byte, 0, 1); break; } catch{ ++fail_counter; // Failed to read from serial port } if (fail_counter > 100){ throw new System.Exception("Failed to read from port too many times." + " This could mean the port is not open or the Mono serial read is not responding."); } } if (confirm_byte[0] == 0){ // Read data length of packet byte[] length_byte = new byte[1]; sp.Read(length_byte, 0, 1); byte length = length_byte[0]; // Read the length of the data in the packet byte[] read_bytes = new byte[length]; sp.Read(read_bytes, 0, length); } } // Update is called once per frame void Update(){ counter++; // Wireless packets always have a confirm and id byte pre-appened to the data byte[] confirm_byte = new byte[1]; byte[] id_byte = new byte[1]; int fail_counter = 0; // Mono, for some reason, seems to randomly fail on the first read after a wirte so we must loop // through to make sure the bytes are read while (true){ try{ sp.Read(confirm_byte, 0, 1); sp.Read(id_byte, 0, 1); break; } catch{ ++fail_counter; // Failed to read from serial port } if (fail_counter > 100){ throw new System.Exception("Failed to read from port too many times." + " This could mean the port is not open or the Mono serial read is not responding."); } } if (confirm_byte[0] == 0){ // Read data length of packet byte[] length_byte = new byte[1]; sp.Read(length_byte, 0, 1); byte length = length_byte[0]; // Read the length of the data in the packet byte[] read_bytes = new byte[length]; sp.Read(read_bytes, 0, length); // Convert bytes to floats float x = bytesToFloat(read_bytes, 0); float y = bytesToFloat(read_bytes, 4); float z = bytesToFloat(read_bytes, 8); float w = bytesToFloat(read_bytes, 12); // Create a quaternion Quaternion quat = new Quaternion(x, y, z, w); // Perform rotation transform.rotation = quat; } if ((counter % 25) == 0){ getButtonState(); } else if (counter > 150){ tareSensor(); counter = 1; } sp.Write(send_bytes, 0, 4); } }
IO.Portsが使えない問題:
http://d.hatena.ne.jp/shinobu_siv/20110622/1308746557
シリアルポートからの読み込みにSystem.IO.Portsパッケージを使っていますが、このパッケージはUnityが使用している.NET 2.0 Subsetには含まれていません。