Assets\MaxstAR\VPS\VPSStudio\Path\NavigationController.cs(5,13): error CS0234: The type or namespace name โEditorCoroutinesโ does not exist in the namespace โUnityโ ๊ด๋ จ ์๋ฌ๊ฐ ๋์ฌ ๋๋ Window->PackageManager->Editor Coroutines์ ๊ฒ์ํ์ฌ ํจํค์ง๋ฅผ ์ค์นํฉ๋๋ค.
- Unity Project Setting์์ Android๋ Graphics API๋ฅผ OpenGLES3 ๋ง ์ง์ํฉ๋๋ค.
- Multithreaded Rendering์ unCheck ๋์ด์ผ ํฉ๋๋ค.
VPSData_(xxx).zip๋ฅผ Project Folder ์ ๋์ผํ ํด๋์ ํ๋๋ค. Unity(Project Name)/../VPSData/VPSSimulationData ์ด๋ฐ์์ ๊ตฌ์กฐ๊ฐ ๋์ด์ผ ํฉ๋๋ค.
- Asset/Scene/Scenes/MaxstScene.unity์ ์ ํํฉ๋๋ค.
- Hierarchy์์ VPSStudio๋ฅผ ์ ํํฉ๋๋ค.
- VPS Map์์ ์๋ฎฌ๋ ์ด์ ์ ํ ๋งต์ ์ ํํฉ๋๋ค.
- VPS Simulation Data์์ ์ฌ์ฉํ๊ณ ์ถ์ ์๋ฎฌ๋ ์ด์ ๋ฐ์ดํฐ๋ฅผ ์ ํํฉ๋๋ค.(๋ค๋ฅธ ๋ฐ์ดํฐ๋ฅผ ์ ํํ์๋ฉด ๋ค๋ฅธ ์๋ฎฌ๋ ์ดํ ๋ ํ๋ฉด์ด ๋ํ๋ฉ๋๋ค.)
- Load VPS Map์ ํด๋ฆญํด์ ํด๋น ๋งต์ ๋ํ ์ ๋ณด๋ฅผ ๋ถ๋ฌ์ต๋๋ค.
- VPS ๋งต์ด ์์ฑ ๋๊ณ ์นด๋ฉ๋ผ๊ฐ ํ์๋ฉ๋๋ค.
-
- Hierarchy์ Trackable ํ์์ ์ฅ์์ ๋ฉ์ฌ ์ปจํ ์ธ ๊ฐ ์กด์ฌํฉ๋๋ค.
- ๊ฐ ์ฅ์์ ๋ง๋ Trackable ํ์์ ์ปจํ ์ธ ๋ฅผ ๋ฐฐ์นํ์ฌ์ผ ์ ๋๋ก ์ธ์์ด ๊ฐ๋ฅ ํฉ๋๋ค.(๊ฐ ์ฅ์์ ์ด๋ฆ์ ๋ฉ์ฌ์ Trackable ์์ฑ์ ์์ต๋๋ค.)
- ๊ฐ๊ฐ์ Trackable ํ์ GameObject์ Position์ ๋ณ๊ฒฝํ์ฌ ์ฌ๋ฐฐ์น ํ๋ฉด ๋ฉ๋๋ค,
- ์ฌ๋ฐฐ์น๋ ์ปจํ ์ธ ๋ฅผ Play๋ฒํผ์ ๋๋ฅด๋ฉด ์๋ฎฌ๋ ์ดํฐ ๋ฐ์ดํฐ๊ฐ ๋ก๋ ๋๋ฉด์ ์ปจํ ์ธ ๊ฐ ์ค์ ํ๋ฉด์์ ์ด๋ป๊ฒ ์ฆ๊ฐ ๋๋์ง ๋ณด์ฌ์ง๊ฒ ๋ฉ๋๋ค.
- ์ธ์ ์์น์ ๋ฐ๋ผ์ ๊ฐ๊ฐ์ Trackable์ด Active๋๊ฒ ๋ฉ๋๋ค.
VPSStudio์์ ํด๋น VPS Map์ ์ ํํ๊ณ Load VPS Map์ ํด๋ฆญํ๋ฉด ๋งต์ ํ์ต ์์ ์ ์นด๋ฉ๋ผ๊ฐ VPSStudioํ์์ ์์ฑ ๋ฉ๋๋ค.
ํ์์ ์์ฑ๋ ์นด๋ฉ๋ผ ๊ทธ๋ฃน์ ์ ํํ๊ฑฐ๋ Game View์์ ์นด๋ฉ๋ผ๋ฅผ ์ ํํ๊ณ ํ์์ ReferenceCamera๋ฅผ ์ ํํ๋ฉด Game View์ ํ์ต ์์ ์ ์ด๋ฏธ์ง์ ํจ๊ป ์ปจํ ์ธ ๊ฐ ์ด๋ป๊ฒ ๋ฐฐ์น ๋๋์ง ํ์ธ ํ ์ ์์ต๋๋ค.
ํด๋น ์์น์ Trackable ํ์์ ์ปจํ ์ธ ๋ฅผ ๋ฐฐ์นํ๊ณ ์์น๋ฅผ ์ด๋ ์ํค๋ฉด์ ์ค์ ๋ฐฐ์น๊ฐ ์ด๋ป๊ฒ ๋ ์ง ํ์ธ ํฉ๋๋ค.
- Occlusion ๊ธฐ๋ฅ์ ์ฌ์ฉํ๊ณ ์ถ์ผ์๋ฉด, Hierarchy์์ SceneManager์ Occlusion Objects์ ์ปจํ ์ธ ๋ฅผ ์ถ๊ฐํ๋ฉด ๋ฉ๋๋ค. Occlusion Objects ์ปจํ ์ธ ๋ ๋ฐํ์ ์์ ์ ๋ชจ๋ ํฌ๋ช ์ฒ๋ฆฌ๊ฐ ๋๋ Material๋ก ๋ณ๊ฒฝ ๋ฉ๋๋ค.
- Occlusion ๊ธฐ๋ฅ ์คํํ๊ณ ์ถ์ง ์์ผ์๋ฉด, SceneManager์ IsOcclusion์ uncheckํ๋ฉด ๋ฉ๋๋ค. ๋ค๋ง Occlusion์ ์ ์ฉํ์ง ์์ผ๋ฉด ํด๋น ์์น์ Mesh๊ฐ ๋ณด์ฌ์ง๊ฒ ๋ฉ๋๋ค.
- ๋ค๋น๊ฒ์ด์ ์ SceneManager GameObject์ ํฌํจ๋์ด ์์ต๋๋ค. ํ์ดํ์ ๊ฑฐ๋ฆฌ, ํ์ดํ๊ฐ ๋ณด์ด๋ ๊ฑฐ๋ฆฌ, ํ์ดํ์ ๊ธฐ๋ณธ ๋์ด, ํ์ดํ์ prefab์ด ์์ฑ์ ๋๋ค. ํ์ดํ prefab์ ๋ณ๊ฒฝ ๊ฐ๋ฅ ํฉ๋๋ค.
- NavigationController์ MakePath ํจ์๋ฅผ ์ฌ์ฉํด์ ๋ค๋น๊ฒ์ด์ ๊ฒฝ๋ก๊ฐ ์์ฑ ๋ฉ๋๋ค.
MakePath(string start_location, Vector3 start_position, string end_location, Vector3 end_position, VPSTrackable[] trackables, string serverName = "")
- start_location : ํ์ฌ Trackable์ ์์น ์ ๋๋ค.
- start_position : ํ์ฌ Trackable์ ์์น์ 3์ฐจ์ ์ขํ ์ ๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ARCamera์ position ์ขํ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
- end_location : ๋ชฉ์ ์ง์ Trackable์ ์์น ์ ๋๋ค. ์ฝ์์ค์์๋ 1์ธต, ์งํ1์ธต, ์งํ 2์ธต, ์ค์ธ๋ก ์ง์ ๋ฉ๋๋ค.
- end_position : ๋ชฉ์ ์ง์ 3์ฐจ์ ์ขํ ์ ๋๋ค. ํด๋น ๋ชฉ์ ์ง์ ์์น์ ์ขํ๊ฐ ๋ง์์ผ ํฉ๋๋ค.
- serverName : ๋ค๋น๊ฒ์ด์ ์ ์ฐพ๊ธฐ์ํ ์๋ฒ๋ฅผ ์ง์ ํด์ผํ ๊ฒฝ์ฐ ์ฌ์ฉํฉ๋๋ค.
- MacOS์์ ์์ ํ์ค๊ฒฝ์ฐ ํ์ฌ Unity์์ Nortarization์ ์ ๊ณตํ์ง ์์ ํ๋ฌ๊ทธ์ธ์ด ์ ๋๋ก ์๋ํ์ง ์์ต๋๋ค. ์๋์ ๋ช ๋ น์ผ๋ก GateKeeper๋ฅผ ํด์ ํ์ ์ผํฉ๋๋ค.
cd Assets/MaxstAR/Plugins
xattr -cr MaxstAR.bundle
sudo spctl โmaster-disable
- Android์์๋ ์นด๋ฉ๋ผ์ ์์น ๊ถํ์ด ํ์ํฉ๋๋ค. AndroidManifest.xml๋ฅผ ์ฐธ๊ณ ํ์๊ธธ ๋ฐ๋๋๋ค. Android OS 8(์ค๋ ์ค) ์ด์์ด๋ฉด ํด๋น ํ๋ก์ ํธ์์ ์๋๋ก์ด๋ ํผ๋ฏธ์ ์ ์ป์ผ์ ์ผํฉ๋๋ค. ํ์ฌ๋ ์๋์ ์ฝ๋๋ก ๊ถํ์ ์ป์ต๋๋ค.
AndroidRuntimePermissions.Permission[] result = AndroidRuntimePermissions.RequestPermissions("android.permission.WRITE_EXTERNAL_STORAGE", "android.permission.CAMERA", "android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_COARSE_LOCATION");
- https๋ฌธ์ ๋ก AndroidManifest.xml์ ์๋ ์ฝ๋๋ฅผ ์ถ๊ฐํ์ ์ผ ํฉ๋๋ค.
android:usesCleartextTraffic=โtrueโ
-
iOS์์๋ ๋ํ ์์น์ ์นด๋ฉ๋ผ ๊ถํ์ ์๊ตฌํฉ๋๋ค.
Info.plist์ Privacy - Location์ ๊ด๋ จ๋ ๊ถํ์ ๋ชจ๋ ์ป์ด์ผํฉ๋๋ค.(Location ๊ถํ์ ์ป์ง ๋ชปํ๋ฉด GPS ์ขํ๋ฅผ ์ป์ง ๋ชปํฉ๋๋ค.)
-
์ธ์์๋ ์ธํฐ๋ท์ด ํ์ํฉ๋๋ค. SDK๊ฐ ๋น๋๋ ํฐ์ ์ธํฐ๋ท์ด ์๋ํ๋์ง ํ์ธํด ์ฃผ์ธ์.
VPS SDK๋ ์นด๋ฉ๋ผ์ TrackerManager์ ์์์ด ์์ด์ผ ์๋์ด ๋ฉ๋๋ค.
if (Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.WindowsEditor)
{
string simulatePath = vPSStudioController.vpsSimulatePath;
if (Directory.Exists(simulatePath))
{
CameraDevice.GetInstance().Start(simulatePath);
MaxstAR.SetScreenOrientation((int)ScreenOrientation.Portrait);
}
}
else
{
if (CameraDevice.GetInstance().IsFusionSupported(CameraDevice.FusionType.ARCamera))
{
CameraDevice.GetInstance().Start();
}
else
{
TrackerManager.GetInstance().RequestARCoreApk();
}
}
TrackerManager.GetInstance().StartTracker();
}
์นด๋ฉ๋ผ๋ฅผ ์์ํ๋ ์ฝ๋๋ ์๋์ ๊ฐ์ต๋๋ค.
CameraDevice.GetInstance().Start();
์๋ฎฌ๋ ์ด์ ์นด๋ฉ๋ผ๋ฅผ ์์ํ๋ ์ฝ๋๋ ์๋์ ๊ฐ์ต๋๋ค. ์๋ฎฌ๋ ์ด์ ์นด๋ฉ๋ผ๋ VPSCollector๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ง๋ค์ด์ง ๋ฐ์ดํฐ์ ์์น๋ฅผ Path๋ก ์ ๋ฌํด ์ฃผ์ด์ผ ํฉ๋๋ค.
CameraDevice.GetInstance().Start(simulatePath);
VPS์ ์์ง์ ์์ํ๋ ์ฝ๋๋ ์๋์ ๊ฐ์ต๋๋ค.
TrackerManager.GetInstance().StartTracker();
VPS์ ๋ํ ๊ฒฐ๊ณผ๋ฌผ์ Update ํจ์์์ ๊ฐฑ์ ์ด ๋ฉ๋๋ค. openGL thread๋ฅผ ์ด์ฉํ๋ ค๋ ๋ชฉ์ ์ด ์์ต๋๋ค.
TrackerManager.GetInstance().UpdateFrame();
UpdateFrame ํจ์๋ฅผ ํตํด์ ์นด๋ฉ๋ผ์ ํฌ์ง์ ๊ณผ VPS์ ๊ด๋ จ๋ ๋ฐ์ดํฐ๋ฅผ ARFrame์ ์ ์ฅํฉ๋๋ค.
ARFrame ํด๋์ค๋ VPS์ ์ธ์์ผ๋ก ์ธํด ์ป์ด์ง ๋ฐ์ดํฐ๋ฅผ ๋ด๊ณ ์์ต๋๋ค.
- GetTrackedImage() ๋ฅผ ํตํด์ ์ด๋ฏธ์ง๋ฅผ ์ป์ด๋ด๊ฒ ๋ฉ๋๋ค.
- GetARLocationRecognitionState() ๋ฅผ ํตํด์ ์ธ์ ์ํ๋ฅผ ์ป์ด๋ ๋๋ค.
- GetARTrackingState() ๋ฅผ ํตํด์ ARCore, ARKit์ ํธ๋ํน ์ํ ์ฌ๋ถ๋ฅผ ์ป์ต๋๋ค.
- GetARTrackingFailureReason() ๋ฅผ ํตํด์ ARCore, ARKit์ด ์๋ ๋์ง ์๋ ์ด์ ๋ฅผ ์ป์ ์ ์์ต๋๋ค.
- GetTransform() ๋ฅผ ํตํด์ ์ธ์์ด ์๋ฃ๋ ์นด๋ฉ๋ผ์ ์์น๋ฅผ ์ป์ ์ ์์ต๋๋ค.
- GetARLocalizerLocation()๋ฅผ ํตํด์ ์๋ฎฌ๋ ์ด์ ์์์ด๋, ์นด๋ฉ๋ผ ์ด๋ฏธ์ง๋ก ์ป์ด์ง ์ธ์ ์์น๋ฅผ ์ ๋ฌํฉ๋๋ค.
if(arFrame.GetARLocationRecognitionState() == ARLocationRecognitionState.ARLocationRecognitionStateNormal)
{
Matrix4x4 targetPose = arFrame.GetTransform();
arCamera.transform.position = MatrixUtils.PositionFromMatrix(targetPose);
arCamera.transform.rotation = MatrixUtils.QuaternionFromMatrix(targetPose);
arCamera.transform.localScale = MatrixUtils.ScaleFromMatrix(targetPose);
string localizerLocation = arFrame.GetARLocalizerLocation();
if (currentLocalizerLocation != localizerLocation)
{
currentLocalizerLocation = localizerLocation;
foreach (VPSTrackable eachTrackable in vPSTrackablesList)
{
bool isLocationInclude = false;
foreach(string eachLocation in eachTrackable.localizerLocation)
{
if(currentLocalizerLocation == eachLocation)
{
isLocationInclude = true;
break;
}
}
eachTrackable.gameObject.SetActive(isLocationInclude);
}
}
}
์์ ์ฝ๋๋ ์ธ์์ด ์๋ฃ๋ ์์ ์ ์นด๋ฉ๋ผ์ position๊ณผ rotation์ ์ ์ฉํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
์ธ์๋ ์์น๋ฅผ ํตํด์ ํด๋น VPSTrackable์ ์ ํํ์ฌ ๊ด๋ จ๋ ์ปจํ ์ธ ๋ฅผ Active์ํ๋ก ๋ณ๊ฒฝ ํฉ๋๋ค.
๋ค๋น๊ฒ์ด์ ๊ด๋ จ๋ ์ฝ๋๋ ์๋์ ๊ฐ์ต๋๋ค.
NavigationController navigationController = vPSStudioController.GetComponent<NavigationController>();
if(currentLocalizerLocation != null)
{
navigationController.MakePath(currentLocalizerLocation, arCamera.transform.position, "indoor_maxst_f2", new Vector3(9.723813f, 0, 10.732927f), vPSTrackablesList.ToArray(),
()=> {
Debug.Log("No Path");
});
}
VPSStudio์์ NavigationController๋ฅผ ์ป์ด๋ด์ ์ฌ์ฉํฉ๋๋ค.
NavigationController๋ ํ์ฌ ์์น๋ฅผ ํ๋จ๋ ์ํ์์ ์ฌ์ฉํ ์ ์์ต๋๋ค. MakePath๋ฅผ ํตํด์ ๊ธธ์ ๋ง๋ค์ด ๋ ๋๋ค. ๊ธธ์ ๋ํ ์ ๋ณด๊ฐ ์์ ๊ฒฝ์ฐ "No Path"๋ผ๋ ๋ก๊ทธ๋ฅผ ์ ๋ฌ ํฉ๋๋ค.
MakePath ํจ์๋ ์๋์ ๊ฐ์ต๋๋ค.
public void MakePath(string start_location, Vector3 start_position, string end_location, Vector3 end_position, VPSTrackable[] trackables, Action fail, string serverName = "")
๋ค๋น๊ฒ์ด์ ์ ์คํ ํ ๋๋ ์์์์น์ ๋๋๋ ์์น ์ด๋ฆ๊ณผ position์ ์ ๋ฌํด์ผ ํฉ๋๋ค.
- Camera์ Clipping Planes Near์ Far๋ฅผ ์กฐ์ ํฉ๋๋ค.
AbstractARManager.cs
void OnPreRender()
{
if (screenWidth != Screen.width || screenHeight != Screen.height)
{
screenWidth = Screen.width;
screenHeight = Screen.height;
MaxstAR.OnSurfaceChanged(screenWidth, screenHeight);
}
if (orientation != Screen.orientation)
{
orientation = Screen.orientation;
if (Application.platform == RuntimePlatform.Android ||
Application.platform == RuntimePlatform.IPhonePlayer)
{
MaxstAR.SetScreenOrientation((int)orientation);
}
}
if (nearClipPlane != arCamera.nearClipPlane || farClipPlane != arCamera.farClipPlane)
{
nearClipPlane = arCamera.nearClipPlane;
farClipPlane = arCamera.farClipPlane;
CameraDevice.GetInstance().SetClippingPlane(arCamera.nearClipPlane, arCamera.farClipPlane);
}
arCamera.projectionMatrix = CameraDevice.GetInstance().GetProjectionMatrix();
}
CameraDevice.GetInstance().SetClippingPlane(arCamera.nearClipPlane, arCamera.farClipPlane);
์ ํตํด์ Near์ Far๋ฅผ ์กฐ์ ํฉ๋๋ค.