Unity 3D игра с использованием акселерометра

Я занимаюсь разработкой виртуальной реальности для Windows. Я буду использовать датчик акселерометра, чтобы получить движения руки игрока и использовать его в игре, где игрок будет использовать его для борьбы с врагом в игре. Мне удалось получить показания акселерометра от датчика.

Мне просто нужно понять, как я могу теперь интегрировать это с моей игрой в Unity. Я использовал.Net, чтобы получить показания от датчика. Это тег датчика простой ссылки TI (CC2650STK). Это подключит через Bluetooth к моему телефону Windows.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Devices.Bluetooth.GenericAttributeProfile;
using Windows.Devices.Enumeration;
using Windows.Storage.Streams;
using Buffer = Windows.Storage.Streams.Buffer;

namespace SensorTag
{
    /// This class provides access to the SensorTag Accelerometer BLE data

    public class BleAccelerometerService : BleGenericGattService
    {

        public BleAccelerometerService() 
        {
        }


        /// The version of the SensorTag device.  1=CC2541, 2=CC2650.

        public int Version { get; set; }

        static Guid AccelerometerServiceUuid = Guid.Parse("f000aa10-0451-4000-b000-000000000000");
        static Guid AccelerometerCharacteristicUuid = Guid.Parse("f000aa11-0451-4000-b000-000000000000");
        static Guid AccelerometerCharacteristicConfigUuid = Guid.Parse("f000aa12-0451-4000-b000-000000000000");
        static Guid AccelerometerCharacteristicPeriodUuid = Guid.Parse("f000aa13-0451-4000-b000-000000000000");

        Delegate _accelerometerValueChanged;

        public event EventHandler<AccelerometerMeasurementEventArgs> AccelerometerMeasurementValueChanged
        {
            add
            {
                if (_accelerometerValueChanged != null)
                {
                    _accelerometerValueChanged = Delegate.Combine(_accelerometerValueChanged, value);
                }
                else
                {
                    _accelerometerValueChanged = value;
                    RegisterForValueChangeEvents(AccelerometerCharacteristicUuid);
                }
            }
            remove
            {
                if (_accelerometerValueChanged != null)
                {
                    _accelerometerValueChanged = Delegate.Remove(_accelerometerValueChanged, value);
                    if (_accelerometerValueChanged == null)
                    {
                        UnregisterForValueChangeEvents(AccelerometerCharacteristicUuid);
                    }
                }
            }
        }

        private async Task<int> GetConfig()
        {
            var ch = GetCharacteristic(AccelerometerCharacteristicConfigUuid);
            if (ch != null)
            {
                var properties = ch.CharacteristicProperties;

                if ((properties & GattCharacteristicProperties.Read) != 0)
                {
                    var result = await ch.ReadValueAsync();
                    IBuffer buffer = result.Value;
                    DataReader reader = DataReader.FromBuffer(buffer);
                    var value = reader.ReadByte();
                    Debug.WriteLine("Acceleration config = " + value);
                    return (int)value;
                }
            }
            return -1;
        }

        bool isReading;

        public async Task StartReading()
        {
            if (!isReading)
            {
                await WriteCharacteristicByte(AccelerometerCharacteristicConfigUuid, 1);
                isReading = true;
            }
        }

        public async Task StopReading()
        {
            if (isReading)
            {
                isReading = false;
                await WriteCharacteristicByte(AccelerometerCharacteristicConfigUuid, 0);
            }
        }


        /// Get the rate at which accelerometer is being polled, in milliseconds.  
        /// </summary>
        /// <returns>Returns the value read from the sensor or -1 if something goes wrong.</returns>
        public async Task<int> GetPeriod()
        {
            byte v = await ReadCharacteristicByte(AccelerometerCharacteristicPeriodUuid, Windows.Devices.Bluetooth.BluetoothCacheMode.Uncached);
            return (int)(v * 10);
        }

        /// <summary>
        /// Set the rate at which accelerometer is being polled, in milliseconds.  
        /// </summary>
        /// <param name="milliseconds">The delay between updates, accurate only to 10ms intervals. Maximum value is 2550.</param>
        public async Task SetPeriod(int milliseconds)
        {
            int delay = milliseconds / 10;
            byte p = (byte)delay;
            if (p < 1)
            {
                p = 1;
            }

            await WriteCharacteristicByte(AccelerometerCharacteristicPeriodUuid, p);
        }

        private void OnAccelerationMeasurementValueChanged(AccelerometerMeasurementEventArgs args)
        {
            if (_accelerometerValueChanged != null)
            {
                ((EventHandler<AccelerometerMeasurementEventArgs>)_accelerometerValueChanged)(this, args);
            }
        }


        public async Task<bool> ConnectAsync(string deviceContainerId)
        {
            return await this.ConnectAsync(AccelerometerServiceUuid, deviceContainerId);
        }

        protected override void OnCharacteristicValueChanged(GattCharacteristic sender, GattValueChangedEventArgs eventArgs)
        {
            if (sender.Uuid == AccelerometerCharacteristicUuid)
            {
                if (_accelerometerValueChanged != null)
                {
                    uint dataLength = eventArgs.CharacteristicValue.Length;
                    using (DataReader reader = DataReader.FromBuffer(eventArgs.CharacteristicValue))
                    {
                        if (dataLength == 3)
                        {
                            var data = new byte[dataLength];
                            reader.ReadBytes(data);

                            AccelerometerMeasurement measurement = new AccelerometerMeasurement();

                            sbyte x = (sbyte)data[0];
                            sbyte y = (sbyte)data[1];
                            sbyte z = (sbyte)data[2];

                            measurement.X = (double)x / 64.0;
                            measurement.Y = (double)y / 64.0;
                            measurement.Z = (double)z / 64.0;

                            OnAccelerationMeasurementValueChanged(new AccelerometerMeasurementEventArgs(measurement, eventArgs.Timestamp));
                        }
                    }
                }
            }
        }

    }


    public class AccelerometerMeasurement
    {
        /// <summary>
        /// Get/Set X accelerometer in units of 1 g (9.81 m/s^2).
        /// </summary>
        public double X { get; set;}   

        /// <summary>
        /// Get/Set Y accelerometer in units of 1 g (9.81 m/s^2).
        /// </summary>
        public double Y { get; set;}        

        /// <summary>
        /// Get/Set Z accelerometer in units of 1 g (9.81 m/s^2).
        /// </summary>
        public double Z { get; set;}

        public AccelerometerMeasurement()
        {
        }

    }

    public class AccelerometerMeasurementEventArgs : EventArgs
    {
        public AccelerometerMeasurementEventArgs(AccelerometerMeasurement measurement, DateTimeOffset timestamp)
        {
            Measurement = measurement;
            Timestamp = timestamp;
        }

        public AccelerometerMeasurement Measurement
        {
            get;
            private set;
        }

        public DateTimeOffset Timestamp
        {
            get;
            private set;
        }
    }

}

1 ответ

Решение

Одним из требований будет преобразование значений ускорения в кватернион:

private void ReadAcceleration(AccelerometerMeasurement measure){
    Vector3 accel = new Vector3((float)measure.X, 
            (float)measure.Y, (float)measure.Z);
    Quaternion rotation = Quaternion.LookRotation(accel,Vector3.forward);
}

Кватернион вращения можно использовать для установки объекта на поворот устройства.

Другие вопросы по тегам