Detecting Google Cardboard Magnetic Button Click

落花浮王杯 提交于 2020-01-06 02:40:05

问题


I'm developing a VR app with cardboard. When I click twice on the magnetic button, I want the menu to appear.

How do I write this condition in C#?


回答1:


In brief, you need to detect that your phone's compass changed without any tilt (i.e., the magnet has gotten close to the phone and disrupted its compass without changing its physical orientation).

You'll want to look at both vectors and see if they've changed.

There's two open source implementations, the simplest of which I shamelessly include below (all credit to Andrew Whyte from Secret Ingredient Games):

  1. http://www.andrewnoske.com/wiki/Unity_-_Detecting_Google_Cardboard_Click
  2. https://github.com/CaseyB/UnityCardboardTrigger/blob/develop/MagnetSensor.cs
/*     -- 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;
    }
  }
}


来源:https://stackoverflow.com/questions/37228072/detecting-google-cardboard-magnetic-button-click

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!