C# 纸板磁铁检测
我的unity硬纸板应用程序出现了一些问题。希望你们中的一些人能帮助我。 我已经建立了一个小岛与动画和第二个岛作为主菜单。 因此,当应用程序启动时,您可以从上方看到岛和应用程序的徽标。 当用户拉下侧面的磁铁按钮时,应用程序将启动另一个级别 我使用了以下脚本: 检测谷歌纸板磁性按钮点击-单例实现 CardboardMagnetSensor.cs和CardboardTriggerControlMono.cs 我在我的资产文件夹(CardboardMagnetSensor.cs)中创建了一个脚本,就像链接中的描述一样。然后我创建了第二个脚本(CardboardTriggerControlMono.cs),就像在5月份的项目中描述的那样,并将它拖到了我的CardboardMain上 CardboardTriggerControlMono.cs看起来像:C# 纸板磁铁检测,c#,unity3d,C#,Unity3d,我的unity硬纸板应用程序出现了一些问题。希望你们中的一些人能帮助我。 我已经建立了一个小岛与动画和第二个岛作为主菜单。 因此,当应用程序启动时,您可以从上方看到岛和应用程序的徽标。 当用户拉下侧面的磁铁按钮时,应用程序将启动另一个级别 我使用了以下脚本: 检测谷歌纸板磁性按钮点击-单例实现 CardboardMagnetSensor.cs和CardboardTriggerControlMono.cs 我在我的资产文件夹(CardboardMagnetSensor.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不会阻塞传感器