纸板磁铁检测

时间:2015-02-03 12:13:01

标签: c# unity3d

我的团结纸板应用程序遇到了麻烦。愿你们中的一些人能帮助我。 我建造了一个带有动画的小岛和一个第二岛作为主菜单。 因此,当应用程序启动时,您会看到上面的岛屿和应用程序的徽标。 当用户拉下侧面的磁铁按钮时,应用程序将启动另一个级别。

我用过这个脚本:

http://www.andrewnoske.com/wiki/Unity_-_Detecting_Google_Cardboard_Click

检测Google Cardboard磁性按钮单击 - 单例实现 CardboardMagnetSensor.cs和CardboardTriggerControlMono.cs

我在资产文件夹(CardboardMagnetSensor.cs)中创建了一个脚本,就像Link中的描述一样。比我在描述中创建了第二个脚本(CardboardTriggerControlMono.cs),将它拖到了我的CardboardMain中,可能是Projekt。

CardboardTriggerControlMono.cs看起来像:

using UnityEngine;
using System.Collections;

public class CardboardTriggerControlMono : MonoBehaviour {
    public bool magnetDetectionEnabled = true;

    void Start() {
        CardboardMagnetSensor.SetEnabled(magnetDetectionEnabled);
        // Disable screen dimming:
        Screen.sleepTimeout = SleepTimeout.NeverSleep;


    } 

    void Update () {
        if (!magnetDetectionEnabled) return;
        if (CardboardMagnetSensor.CheckIfWasClicked()) {
            Debug.Log("Cardboard trigger was just clicked");
            Application.LoadLevel(1);
            CardboardMagnetSensor.ResetClick();

        }
    }
}

CarboardMagnetSensor:

using UnityEngine;
using System.Collections.Generic;

public class CardboardMagnetSensor {
    // Constants:
    private const int WINDOW_SIZE = 40;
    private const int NUM_SEGMENTS = 2;
    private const int SEGMENT_SIZE = WINDOW_SIZE / NUM_SEGMENTS;
    private const int T1 = 30, T2 = 130;

    // Variables:
    private static bool wasClicked;           // Flips to true once set off.
    private static bool sensorEnabled;        // Is sensor active.
    private static List<Vector3> sensorData;  // Keeps magnetic sensor data.
    private static float[] offsets;           // Offsets used to detect click.


    // Call this once at beginning to enable detection.
    public static void SetEnabled(bool enabled) {
        Reset();
        sensorEnabled = enabled;
        Input.compass.enabled = sensorEnabled;

    }

    // Reset variables.
    public static void Reset() {
        sensorData = new List<Vector3>(WINDOW_SIZE);
        offsets = new float[SEGMENT_SIZE];
        wasClicked = false;
        sensorEnabled = false;

    }

    // Poll this once every frame to detect when the magnet button was clicked
    // and if it was clicked make sure to call "ResetClick()"
    // after you've dealt with the action, or it will continue to return true.
    public static bool CheckIfWasClicked() {
        UpdateData();
        return wasClicked;
    }

    // Call this after you've dealt with a click operation.
    public static void ResetClick() {
        wasClicked = false;
    }

    // Updates 'sensorData' and determines if magnet was clicked.
    private static void UpdateData() {
        Vector3 currentVector = Input.compass.rawVector;



        if (currentVector.x == 0 && currentVector.y == 0 && currentVector.z == 0) {

            return;
        }

        if(sensorData.Count >= WINDOW_SIZE) sensorData.RemoveAt(0);
        sensorData.Add(currentVector);

        // Evaluate model:
        if(sensorData.Count < WINDOW_SIZE) return;

        float[] means = new float[2];
        float[] maximums = new float[2];
        float[] minimums = new float[2];

        Vector3 baseline = sensorData[sensorData.Count - 1];

        for(int i = 0; i < NUM_SEGMENTS; i++) {
            int segmentStart = 20 * i;
            offsets = ComputeOffsets(segmentStart, baseline);

            means[i] = ComputeMean(offsets);
            maximums[i] = ComputeMaximum(offsets);
            minimums[i] = ComputeMinimum(offsets);
        }

        float min1 = minimums[0];
        float max2 = maximums[1];

        // Determine if button was clicked.
        if(min1 < T1 && max2 > T2) {
            sensorData.Clear();
            wasClicked = true;  // Set button clicked to true.
            // NOTE: 'wasClicked' will now remain true until "ResetClick()" is called.
        }
    }

    private static float[] ComputeOffsets(int start, Vector3 baseline) {
        for(int i = 0; i < SEGMENT_SIZE; i++) {
            Vector3 point = sensorData[start + i];
            Vector3 o = new Vector3(point.x - baseline.x, point.y - baseline.y, point.z - baseline.z);
            offsets[i] = o.magnitude;
        }
        return offsets;
    }

    private static float ComputeMean(float[] offsets) {
        float sum = 0;
        foreach(float o in offsets) {
            sum += o;
        }
        return sum / offsets.Length;
    }

    private static float ComputeMaximum(float[] offsets) {
        float max = float.MinValue;
        foreach(float o in offsets) {
            max = Mathf.Max(o, max);
        }
        return max;
    }

    private static float ComputeMinimum(float[] offsets) {
        float min = float.MaxValue;
        foreach(float o in offsets) {
            min = Mathf.Min(o, min);
        }
        return min;
    }
}

我的步骤:

http://www.directupload.net/file/d/3887/mtjygjan_jpg.htm

(对不起,我不能在这里上传图片)

然而,它不会工作。当我启动应用程序并拉下磁铁时,没有任何反应。我是否可以将级别转换为级别索引?

我使用nexus 4和5来测试应用程序

感谢分配给你和你好!

菲利普

1 个答案:

答案 0 :(得分:-1)

如果您使用的是适用于Unity的Google Cardboard SDK,它目前有一个错误,可以防止Unity看到磁铁(以及陀螺仪和加速度计)。这可能就是你的脚本不起作用的原因。在修复错误之前,没有好的解决方法,但您可以使用属性Cardboard.CardboardTriggered来检测磁铁是否被拉动。

Unity 5更新:传感器错误消失了。 Cardboard SDK不会阻止传感器。