AR设备使用Vuforia的优化
主要是设置识别的范围,在应用内检测当前识别图和我的距离,以及识别图和我的角度,当进入了规定的范围和角度后,
在进行定位功能。我目前用的是距离在两米内 摄像机和识别图的角度正负不超过30度的范围
VuforiaManager 管理
VuforialFindImageAction 识别图上,设置对应管理里的第几个VuforiaAnchor
VuforiaAnchor 定位的物体,注意旋转,Z轴要和Camera 看向物体的方向一致(反正180 自己测一下)
/**************************** summary: ****************************/ using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class VuforiaManager : MonoSingleton<VuforiaManager> { /// <summary> /// 当前生成的场景 /// </summary> public Transform sceneMap; //[SerializeField] //private List<Transform> list_ImageTargetObj; [SerializeField] public List<VuforiaAnchor> list_Anchor; private VuforiaAnchor oldAnchor; public Text text; public bool isCorrect; private void Start() { oldAnchor = null; StartCoroutine(LoadARCamera()); isCorrect = false; } //private void Update() //{ // if (oldAnchor != null) // text.text = oldAnchor.transform.eulerAngles.x + " " + oldAnchor.transform.eulerAngles.y + " " + oldAnchor.transform.eulerAngles.z; //} public void TrackingFound(Transform targetObj , int num) { try { if (list_Anchor.Count < (num+1) || list_Anchor.Count < 1) return; SelectSceneAnchor(targetObj, num); } catch (System.Exception e) { Debug.LogError(e.Message); } } public void TrackingLost(int num) { if (list_Anchor.Count < (num+1) || list_Anchor.Count < 1) return; list_Anchor[num].Close(); } public void SelectSceneAnchor(Transform targetObj, int num) { if (oldAnchor == null) { oldAnchor = list_Anchor[num]; oldAnchor.Show(targetObj); } else if (oldAnchor == list_Anchor[num]) { // oldTarget.DirectClose(); oldAnchor.ReplaceShow(); } else if (oldAnchor != list_Anchor[num]) { oldAnchor.DirectClose(); oldAnchor = list_Anchor[num]; oldAnchor.Show(targetObj); // if(oldAnchor!=list_Anchor[num].gameObject) } } public void ARCameraLoad() { // StartCoroutine(LoadARCamera()); } IEnumerator LoadARCamera() { // yield return API_GSXR_Slam.SlamManager.IsRunning; yield return new WaitForSeconds(2f); GameObject.Instantiate(Resources.Load<GameObject>("ARCamera")); } }
/**************************** summary: 计算锚点差值,定位场景 ****************************/ using System.Collections; using System.Collections.Generic; using UnityEngine; public class VuforiaAnchor : MonoBehaviour { private Transform targetObj = null; private bool state = false; private bool onlySet = true; // private Collider[] coliders; public Transform player; private float y; private Vector3 disPos; private float dic; private Vector3 dir; private Vector3 cross; private float dot; private float deg; private void Start() { // player = API_SVR.GetHead(); } private void FixedUpdate() { /* * 1.首次定位时直接整体 移动选择 * 2.后续矫正判断识别图和Player的公积和距离,在范围内再进行移动 * */ if (state && VuforiaManager.Instance.isCorrect) { if (player == null) return; if (onlySet) { onlySet = false; y = targetObj.eulerAngles.y - transform.eulerAngles.y; VuforiaManager.Instance.sceneMap.eulerAngles += new Vector3(0, y, 0); disPos = targetObj.position - transform.position; //Debug.Log(transform.position + " " + targetObj.position); //Debug.Log(VuforiaManager.Instance.sceneMap.position); //Debug.Log(" DisPos " + disPos); VuforiaManager.Instance.sceneMap.position += disPos; } else { Vector3 disPos = targetObj.position - transform.position; disPos = VuforiaManager.Instance.sceneMap.position + disPos; VuforiaManager.Instance.sceneMap.position = Vector3.Lerp(VuforiaManager.Instance.sceneMap.position, disPos, Time.deltaTime * 10f); } } } // 首次定位 public void Show( Transform targetObj) { Debug.Log(" Show "); this.targetObj = targetObj; // StartCoroutine(Show(1)); state = true; onlySet = true; } //再次定位 public void ReplaceShow() { state = true; // onlySet = true; // StartCoroutine(Show(1)); } // 关闭 public void Close() { state = false; } // 强制关闭 public void DirectClose() { state = false; } public void PhysicsCollider() { //coliders = Physics.OverlapSphere(transform.position, 2.5f, 8); //player = coliders[0].transform; //if (coliders.Length>1) //{ // Debug.LogError(" 检测玩家个数设置错误 "); // return; //} } IEnumerator Show(float timer) { yield return new WaitForSeconds(timer); float y = targetObj.eulerAngles.y - transform.eulerAngles.y; VuforiaManager.Instance.sceneMap.eulerAngles += new Vector3(0, y, 0); Vector3 disPos = targetObj.position - transform.position; Debug.Log(transform.position + " " + targetObj.position); Debug.Log(VuforiaManager.Instance.sceneMap.position); Debug.Log(" DisPos " + disPos); VuforiaManager.Instance.sceneMap.position += disPos; } }
using System.Collections; using System.Collections.Generic; using UnityEngine; public class VuforialFindImageAction : DefaultTrackableEventHandler { public string Name; // [HideInInspector] public TargetObjDeg targetObj; // [HideInInspector] public int num; [HideInInspector] public int pointObj; protected override void OnTrackingFound() { //if (VuforialMap.Instance != null) // VuforialMap.Instance.TargetPointShow(this); if (VuforiaManager.Instance != null) { Debug.Log(num); // VuforialControl.Instance.TrackingFound(targetObj, num, pointObj); VuforiaManager.Instance.TrackingFound(targetObj.transform, num); targetObj.state = true; } base.OnTrackingFound(); } protected override void OnTrackingLost() { // VuforialControl.Instance.TrackingLost(num); if(VuforiaManager.Instance!=null) { Debug.Log(num); VuforiaManager.Instance.TrackingLost(num); targetObj.state = false; } //if (VuforialMap.Instance != null) // VuforialMap.Instance.TargetPointClose(this); base.OnTrackingLost(); } } public enum ShowObj { ScenicSpot = 0, Rotue = 1, obj3D = 2 }