Spisu treści:

Portal AR do góry nogami od Stranger Things: 10 kroków (ze zdjęciami)
Portal AR do góry nogami od Stranger Things: 10 kroków (ze zdjęciami)

Wideo: Portal AR do góry nogami od Stranger Things: 10 kroków (ze zdjęciami)

Wideo: Portal AR do góry nogami od Stranger Things: 10 kroków (ze zdjęciami)
Wideo: NOCNE ZDJĘCIA INSPIROWANE STRANGER THINGS | #KONKURS #GIVEAWAY 2024, Listopad
Anonim
Portal AR do góry nogami od dziwniejszych rzeczy
Portal AR do góry nogami od dziwniejszych rzeczy
Portal AR do góry nogami od dziwniejszych rzeczy
Portal AR do góry nogami od dziwniejszych rzeczy

Ten Instructable przejdzie przez tworzenie aplikacji mobilnej rzeczywistości rozszerzonej na iPhone'a z portalem, który prowadzi do góry nogami od Stranger Things. Możesz wejść do portalu, obejść się i wyjść. Wszystko w portalu można zobaczyć tylko przez portal, dopóki nie wejdziesz do środka. Gdy znajdziesz się w środku, wszystko będzie renderowane wszędzie, dopóki nie wrócisz do prawdziwego świata. Wykorzystamy silnik gier wideo Unity 3D z wtyczką Apple ARKit. Całe oprogramowanie, z którego będziemy korzystać, można pobrać i używać za darmo. Nie musisz być ekspertem, aby podążać dalej, przejdziemy przez każdy krok!

Krok 1: Rozpocznij nowy projekt Unity

Rozpocznij nowy projekt Unity
Rozpocznij nowy projekt Unity

Najpierw pobierz Unity3D i upewnij się, że zainstalowałeś pliki kompilacji dla platformy IOS. Będziesz także musiał pobrać Xcode i założyć bezpłatne konto programisty Apple. Twój iPhone będzie również musiał mieć system IOS 11 lub nowszy. Od dzisiaj 5 lutego 2018 r. IOS 11.3 jest dostępny, ale xCode 9.2 nie ma jeszcze plików obsługi dla niego. Jeśli więc korzystasz z najnowszej wersji IOS, pobierz najnowszą wersję beta Xcode ze strony Apple. Developer.com.

Gdy masz już wszystkie potrzebne programy, otwórz Unity i rozpocznij nowy projekt, nazwij go, jak chcesz. Będziemy potrzebować wtyczki Apple ARKit, abyśmy mogli używać kamery naszego telefonu do wykrywania podłoża i umieszczania obiektów na podłodze. Zaimportujmy to teraz, przechodząc do zakładki Asset Store i wyszukaj „ARKit”. Będziesz musiał utworzyć darmowe konto Unity, jeśli jeszcze go nie masz, a następnie kliknij importuj, aby pobrać wtyczkę.

Przejdź do folderu przykładów w folderze ARKit i znajdź „UnityARKitScene”. Kliknij dwukrotnie, aby go otworzyć. Wykorzystamy tę scenę jako punkt wyjścia i stąd będziemy budować. Ta scena domyślnie pozwoli ci wykryć ziemię, a po dotknięciu ekranu kostka zostanie umieszczona w tej pozycji.

Najpierw ustalmy nasze ustawienia budowania, abyśmy nie zapomnieli zrobić tego później. Kliknij plik, zbuduj ustawienia i usuń wszystkie sceny z tej listy. Kliknij dodaj otwarte sceny, aby dodać naszą aktualną. Ostatnią rzeczą, którą musimy tutaj ustawić, jest przejście w ustawieniach odtwarzacza do identyfikatora pakietu, a format tego ciągu to com. NazwaTwojejFirmy. NazwaTwojejAplikacji, więc w moim przypadku robię coś takiego jak com. MatthewHallberg. PortalTest.

Krok 2: Skonfiguruj scenę

Przygotuj scenę
Przygotuj scenę

Najpierw spójrz w lewo i znajdź obiekt gry o nazwie „GeneratePlanes”. Mając to podświetlone, spójrz teraz w prawo i kliknij pole wyboru, aby je wyłączyć. W ten sposób nie mamy brzydkich niebieskich kwadratów generowanych, gdy ARKit wykryje płaszczyznę uziemienia. Następnie usuń obiekt gry „RandomCube”, ponieważ nie chcemy go widzieć w naszej scenie.

