using UnityEngine; using System.Collections; using System.Collections.Generic; using System; public class TurntableSensorCamera : MonoBehaviour { public Transform target; public float distance; public float heightdistance; public bool useRelativeCameraRotation = true; // initial camera and sensor value private Quaternion initialCameraRotation = Quaternion.identity; List<Quaternion> quaternionList = new List<Quaternion>(); private bool gotFirstValue = false; float timer = 0f; // Use this for initialization void Start() { Input.compass.enabled = true; // for distance calculation --> its much easier to make adjusments in the editor, just put // your camera where you want it to be if (target == null) { Debug.LogWarning("Warning! Target for TurntableSensorCamera is null."); return; } // if distance is set to zero, use current camera position --> easier setup if (distance == 0) distance = (transform.position - target.position).magnitude; heightdistance = -1; // if you start the app, you will be viewing in the same direction your unity camera looks right now if (useRelativeCameraRotation) initialCameraRotation = Quaternion.Euler(0, -transform.rotation.eulerAngles.y, 0); else initialCameraRotation = Quaternion.identity; print(-transform.rotation.eulerAngles.y); // direct call // Sensor.Activate(Sensor.Type.RotationVector); // SensorHelper call with fallback // SensorHelper.ActivateRotation(); SensorHelper.TryForceRotationFallback(RotationFallbackType.OrientationAndAcceleration); StartCoroutine(Calibration()); } IEnumerator Calibration() { gotFirstValue = false; while (!SensorHelper.gotFirstValue) { SensorHelper.FetchValue(); yield return null; } SensorHelper.FetchValue(); // wait some frames yield return new WaitForSeconds(0.1f); // Initialize rotation values Quaternion initialSensorRotation = SensorHelper.rotation; initialCameraRotation *= Quaternion.Euler(0, Input.compass.trueHeading - initialSensorRotation.eulerAngles.y, 0);//真实方向 // allow updates gotFirstValue = true; } AngleFilter magneticFilter = new AngleFilter(10); // Update is called once per frame void LateUpdate() { // first value gotten from sensor is the offset value for further processing if (useRelativeCameraRotation) if (!gotFirstValue) return; // do nothing if there is no target timer += Time.deltaTime; if (target == null) return; if (timer >= 1 && timer <= 1.5) { initialCameraRotation = Quaternion.identity; Quaternion initialSensorRotation = SensorHelper.rotation; switch (Input.deviceOrientation) { case DeviceOrientation.FaceDown://该设备与地面平行,屏幕朝下。 initialCameraRotation *= Quaternion.Euler(0, initialSensorRotation.eulerAngles.y - Input.compass.trueHeading, 0);//真实方向 break; case DeviceOrientation.FaceUp://该设备与地面平行,屏幕朝上。 case DeviceOrientation.LandscapeLeft://设备处于横向模式,设备保持直立状态 case DeviceOrientation.LandscapeRight://设备处于横向模式,设备保持直立状态 case DeviceOrientation.Portrait://设备处于竖屏模式,设备保持直立状态 case DeviceOrientation.PortraitUpsideDown://该设备处于竖屏模式,但上下颠倒,设备直立。 initialCameraRotation *= Quaternion.Euler(0, Input.compass.trueHeading - initialSensorRotation.eulerAngles.y, 0);//真实方向 break; } Quaternion q = initialCameraRotation * SensorHelper.rotation; transform.rotation = Quaternion.Slerp(transform.rotation, q, 0.5f); if (timer > 1.5f) timer = 0; } else { quaternionList.Add(initialCameraRotation * SensorHelper.rotation); if (quaternionList.Count > 1) { Quaternion q = new Quaternion(Round(EndPosionManager.Average(quaternionList).x, 1), Round(EndPosionManager.Average(quaternionList).y, 1), Round(EndPosionManager.Average(quaternionList).z, 1), EndPosionManager.Average(quaternionList).w); transform.rotation = Quaternion.Slerp(transform.rotation, q, 0.2f); quaternionList.Clear(); } } transform.position = target.position - transform.forward * distance - transform.up * heightdistance; } float Round(float x, int f)//四元数精度处理 { float result = (float)Math.Round((double)x, f); return result; }
插件 GyroDroid
下载地址 http://www.manew.com/thread-3596-1-1.html
【C#】AR unity 陀螺仪控制摄像机 真实方向
最新推荐文章于 2024-06-19 11:06:54 发布