Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 纸板磁铁检测_C#_Unity3d - Fatal编程技术网

C# 纸板磁铁检测

C# 纸板磁铁检测,c#,unity3d,C#,Unity3d,我的unity硬纸板应用程序出现了一些问题。希望你们中的一些人能帮助我。 我已经建立了一个小岛与动画和第二个岛作为主菜单。 因此,当应用程序启动时,您可以从上方看到岛和应用程序的徽标。 当用户拉下侧面的磁铁按钮时,应用程序将启动另一个级别 我使用了以下脚本: 检测谷歌纸板磁性按钮点击-单例实现 CardboardMagnetSensor.cs和CardboardTriggerControlMono.cs 我在我的资产文件夹(CardboardMagnetSensor.cs)中创建了一个脚本,就

我的unity硬纸板应用程序出现了一些问题。希望你们中的一些人能帮助我。 我已经建立了一个小岛与动画和第二个岛作为主菜单。 因此,当应用程序启动时,您可以从上方看到岛和应用程序的徽标。 当用户拉下侧面的磁铁按钮时,应用程序将启动另一个级别

我使用了以下脚本:

检测谷歌纸板磁性按钮点击-单例实现 CardboardMagnetSensor.cs和CardboardTriggerControlMono.cs

我在我的资产文件夹(CardboardMagnetSensor.cs)中创建了一个脚本,就像链接中的描述一样。然后我创建了第二个脚本(CardboardTriggerControlMono.cs),就像在5月份的项目中描述的那样,并将它拖到了我的CardboardMain上

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;
    }
}
使用UnityEngine;
使用System.Collections.Generic;
公共级卡板磁传感器{
//常数:
私有常量int窗口大小=40;
私有常量int NUM_段=2;
私有常量int段大小=窗口大小/NUM段;
私有常量int T1=30,T2=130;
//变量:
private static bool已单击;//一旦启动,将翻转为true。
专用静态布尔传感器已启用;//传感器已激活。
私有静态列表sensorData;//保存磁性传感器数据。
私有静态浮点[]偏移量;//用于检测单击的偏移量。
//在开始时调用此命令一次以启用检测。
公共静态无效设置已启用(bool已启用){
重置();
传感器启用=启用;
Input.compass.enabled=传感器已启用;
}
//重置变量。
公共静态无效重置(){
sensorData=新列表(窗口大小);
偏移=新浮动[段大小];
wasClicked=false;
sensorEnabled=false;
}
//每帧轮询一次,以检测何时单击磁铁按钮
//如果单击了它,请确保调用“ResetClick()”
//在处理该操作之后,它将继续返回true。
公共静态bool CheckIfWasClicked(){
更新数据();
点击返回按钮;
}
//处理完单击操作后调用此函数。
公共静态无效重置单击(){
wasClicked=false;
}
//更新“传感器数据”并确定是否单击了磁铁。
私有静态void UpdateData(){
Vector3 currentVector=Input.compass.rawVector;
if(currentVector.x==0&¤tVector.y==0&¤tVector.z==0){
返回;
}
如果(sensorData.Count>=窗口大小)sensorData.RemoveAt(0);
sensorData.Add(currentVector);
//评估模型:
if(sensorData.Count<窗口大小)返回;
浮动[]表示=新浮动[2];
浮动[]最大值=新浮动[2];
浮动[]最小值=新浮动[2];
Vector3基线=传感器数据[sensorData.Count-1];
对于(int i=0;iT2){
sensorData.Clear();
wasClicked=true;//将单击的按钮设置为true。
//注意:在调用“ResetClick()”之前,“wasClicked”现在将保持为true。
}
}
专用静态浮点[]计算偏移量(整数开始,矢量3基线){
对于(int i=0;i<段大小;i++){
矢量3点=传感器数据[start+i];
Vector3o=新的Vector3(点.x-基线.x,点.y-基线.y,点.z-基线.z);
偏移量[i]=o.量级;
}
返回偏移量;
}
专用静态浮点计算平均值(浮点[]偏移量){
浮点数和=0;
foreach(偏移量中的浮点o){
总和+=o;
}
返回和/偏移量。长度;
}
专用静态浮点计算最大值(浮点[]偏移量){
float max=float.MinValue;
foreach(偏移量中的浮点o){
最大值=最大值(o,最大值);
}
返回最大值;
}
私有静态浮点计算最小值(浮点[]偏移量){
float min=float.MaxValue;
foreach(偏移量中的浮点o){
最小值=数学最小值(o,最小值);
}
返回最小值;
}
}
我的步骤是:

(抱歉,我无法在此上传图片)

但无论如何,它不会起作用。当我启动应用程序并拉下磁铁时,什么也没发生。我把级别转换为级别索引可能有问题吗

我使用Nexus4和Nexus5测试应用程序

感谢allot和greetz


Phillip

如果您使用的是用于Unity的谷歌硬纸板SDK,它目前有一个bug,阻止Unity看到磁铁(以及陀螺仪和加速计)。这可能就是您的脚本无法工作的原因。在修复错误之前,没有很好的解决方法,但是您可以使用Cardward.CardboardTriggered属性来检测磁铁是否被拉过

Unity 5更新:传感器错误消失。纸板SDK不会阻塞传感器