检测Google Cardboard磁性按钮单击

时间:2016-05-14 14:49:04

标签: unity5 google-cardboard

我正在用纸板开发VR应用程序。当我在磁性按钮上单击两次时,我希望菜单出现。

如何在C#中编写此条件?

1 个答案:

答案 0 :(得分:0)

简而言之,您需要检测到手机的指南针在没有任何倾斜的情况下发生了变化(即磁铁已经靠近手机并且在不改变其物理方向的情况下中断了指南针)。

您想要查看这两个向量,看看它们是否已发生变化。

有两个开源实现,其中最简单的是我在下面无耻地包含(所有信用来自Secret Ingredient Games的Andrew Whyte):

  1. http://www.andrewnoske.com/wiki/Unity_-_Detecting_Google_Cardboard_Click
  2. https://github.com/CaseyB/UnityCardboardTrigger/blob/develop/MagnetSensor.cs
  3. /*     -- MIT/X11 like license --
    Copyright (c) 2014 Paramita ltd, (Secret Ingredient Games)
    */
    
    //
    //  Google Cardboard click code in C# for Unity.
    //  Author: Andrew Whyte
    //
    using UnityEngine;
    using System.Collections;
    using System;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.IO;
    
    //public static XmlDocument XmlDoc;
    //public static XmlNodeList xnl;
    //public TextAsset TA;
    
    public class magneticClick {
      //  Concept: two FIR filters,  running on Magnetics and tilt.
      //  If the tilt hasn't changed, but the compass has, then the magnetic field moved
      //  without device this is the essence of a cardboard magnet click.
      private Vector3 lastTiltVector;
      public float tiltedBaseLine = 0f;
      public float magnetBaseLine = 0f;
    
      public float tiltedMagn = 0f;
      public float magnetMagn = 0f;
    
      private int N_SlowFIR = 25;
      private int N_FastFIR_magnet = 3;
      private int N_FastFIR_tilted = 5;  // Clicking the magnet tends to tilt the device slightly.
    
    
      public float threshold = 1.0f;
    
      bool click = false;
      bool clickReported = false;
    
      public void init() {
        Input.compass.enabled = true;
    
        // Note that init is platform specific to unity.
        magnetMagn = Input.compass.rawVector.magnitude;
        magnetBaseLine = Input.compass.rawVector.magnitude;
        tiltedBaseLine = Input.acceleration.magnitude;
        tiltedMagn = Input.acceleration.magnitude;
      }
    
      public void magUpdate(Vector3 acc,  Vector3 compass) {
        // Call this function in the Update of a monobehaviour as follows:
        // <magneticClickInstance>.magUpdate(Input.acceleration, Input.compass.rawVector);
    
        // we are interested in the change of the tilt not the actual tilt.
        Vector3 TiltNow = acc;
        Vector3 motionVec3 = TiltNow - lastTiltVector;
        lastTiltVector = TiltNow;
    
        // update tilt and compass "fast" values
        tiltedMagn = ((N_FastFIR_tilted-1) * tiltedMagn + motionVec3.magnitude) / N_FastFIR_tilted;
        magnetMagn = ((N_FastFIR_magnet-1) * magnetMagn + compass.magnitude) / N_FastFIR_magnet;
    
        // update the "slow" values
        tiltedBaseLine = ( (N_SlowFIR-1) * tiltedBaseLine + motionVec3.magnitude) / N_SlowFIR;
        magnetBaseLine = ( (N_SlowFIR-1) * magnetBaseLine + compass.magnitude) / N_SlowFIR;
    
        if( tiltedMagn < 0.2 && (magnetMagn / magnetBaseLine) > 1.1  ) {
          if( clickReported == false) {
            click = true;
          }
          clickReported = true;
        } else  {
          clickReported = false;
        }
      }
    
      public bool clicked()  {
        // Basic premise is that the magnitude of magnetic field should change while the 
        // device is steady.  This seems to be suiltable for menus etc.
    
        // Clear the click by reading (so each 'click' returns true only once)
        if(click == true) {
          click = false;
          return true;
        } else {
          return false;
        }
      }
    }