背景:
AR项目开发时遇到的这个问题,即扫描的底图特别大,好几米×好几米的那种,只用一台手机或者Pad不可能扫描到底图的全部分,所以要实现只扫描底图的局部即可实现AR功能,并且模型位置准确。
ps:EsayAR可以扫描局部。。。
方法:
1、将大图用PS分成了1×1米的N个小图。
2、将小图全部放到ARFoundationReferenceImageLibrary中。名字123.。。
1.png
3、Anchor的预制体放N个锚点(排列与Library中小图的顺序相反,即小图切开的顺序是左上到右下,锚点的放置是右下到左上,小图第一张在左上,锚点第一个在右下。但对应名字是相同,你懂我意思吧=。=?我这儿切了18张小图,所以放18个锚点)
2.png
4、上代码(Jobe)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.ARSubsystems;
using UnityEngine.XR.ARFoundation;
using UnityEngine.UI;
public class ImageController : MonoBehaviour
{
ARTrackedImageManager imageTrackManager;
ARAnchorManager anchorManager;
Vector3 vecpos,vecScl;
Quaternion quarot;
GameObject AnchorObj,AnchorChild,DayObj,NightObj;
public GameObject DayButton, NightButton;
public Slider ScaleControlSlider;
bool isDay = true;
public GameObject AnchorButton, TrackButton;
GameObject[] AnchorPoint = new GameObject[18];
bool IsAnchorCreat = false;
bool IsBuildSource,isStartBuild;
public GameObject UITishiObj,SaomiaoUI,Tishikuang;
public GameObject CamObj;
public List<GameObject> ImgTargetObj = new List<GameObject>();
private List<float> ObjList;
private Dictionary<float, GameObject> TargetDic;
List<float> dis = new List<float>();
float MinDis = 500;
public Text text;
// Start is called before the first frame update
void Awake()
{
ManagerAudio.Instance.PlayBg(TypeAudio.Music.BeiJing01, true);
imageTrackManager = GetComponent<ARTrackedImageManager>();
anchorManager = GetComponent<ARAnchorManager>();
TargetDic = new Dictionary<float, GameObject>();
ObjList = new List<float>();
UITishiObj.SetActive(false);
SaomiaoUI.SetActive(true);
Tishikuang.SetActive(false);
DayObj = new GameObject();
NightObj = new GameObject();
AnchorObj = new GameObject();
IsBuildSource = false;
isStartBuild = true;
DayButton.SetActive(false);
NightButton.SetActive(true);
NightButton.gameObject.GetComponent<Button>().interactable = false;
AnchorButton.gameObject.GetComponent<Button>().interactable = false;
ScaleControlSlider.gameObject.SetActive(false);
}
private void OnEnable()
{
imageTrackManager.trackedImagesChanged += OnTrackedImagesChanged;
anchorManager.anchorsChanged += OnAnchorsChanged;
}
void OnDisable()
{
imageTrackManager.trackedImagesChanged -= OnTrackedImagesChanged;
anchorManager.anchorsChanged -= OnAnchorsChanged;
}
void UpdateInfo(ARTrackedImage trackedImage)
{
//if (trackedImage.trackingState != TrackingState.None)
//{
// vecpos = imageTrackManager.trackedImagePrefab.gameObject.transform.position;
// quarot = imageTrackManager.trackedImagePrefab.gameObject.transform.rotation;
//}
}
void OnTrackedImagesChanged(ARTrackedImagesChangedEventArgs eventArgs)
{
foreach (var item in eventArgs.added)
{
ImgTargetObj.Add(item.gameObject);
if (!IsAnchorCreat)
{
vecpos = item.transform.position;
quarot = item.transform.rotation;
AnchorObj = anchorManager.AddAnchor(new Pose(vecpos, quarot)).gameObject;
AnchorChild = AnchorObj.gameObject.transform.GetChild(18).gameObject;
AnchorPoint[0] = AnchorObj.gameObject.transform.GetChild(0).gameObject;
AnchorPoint[1] = AnchorObj.gameObject.transform.GetChild(1).gameObject;
AnchorPoint[2] = AnchorObj.gameObject.transform.GetChild(2).gameObject;
AnchorPoint[3] = AnchorObj.gameObject.transform.GetChild(3).gameObject;
AnchorPoint[4] = AnchorObj.gameObject.transform.GetChild(4).gameObject;
AnchorPoint[5] = AnchorObj.gameObject.transform.GetChild(5).gameObject;
AnchorPoint[6] = AnchorObj.gameObject.transform.GetChild(6).gameObject;
AnchorPoint[7] = AnchorObj.gameObject.transform.GetChild(7).gameObject;
AnchorPoint[8] = AnchorObj.gameObject.transform.GetChild(8).gameObject;
AnchorPoint[9] = AnchorObj.gameObject.transform.GetChild(9).gameObject;
AnchorPoint[10] = AnchorObj.gameObject.transform.GetChild(10).gameObject;
AnchorPoint[11] = AnchorObj.gameObject.transform.GetChild(11).gameObject;
AnchorPoint[12] = AnchorObj.gameObject.transform.GetChild(12).gameObject;
AnchorPoint[13] = AnchorObj.gameObject.transform.GetChild(13).gameObject;
AnchorPoint[14] = AnchorObj.gameObject.transform.GetChild(14).gameObject;
AnchorPoint[15] = AnchorObj.gameObject.transform.GetChild(15).gameObject;
AnchorPoint[16] = AnchorObj.gameObject.transform.GetChild(16).gameObject;
AnchorPoint[17] = AnchorObj.gameObject.transform.GetChild(17).gameObject;
AnchorButton.gameObject.GetComponent<Button>().interactable = true;
UITishiObj.SetActive(true);
SaomiaoUI.SetActive(false);
ScaleControlSlider.gameObject.SetActive(true);
IsAnchorCreat = true;
}
//if(!IsBuildSource)
//{
// AnchorChild.gameObject.transform.parent = AnchorPoint[int.Parse(item.referenceImage.name) - 1].transform;
// AnchorChild.gameObject.transform.localPosition = Vector3.zero;
//}
}
foreach (var imgTarget in eventArgs.updated)
{
if(imgTarget.trackingState == TrackingState.Tracking)
{
imgTarget.gameObject.SetActive(true);
vecpos = imgTarget.transform.position;
quarot = imgTarget.transform.rotation;
if (isStartBuild)
{
CountDistance();
//AnchorChild.gameObject.transform.parent = AnchorPoint[int.Parse(imgTarget.referenceImage.name) - 1].transform;
//AnchorChild.gameObject.transform.localPosition = Vector3.zero;
//AnchorObj.gameObject.transform.position = vecpos;
//AnchorObj.gameObject.transform.rotation = quarot;
}
else
{
if (!IsBuildSource)
{
CountDistance();
//AnchorChild.gameObject.transform.parent = AnchorPoint[int.Parse(imgTarget.referenceImage.name) - 1].transform;
//AnchorChild.gameObject.transform.localPosition = Vector3.zero;
//AnchorObj.gameObject.transform.position = vecpos;
//AnchorObj.gameObject.transform.rotation = quarot;
}else
{
AnchorObj.transform.position = AnchorPos;
AnchorObj.transform.rotation = AnchorQua;
}
}
}
else if (imgTarget.trackingState == TrackingState.Limited)
{
imgTarget.gameObject.SetActive(false);
}
//vecScl = new Vector3(imgTarget.size.x,0.01f,imgTarget.size.y);
}
}
void CountDistance()
{
for (int i = 0; i < ImgTargetObj.Count; i++)
{
float minDis;
if (ImgTargetObj[i].activeInHierarchy)
{
minDis = Vector3.Distance(CamObj.transform.position, ImgTargetObj[i].gameObject.transform.position);
}
else
{
minDis = 500 + i;
}
if (!TargetDic.ContainsKey(minDis))
{
dis.Add(minDis);
}
TargetDic.Add(dis[i], ImgTargetObj[i].gameObject);
}
dis.Sort();
if (dis.Count != 0)
MinDis = dis[0];
GameObject obj;
TargetDic.TryGetValue(MinDis, out obj);
AnchorObj.transform.gameObject.transform.position = obj.gameObject.transform.position;
AnchorObj.transform.gameObject.transform.rotation = obj.gameObject.transform.rotation;
AnchorChild.transform.parent = AnchorPoint[int.Parse(obj.gameObject.GetComponent<ARTrackedImage>().referenceImage.name) - 1].gameObject.transform;
AnchorChild.transform.localPosition = Vector3.zero;
TargetDic.Clear();
dis.Clear();
}
Vector3 AnchorPos;
Quaternion AnchorQua;
public void AddAnchorsFunc()
{
if(isStartBuild)
{
isStartBuild = false;
//anchorManager.AddAnchor(new Pose(vecpos, quarot));
foreach (var img in imageTrackManager.trackables)
{
img.gameObject.transform.GetChild(0).gameObject.SetActive(false);
img.gameObject.SetActive(false);
}
UITishiObj.SetActive(false);
Tishikuang.SetActive(true);
AnchorPos = AnchorObj.transform.position;
AnchorQua = AnchorObj.transform.rotation;
IsBuildSource = true;
}
else
{
if(IsBuildSource)
{
IsBuildSource = false;
foreach (var img in imageTrackManager.trackables)
{
img.gameObject.SetActive(true);
}
}
else
{
IsBuildSource = true;
AnchorPos = AnchorObj.transform.position;
AnchorQua = AnchorObj.transform.rotation;
foreach (var img in imageTrackManager.trackables)
{
img.gameObject.SetActive(false);
}
}
}
}
void OnAnchorsChanged(ARAnchorsChangedEventArgs eventArgs)
{
foreach (var item in eventArgs.added)
{
//StartCoroutine(ScaleTweensControl());
NightButton.gameObject.GetComponent<Button>().interactable = true;
ScaleControlSlider.interactable = true;
ScaleControlSlider.value = 0;
DayObj = AnchorChild.gameObject.transform.GetChild(0).GetChild(0).GetChild(0).gameObject;
NightObj = AnchorChild.gameObject.transform.GetChild(0).GetChild(0).GetChild(1).gameObject;
//item.gameObject.transform.GetChild(0).GetChild(0).GetChild(2).transform.localScale = vecScl;
}
foreach (var anchorObj in eventArgs.updated)
{
}
}
IEnumerator ScaleTweensControl()
{
bool go = true;
float addnum = 0.005f;
yield return new WaitForEndOfFrame();
while(go)
{
ScaleControlSlider.value += addnum;
yield return new WaitForEndOfFrame();
if(ScaleControlSlider.value >= 0.55f)
{
go = false;
}
addnum += 0.0008f;
}
yield return new WaitForEndOfFrame();
}
public void DayNightChangeControll()
{
isDay = !isDay;
DayButton.SetActive(!isDay);
NightButton.SetActive(isDay);
DayObj.SetActive(isDay);
NightObj.SetActive(!isDay);
}
private void Update()
{
if (!IsBuildSource)
{
AnchorButton.SetActive(true);
TrackButton.SetActive(false);
}
else
{
AnchorButton.SetActive(false);
TrackButton.SetActive(true);
}
text.text = IsBuildSource.ToString();
if (ScaleControlSlider.gameObject.activeInHierarchy && ScaleControlSlider.interactable == true)
{
AnchorChild.gameObject.transform.localScale = new Vector3(ScaleControlSlider.value + 1f, ScaleControlSlider.value + 1f, ScaleControlSlider.value + 1f);
}
}
public void OnClickQuit()
{
Application.Quit();
}
}
网友评论