Teraz musimy najpierw stworzyć drzwi naszego portalu. Usuń kostkę, która jest elementem podrzędnym „HitCubeParent”. Kliknij prawym przyciskiem myszy i wybierz utwórz pusty obiekt gry. Zmień jego nazwę na „Portal”. Teraz kliknij prawym przyciskiem myszy na ten obiekt i utwórz sześcian, dzięki czemu będzie on dzieckiem portalu. Zmień jego nazwę na "PostLeft", a będzie to lewy post naszego portalu. Przeskaluj go tak, aby x to 1, y to 28, a z to jeden. Zrób to samo dla właściwego posta. Teraz utwórz górny słupek i przeskaluj y do 14. Obróć go na bok i przesuń tak, aby łączył inne słupki. Zrób cały portal w skali 1,3 x 1,4 x 1.

Przejdź do google i wpisz teksturę drewna lub kory. Pobierz jeden z tych obrazów i przeciągnij go do folderu zasobów w Unity. Teraz przeciągnij ten obraz na wszystkie swoje posty na portalu.

Kliknij ponownie obiekt "Portal" i kliknij dodaj komponent po prawej stronie. Dodaj do niego skrypt „UnityARHitTestExample”. Jest tam pusty slot dla "Hit Transform", przeciągnij obiekt "HitCubeParent" do tego slotu.

Krok 3: Zróbmy trochę cząstek

Zróbmy trochę cząstek
Zróbmy trochę cząstek

Teraz użyjemy systemu Unity Particle do stworzenia efektu dymu i unoszących się cząsteczek wewnątrz naszego portalu. Przejdź do zasobów na górnym pasku menu, standardowych zasobów i importu systemów cząstek.

Utwórz dwa puste obiekty w swoim portalu i nazwij jeden „SmokeParticles”, a drugi „FloatingParticles”.

Dodaj składnik systemu cząstek do cząstek dymu.

Ten komponent ma wiele opcji, ale musimy zmienić tylko kilka.

Zmień kolor początkowy na ciemnoniebieski z około 50% przezroczystością. Ustaw wskaźnik emisji 100. Wewnątrz kształtu ustaw promień.01. W dolnej części renderera zmień minimalny rozmiar na.8, a maksymalny rozmiar na 5. W komponencie materialnym po prostu wybierz materiał dymny z listy, ale zmienimy to później.

Dodaj teraz system cząstek do pływającego obiektu gry i ustaw emisję na 500. Ustaw początkowy czas życia na 2, promień na 10, minimalny rozmiar cząstek na 0,01 i maksymalny rozmiar cząstek na 0,015. Na razie ustaw materiał na domyślną cząsteczkę.

Na koniec weź oba obiekty w grze i obróć je o 90 stopni na osi x i podnieś je w powietrze, aby emitowały w dół do drzwi portalu.

Krok 4: Spowolnienie cząstek

Spowolnienie cząstek
Spowolnienie cząstek

Ponieważ chcemy, aby te cząstki pokryły duży obszar, ale także poruszały się powoli, musimy stworzyć własną funkcję próbkowania. Kliknij prawym przyciskiem myszy w folderze zasobów i utwórz nowy skrypt C# i nazwij go „ParticleSample”. Skopiuj i wklej w tym kodzie:

za pomocą System. Collections;

za pomocą System. Collections. Generic; za pomocą UnityEngine; public class ParticleSample: MonoBehaviour { private ParticleSystem ps; // Użyj tego do inicjalizacji void Start () { ps = GetComponent (); StartCoroutine (Procedura Cząstek ()); } IEnumerator SampleParticleRoutine(){ var main = ps.main; główna.symulacjaPrędkość = 1000f; ps. Graj (); wydajność zwraca nowe WaitForSeconds (.1f); główna.symulacjaPrędkość = 0,05f; } }

Teraz przeciągnij ten skrypt na każdy z obiektów gry systemu cząstek.

Krok 5: Tworzenie portalu

Tworzenie portalu!
Tworzenie portalu!

Teraz musimy stworzyć portal, więc kliknij prawym przyciskiem myszy obiekt gry portalu i utwórz quad. Przeskaluj quad tak, aby obejmował cały portal, to stanie się naszym oknem portalu. Pierwszą rzeczą, którą musimy dodać, jest shader portalu, który wyrenderuje tylko obiekty z innym konkretnym shaderem. Kliknij prawym przyciskiem myszy w folderze zasobów i utwórz nowy niepodświetlony shader. Usuń wszystko i wklej ten kod:

Shader „Portal/Okno portalu”

{ SubShader { Zwrite off Colormask 0 anulowanie szablonu{ Ref 1 Pass zastąpić } Pass { } } }

Kliknij prawym przyciskiem myszy w hierarchii i utwórz nowy materiał, nazwij go PortalWindowMat, w menu rozwijanym tego materiału znajdź sekcję portalu i wybierz okno portalu. Przeciągnij ten materiał na swój quad portalu.

Krok 6: Shadery cząstek

Shadery cząstek
Shadery cząstek

Ponownie kliknij prawym przyciskiem myszy folder zasobów i utwórz nowy moduł cieniujący. Musimy stworzyć shadery dla cząstek, które wejdą do portalu. Zastąp cały kod następującym:

Shader „Portal/cząsteczki” {

Właściwości { _TintColor („Kolor odcienia”, Kolor) = (0,5, 0,5, 0,5, 0,5) _MainTex („Tekstura cząstek”, 2D) = „biały” {} _InvFade („Współczynnik miękkich cząstek”, Zakres (0,01, 3,0)) = 1.0 _Stencil("stencil", int) = 6 } Kategoria { Tagi { "Kolejka"="Przezroczysty" "IgnoreProjector"="True" "RenderType"="Przezroczysty" "PreviewType"="Płaszczyzna" } Mieszaj SrcAlpha OneMinusSrcAlpha ColorMask RGB Cull Off Lighting Off ZWrite Off SubShader { Stencil{ Ref 1 Comp[_Stencil] } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 2.0 #pragma multi_compile_particles #pragma multi_compile_fog #include "UnityCG.cginc" sampleMainTex2D; naprawiono4 _TintKolor; struct appdata_t { float4 wierzchołek: POZYCJA; stały4 kolor: KOLOR; float2 texcoord: TEXCOORD0; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 wierzchołek: SV_POSITION; stały4 kolor: KOLOR; float2 texcoord: TEXCOORD0; UNITY_FOG_COORDS(1) #ifdef SOFTPARTICLES_ON float4 projPos: TEXCOORD2; #endif UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; v2f vert (appdata_t v) { v2f o; UNITY_SETUP_INSTANCE_ID(v); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); o.wierzchołek = UnityObjectToClipPos(v.wierzchołek); #ifdef SOFTPARTICLES_ON o.projPos = ComputeScreenPos (o.vertex); COMPUTE_EYEDEPTH(o.projPos.z); #endif o.color = v.color * _TintColor; o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); UNITY_TRANSFER_FOG(o, o.wierzchołek); powrót o; } UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture); float _InvFade; fixed4 frag (v2f i): SV_Target { #ifdef SOFTPARTICLES_ON float sceneZ = LinearEyeDepth (SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos))); część zmiennoprzecinkowa Z = i.projPos.z; float fade = nasycenie (_InvFade * (sceneZ-partZ)); i.kolor.a *= zanika; #endif fixed4 col = 2.0f * i.color * tex2D(_MainTex, i.texcoord); UNITY_APPLY_FOG(i.fogCoord, col); powrót kol; } ENDCG } } } }

Utwórz dwa nowe materiały, jeden o nazwie portalSmoke, a drugi o nazwie portalParticles.

Dla każdego wybierz ten shader, z listy rozwijanej, w portalach, cząsteczkach. Dla cząstek dymu wybierz teksturę dymu, a dla cząstek wybierz teksturę cząstek. Zmień kolor dymu na ciemniejszy niebieski z około 50% przezroczystością. Przejdź do komponentu renderującego każdego systemu cząsteczek w swoim portalu i wybierz odpowiednie materiały, które właśnie stworzyliśmy.

Krok 7: Utwórz Skybox

Stwórz Skybox
Stwórz Skybox

Teraz, aby naprawdę stworzyć wygląd do góry nogami, musimy zabarwić wszystko na ciemnoniebieski. W tym celu użyjemy przezroczystego skyboxa, więc utwórz nowy shader i wklej ten kod:

Shader „Portal/portalSkybox” {

Właściwości { _Tint ("Kolor Odcień", Kolor) = (.5,.5,.5,.5) [Gamma] _Ekspozycja ("Ekspozycja", Zakres(0, 8))) = 1.0 _Obrót ("Obrót", Zakres (0, 360)) = 0 [NoScaleOffset] _Tex ("Cubemap (HDR)", Cube) = "szary" {} _Stencil("StencilNum", int) = 6 } SubShader { Tagi { "Kolejka"="Tło" "RenderType"="Tło" "PreviewType"="Skybox" } Odrzuć ZWrite Wyłącz Mieszaj SrcAlpha OneMinusSrcAlpha Stencil{ Ref 1 Comp[_Stencil] } Przekaż { CGPROGRAM #pragma vertex vert #frag fragment pragma #pragma target 2.0 #include "UnityCG.cginc" samplerCUBE _Tex; połowa4 _Tex_HDR; pół4 _Odcień; połowa _Ekspozycja; float _Obrót; float3 RotateAroundYInDegrees (wierzchołek float3, stopnie zmiennoprzecinkowe) { float alfa = stopnie * UNITY_PI / 180.0; pływać sina, cosa; sincos(alfa, sina, cosa); float2x2 m = float2x2(cosa, -sina, sina, cosa); return float3(mul(m, wierzchołek.xz), wierzchołek.y).xzy; } struct appdata_t { float4 wierzchołek: POZYCJA; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex: SV_POSITION; float3 texcoord: TEXCOORD0; UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) { v2f o; UNITY_SETUP_INSTANCE_ID(v); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); float3 obrócony = RotateAroundYInDegrees(v.vertex, _Rotation); o.vertex = UnityObjectToClipPos(obrócony); o.texcoord = v.wierzchołek.xyz; powrót o; } fixed4 frag (v2f i): SV_Target { half4 tex = texCUBE (_Tex, i.texcoord); half3 c = DecodeHDR (tex, _Tex_HDR); c = c * _Odcień.rgb * unity_ColorSpaceDouble.rgb; c *= _Ekspozycja; zwróć połowę4(c,.5); } ENDCG } } Wyłączenie awaryjne }

Teraz utwórz nowy materiał skybox, nazwij go „PortalSkybox” i wybierz ten moduł cieniujący portalSkybox z menu portalu. Przejdź do Window, Lighting na górze i wybierz ten skybox, który właśnie stworzyliśmy. Podejdź do głównej kamery i ustaw jasne flagi na skybox. Skoro już tu jesteśmy, dodajmy kilka komponentów do naszego aparatu, abyśmy mogli wykryć kolizje. Dodaj do kamery komponent ciała sztywnego i usuń zaznaczenie opcji Użyj grawitacji. Dodaj zderzacz pudełek i sprawdź, czy jest wyzwalacz. Ustaw rozmiar zderzaczy pudełek.5 x 1 x 4. Ustaw płaszczyznę przycinania w aparacie na.01.

Krok 8: Logika portalu

Logika portalu
Logika portalu

Ostatnią rzeczą, którą musimy zrobić, to stworzyć logikę kontrolującą nasz portal. Utwórz nowy skrypt C# i nazwij go PortalController.

za pomocą System. Collections;

za pomocą System. Collections. Generic; za pomocą UnityEngine; przestrzeń nazw UnityEngine. XR.iOS{ public class PortalController: MonoBehaviour { public Material materials; public MeshRenderer meshRenderer; publiczne UnityARVideo UnityARVideo; private bool isInside = false; private bool isOutside = true; // Użyj tego do inicjalizacji void Start () { OutsidePortal (); } void OnTriggerStay(Collider col){ Vector3 playerPos = Camera.main.transform.position + Camera.main.transform.forward * (Camera.main.nearClipPlane * 4); if (transform. InverseTransformPoint(playerPos).z <= 0){ if (isOutside) { isOutside = false; isInside = prawda; WewnątrzPortalu (); } } else { if (isInside) { isInside = false; isOutside = prawda; Portal zewnętrzny (); } } } void OutsidePortal(){ StartCoroutine (DelayChangeMat (3)); } void InsidePortal(){ StartCoroutine (DelayChangeMat (6)); } IEnumerator DelayChangeMat(int stencilNum){ UnityARVideo.shouldRender = false; plon zwraca nowy WaitForEndOfFrame (); meshRenderer.enabled = fałsz; foreach (Material mat w materiałach) { mat. SetInt ("_Stencil", stencilNum); } plon zwracać new WaitForEndOfFrame (); meshRenderer.enabled = prawda; UnityARVideo.shouldRender = prawda; } } }

Przeciągnij ten nowy skrypt do okna portalu. Spowoduje to przejście nas do i z portalu za każdym razem, gdy zderzacz w naszej kamerze zderzy się z oknem portalu. Teraz w funkcji zmieniającej wszystkie materiały mówimy wtyczce ARkit, aby nie renderowała klatki, więc przejdź do głównej kamery i otwórz skrypt UnityARVideo. Utwórz public bool shouldRender na górze i ustaw go na wartość true. Down w funkcji OnPreRender() zapakuj wszystko w instrukcję if, w której wszystko wewnątrz będzie działać tylko wtedy, gdy shouldRender ma wartość true. Cały skrypt powinien wyglądać tak:

korzystanie z Systemu;

za pomocą System. Runtime. InteropServices; za pomocą UnityEngine; za pomocą UnityEngine. Rendering; przestrzeń nazw UnityEngine. XR.iOS { public class UnityARVideo: MonoBehaviour { public Material m_ClearMaterial; [HideInInspector] public bool shouldRender = true; prywatny bufor poleceń m_VideoCommandBuffer; prywatne Texture2D _videoTextureY; prywatne Texture2D _videoTextureCbCr; prywatne Matrix4x4 _displayTransform; private bool bCommandBufferInitialized; public void Start() { UnityARSessionNativeInterface. ARFrameUpdatedEvent += UpdateFrame; bCommandBufferInitialized = false; } void UpdateFrame(UnityARCamera cam) { _displayTransform = new Matrix4x4(); _displayTransform. SetColumn(0, cam.displayTransform.column0); _displayTransform. SetColumn(1, cam.displayTransform.column1); _displayTransform. SetColumn(2, cam.displayTransform.column2); _displayTransform. SetColumn(3, cam.displayTransform.column3); } void InitializeCommandBuffer() { m_VideoCommandBuffer = new CommandBuffer(); m_VideoCommandBuffer. Blit(null, BuiltinRenderTextureType. CurrentActive,m_ClearMaterial); GetComponent(). AddCommandBuffer(CameraEvent. BeforeForwardOpaque, m_VideoCommandBuffer); bCommandBufferInitialized = prawda; } void OnDestroy() { GetComponent(). RemoveCommandBuffer(CameraEvent. BeforeForwardOpaque, m_VideoCommandBuffer); UnityARSessionNativeInterface. ARFrameUpdatedEvent -= UpdateFrame; bCommandBufferInitialized = false; } #if !UNITY_EDITOR public void OnPreRender() { if (shouldRender){ Uchwyty ARTextureHandles = UnityARSessionNativeInterface. GetARSessionNativeInterface (). GetARVideoTextureHandles(); if (handles.textureY == System. IntPtr. Zero || handles.textureCbCr == System. IntPtr. Zero) { return; } if (!bCommandBufferInitialized) { InitializeCommandBuffer (); } Rozdzielczość currentResolution = Screen.currentResolution; // Tekstura Y if (_videoTextureY == null) { _videoTextureY = Texture2D. CreateExternalTexture(currentResolution.width, currentResolution.height, TextureFormat. R8, false, false, (System. IntPtr)handles.textureY); _videoTextureY.filterMode = Tryb filtru. Bilinear; _videoTextureY.wrapMode = Tryb teksturowania. Powtórz; m_ClearMaterial. SetTexture("_textureY", _videoTextureY); } // Tekstura CbCr if (_videoTextureCbCr == null) { _videoTextureCbCr = Texture2D. CreateExternalTexture(currentResolution.width, currentResolution.height, TextureFormat. RG16, false, false, (System. IntPtr)handles.textureCbCr); _videoTextureCbCr.filterMode = FilterMode. Bilinear; _videoTextureCbCr.wrapMode = Tryb teksturowania. Powtórz; m_ClearMaterial. SetTexture("_textureCbCr", _videoTextureCbCr); } _videoTextureY. UpdateExternalTexture(handles.textureY); _videoTextureCbCr. UpdateExternalTexture(uchwyty.textureCbCr); m_ClearMaterial. SetMatrix("_DisplayTransform", _displayTransform); } } #else public void SetYTexure(Texture2D YTex) { _videoTextureY = YTex; } public void SetUVTexure(Texture2D UVTex) { _videoTextureCbCr = UVTex; } public void OnPreRender() { if (!bCommandBufferInitialized) { InitializeCommandBuffer (); } m_ClearMaterial. SetTexture("_textureY", _videoTextureY); m_ClearMaterial. SetTexture("_textureCbCr", _videoTextureCbCr); m_ClearMaterial. SetMatrix("_DisplayTransform", _displayTransform); } #endif } }

Krok 9: Prawie gotowe

Prawie skończone!
Prawie skończone!

Wreszcie, gdy klikniemy w ekran i umieścimy portal, chcemy, aby zawsze był zwrócony do nas. Aby to zrobić, przejdź do skryptu „UnityARHitTestExample” w portalu. Zastąp wszystko w środku tym:

korzystanie z Systemu;

za pomocą System. Collections. Generic; przestrzeń nazw UnityEngine. XR.iOS { public class UnityARHitTestPrzykład: MonoBehaviour { public Transform m_HitTransform; public float maxRayDistance = 30.0f; public LayerMaskcollisionLayer = 1 < 0) { foreach (var hitResult w hitResults) { Debug. Log ("Got hit!"); m_HitTransform.position = UnityARMatrixOps. GetPosition (hitResult.worldTransform); m_HitTransform.rotation = UnityARMatrixOps. GetRotation (hitResult.worldTransform); Debug. Log (string. Format ("x:{0:0.######} y:{1:0.######} z:{2:0.###### }", m_HitTransform.position.x, m_HitTransform.position.y, m_HitTransform.position.z)); Vector3 currAngle = transform.eulerAngles; transform. LookAt (Kamera.main.transform); transform.eulerAngles = new Vector3 (currAngle.x, transform.eulerAngles.y, currAngle.z); zwróć prawdę; } } return false; } // Aktualizacja jest wywoływana raz na klatkę void Update() { #if UNITY_EDITOR //będziemy używać tego skryptu tylko po stronie edytora, chociaż nic nie uniemożliwiłoby jego pracy na urządzeniu if (Input. GetMouseButtonDown (0)) { Promień promienia = Camera.main. ScreenPointToRay (Input.mousePosition); Trafienie RaycastHit; //spróbujemy trafić w jeden z obiektów gry zderzających samoloty, które zostały wygenerowane przez wtyczkę //skutecznie podobne do wywołania HitTest za pomocą ARHitTestResultType. ARHitTestResultTypeExistingPlaneUsingExtent if (Physics. Raycast (promień, trafienie wychodzące, maxRayDistance, kolizja/warstwa)) { / pozycję uzyskamy z punktu kontaktowego m_HitTransform.position = hit.point; Debug. Log (string. Format ("x:{0:0.######} y:{1:0.######} z:{2:0.###### }", m_HitTransform.position.x, m_HitTransform.position.y, m_HitTransform.position.z)); //i obrót z transformacji zderzacza płaskiego m_HitTransform.rotation = hit.transform.rotation; } } #else if (Input.touchCount > 0 && m_HitTransform != null) { var touch = Input. GetTouch(0); if (touch.phase == TouchPhase. Began || touch.phase == TouchPhase. Moved) { var screenPosition = Camera.main. ScreenToViewportPoint(touch.position); ARPoint point = new ARPoint { x = screenPosition.x, y = screenPosition.y }; // Prioritize rodzaje reults ARHitTestResultType = {ARHitTestResultType. ARHitTestResultTypeExistingPlaneUsingExtent resultTypes, // jeśli chcesz używać nieskończone samoloty użyj: //ARHitTestResultType. ARHitTestResultTypeExistingPlane, ARHitTestResultType. ARHitTestResultTypeHorizontalPlane, ARHitTestResultType. ARHitTestResultTypeFeaturePoint}; foreach (ARHitTestResultType resultType w typach wyników) { if (HitTestWithResultType (punkt, typ wyniku)) { return; } } } } #endif } } }

Krok 10: Umieść aplikację na swoim telefonie

Umieść aplikację na swoim telefonie!
Umieść aplikację na swoim telefonie!

Wreszcie skończyliśmy. Przejdź do pliku, ustawienia kompilacji i kliknij kompiluj. Otwórz Xcode i wybierz folder, który został utworzony z kompilacji. Wybierz swój zespół programistów i umieść aplikację na swoim telefonie! Możesz zmienić kolory cząsteczek i skyboxa, aby dopasować je do swoich potrzeb. Dajcie znać w komentarzach, jeśli macie jakieś pytania i dziękujemy za obejrzenie!

Zalecana: