สารบัญ:
- ขั้นตอนที่ 1: เริ่มโครงการ Unity ใหม่
- ขั้นตอนที่ 2: ตั้งค่าฉาก
- ขั้นตอนที่ 3: มาสร้างอนุภาคกันเถอะ
- ขั้นตอนที่ 4: ทำให้อนุภาคช้าลง
- ขั้นตอนที่ 5: สร้างพอร์ทัล
- ขั้นตอนที่ 6: อนุภาค Shaders
- ขั้นตอนที่ 7: สร้าง Skybox
- ขั้นตอนที่ 8: พอร์ทัลลอจิก
- ขั้นตอนที่ 9: เกือบเสร็จแล้ว
- ขั้นตอนที่ 10: ใส่แอพในโทรศัพท์ของคุณ
วีดีโอ: AR Portal กลับหัวกลับหางจาก Stranger Things: 10 ขั้นตอน (พร้อมรูปภาพ)
2025 ผู้เขียน: John Day | [email protected]. แก้ไขล่าสุด: 2025-01-13 06:58
คำแนะนำนี้จะผ่านการสร้างแอพมือถือเสมือนจริงสำหรับ iPhone ด้วยพอร์ทัลที่นำไปสู่การกลับหัวจาก Stranger Things คุณสามารถเข้าไปในพอร์ทัล เดินไปรอบๆ และกลับออกมาได้ ทุกอย่างภายในพอร์ทัลสามารถมองเห็นได้ผ่านพอร์ทัลเท่านั้น จนกว่าคุณจะเดินเข้าไปข้างใน เมื่อเข้าไปข้างในแล้ว ทุกอย่างจะปรากฎทุกที่ จนกว่าคุณจะเดินกลับเข้าไปในโลกแห่งความจริง เราจะใช้เอ็นจิ้นวิดีโอเกม Unity 3D กับปลั๊กอิน Apple ARKit ซอฟต์แวร์ทั้งหมดที่เราจะใช้สามารถดาวน์โหลดและใช้งานได้ฟรี คุณไม่จำเป็นต้องเป็นผู้เชี่ยวชาญในการติดตาม เราจะทำทุกขั้นตอน!
ขั้นตอนที่ 1: เริ่มโครงการ Unity ใหม่
ก่อนอื่น ดาวน์โหลด Unity3D และตรวจสอบให้แน่ใจว่าได้ติดตั้งไฟล์บิลด์สำหรับแพลตฟอร์ม IOS คุณจะต้องดาวน์โหลด Xcode และลงทะเบียนสำหรับบัญชีนักพัฒนาแอปเปิ้ลฟรี iPhone ของคุณจะต้องใช้งาน IOS 11 ขึ้นไปด้วย ณ วันนี้ 5 กุมภาพันธ์ 2018 IOS 11.3 ออกมาแล้ว แต่ xCode 9.2 ยังไม่มีไฟล์รองรับ ดังนั้นหากคุณใช้ IOS เวอร์ชันล่าสุด อย่าลืมดาวน์โหลด Xcode เวอร์ชันเบต้าล่าสุดจาก Apple. Developer.com
เมื่อคุณมีโปรแกรมที่จำเป็นทั้งหมดแล้ว ให้เปิด Unity แล้วเริ่มโครงการใหม่ เรียกมันว่าอะไรก็ได้ที่คุณต้องการ เราต้องการปลั๊กอิน Apple ARKit เพื่อที่เราจะสามารถใช้กล้องของโทรศัพท์เพื่อตรวจจับวัตถุที่วางบนพื้นได้ มานำเข้ากันตอนนี้โดยไปที่แท็บ Asset Store และค้นหา "ARKit" คุณจะต้องสร้างบัญชี Unity ฟรี หากคุณยังไม่มีบัญชี จากนั้นคลิกนำเข้าเพื่อรับปลั๊กอิน
ไปที่โฟลเดอร์ตัวอย่างในโฟลเดอร์ ARKit และค้นหา "UnityARKitScene" ดับเบิลคลิกเพื่อเปิด เราจะใช้ฉากนี้เป็นจุดเริ่มต้นและสร้างจากที่นี่ ฉากนี้โดยค่าเริ่มต้นจะให้คุณตรวจจับพื้นได้ และเมื่อคุณแตะหน้าจอ ลูกบาศก์จะถูกวางในตำแหน่งนั้น
อันดับแรก ให้ตั้งค่าการสร้างของเราให้กว้างขึ้นก่อน เราจะได้ไม่ลืมที่จะทำในภายหลัง คลิกไฟล์ สร้างการตั้งค่า และลบฉากทั้งหมดออกจากรายการนั้น คลิกเพิ่มฉากที่เปิดอยู่เพื่อเพิ่มฉากปัจจุบันของเรา สิ่งสุดท้ายที่เราต้องตั้งค่าที่นี่คือในการตั้งค่าผู้เล่นลงไปที่ตัวระบุกลุ่มและรูปแบบของสตริงนี้คือ com. YourCompanyName. YourAppName ดังนั้นในกรณีของฉัน ฉันจึงทำบางอย่างเช่น com. MatthewHallberg. PortalTest
ขั้นตอนที่ 2: ตั้งค่าฉาก
ก่อนอื่น ให้มองไปทางซ้ายและค้นหาวัตถุเกมที่เรียกว่า "GeneratePlanes" ด้วยการไฮไลต์นั้น ให้มองไปทางขวาแล้วคลิกช่องทำเครื่องหมายเพื่อปิดใช้งาน วิธีนี้จะทำให้เราไม่สร้างสี่เหลี่ยมสีน้ำเงินน่าเกลียดเมื่อ ARKit ตรวจพบระนาบพื้น ถัดไปลบวัตถุเกม "RandomCube" เพราะเราไม่ต้องการเห็นสิ่งนั้นในฉากของเรา
ตอนนี้เราต้องสร้างประตูพอร์ทัลของเราก่อน ลบคิวบ์ที่เป็นลูกของ "HitCubeParent" คลิกขวาและเลือกสร้างวัตถุเกมว่าง เปลี่ยนชื่อเป็น "พอร์ทัล" ตอนนี้คลิกขวาที่วัตถุนั้นและสร้างคิวบ์ซึ่งจะทำให้เป็นลูกของพอร์ทัล เปลี่ยนชื่อเป็น "PostLeft" และนี่จะเป็นโพสต์ด้านซ้ายของพอร์ทัลของเรา ปรับขนาดเพื่อให้ x เป็น 1, y เป็น 28 และ z เป็นหนึ่ง ทำสิ่งเดียวกันสำหรับโพสต์ที่ถูกต้อง ตอนนี้สร้างโพสต์บนสุดแล้วปรับขนาด y เป็น 14 พลิกสิ่งนี้ไปด้านข้างแล้วย้ายเพื่อให้เชื่อมโยงโพสต์อื่นๆ ทำให้พอร์ทัลมาตราส่วนทั้งหมด 1.3 x 1.4 x 1
เข้า google แล้วพิมพ์เนื้อไม้หรือเปลือกไม้ ดาวน์โหลดหนึ่งในรูปภาพเหล่านั้นแล้วลากไปไว้ในโฟลเดอร์แอสเซทของคุณใน Unity ตอนนี้ลากรูปภาพนั้นไปยังโพสต์พอร์ทัลทั้งหมดของคุณ
คลิกที่วัตถุ "พอร์ทัล" อีกครั้งและคลิกเพิ่มองค์ประกอบทางด้านขวา เพิ่มสคริปต์ "UnityARHitTestExample" ลงไป มีช่องว่างสำหรับ "Hit Transform" ให้ลากวัตถุ "HitCubeParent" ลงในช่องนั้น
ขั้นตอนที่ 3: มาสร้างอนุภาคกันเถอะ
ตอนนี้เราจะใช้ระบบ Unity Particle เพื่อสร้างเอฟเฟกต์ควันและอนุภาคลอยในพอร์ทัลของเรา ไปที่ สินทรัพย์ ที่แถบเมนูด้านบน สินทรัพย์มาตรฐาน และนำเข้าระบบอนุภาค
สร้างอ็อบเจ็กต์เกมว่างสองอันภายในพอร์ทัลของคุณและเรียก "SmokeParticles" หนึ่งอันและอีกอันหนึ่ง "FloatingParticles"
เพิ่มส่วนประกอบของระบบอนุภาคให้กับอนุภาคควัน
องค์ประกอบนี้มีตัวเลือกมากมาย แต่เราจำเป็นต้องเปลี่ยนเพียงสองสามอย่าง
เปลี่ยนสีเริ่มต้นเป็นสีน้ำเงินเข้มที่มีความโปร่งใสประมาณ 50% ทำอัตราการปล่อย 100. รูปทรงภายใน ทำรัศมี.01. ในส่วนการเรนเดอร์ที่ด้านล่างเปลี่ยนขนาดต่ำสุดเป็น.8 และขนาดสูงสุดเป็น 5 ในส่วนประกอบวัสดุ เพียงแค่เลือกวัสดุควันจากรายการ แต่เรากำลังจะเปลี่ยนแปลงสิ่งนี้ในภายหลัง
เพิ่มระบบอนุภาคให้กับวัตถุเกมอนุภาคลอยตอนนี้และตั้งค่าการปล่อยเป็น 500 ตั้งค่าอายุการใช้งานเริ่มต้นเป็น 2, รัศมีเป็น 10, ขนาดอนุภาคต่ำสุดเป็น.01 และขนาดอนุภาคสูงสุดเป็น.015 ตั้งค่าวัสดุเป็นอนุภาคเริ่มต้นสำหรับตอนนี้
ในที่สุด นำวัตถุทั้งสองเกมมาหมุน 90 องศาบน x แล้วยกมันขึ้นไปในอากาศเพื่อให้พวกมันปล่อยลงสู่ประตูพอร์ทัล
ขั้นตอนที่ 4: ทำให้อนุภาคช้าลง
เนื่องจากเราต้องการให้อนุภาคเหล่านี้ครอบคลุมพื้นที่ขนาดใหญ่ แต่ยังเคลื่อนที่ได้ช้า เราจึงต้องสร้างฟังก์ชันตัวอย่างของเราเอง คลิกขวาในโฟลเดอร์ asset และสร้างสคริปต์ C# ใหม่และเรียกมันว่า "ParticleSample" คัดลอกและวางในรหัสนี้:
ใช้ System. Collections;
ใช้ System. Collections. Generic; ใช้ UnityEngine; ParticleSample คลาสสาธารณะ: MonoBehaviour { ParticleSystem ส่วนตัว ps; // ใช้สำหรับการเริ่มต้นเป็นโมฆะ Start () { ps = GetComponent (); StartCoroutine (SampleParticleRoutine ()); } IEnumerator SampleParticleRoutine(){ var main = ps.main; main.simulationSpeed = 1000f; ps. Play (); ผลตอบแทนผลตอบแทน WaitForSeconds ใหม่ (.1f); main.simulationSpeed =.05f; } }
ตอนนี้ลากสคริปต์นี้ไปยังแต่ละอ็อบเจ็กต์เกมระบบอนุภาคของคุณ
ขั้นตอนที่ 5: สร้างพอร์ทัล
ตอนนี้เราต้องสร้างพอร์ทัล คลิกขวาที่วัตถุเกมพอร์ทัลและสร้างรูปสี่เหลี่ยม ปรับขนาดรูปสี่เหลี่ยมเพื่อให้ครอบคลุมพอร์ทัลทั้งหมด นี่จะกลายเป็นหน้าต่างพอร์ทัลของเรา สิ่งแรกที่เราต้องเพิ่มเข้าไปคือพอร์ทัล shader ซึ่งจะแสดงเฉพาะอ็อบเจ็กต์ที่มี shader เฉพาะอื่นเท่านั้น คลิกขวาในโฟลเดอร์ asset และสร้าง shader ที่ไม่มีแสงใหม่ ลบทุกอย่างในนั้นแล้ววางในรหัสนี้:
Shader "พอร์ทัล/พอร์ทัลหน้าต่าง"
{ SubShader { Zwrite ปิด Colormask 0 ตัดลายฉลุ { Ref 1 Pass แทนที่ } ผ่าน { } } }
คลิกขวาในลำดับชั้นและสร้างวัสดุใหม่ เรียกว่า PortalWindowMat ในเมนูแบบเลื่อนลงสำหรับเนื้อหานี้ ให้ค้นหาส่วนพอร์ทัล และเลือกหน้าต่างพอร์ทัล ลากเนื้อหานี้ไปยังรูปสี่เหลี่ยมพอร์ทัลของคุณ
ขั้นตอนที่ 6: อนุภาค Shaders
คลิกขวาในโฟลเดอร์ asset อีกครั้งและสร้าง shader ใหม่ เราจำเป็นต้องสร้างเฉดสีสำหรับอนุภาคที่เข้าไปในพอร์ทัล แทนที่รหัสทั้งหมดด้วยสิ่งนี้:
Shader "พอร์ทัล/อนุภาค" {
คุณสมบัติ { _TintColor ("Tint Color", Color) = (0.5, 0.5, 0.5, 0.5) _MainTex ("Particle Texture", 2D) = "white" {} _InvFade ("Soft Particles Factor", ช่วง (0.01, 3.0)) = 1.0 _Stencil("stencil", int) = 6 } หมวดหมู่ { แท็ก { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" } Blend SrcAlpha OneMinusSrcAlpha ColorMask RGB Cull ปิดไฟ ปิด ZWrite ปิด SubShader { ลายฉลุ { Ref 1 Comp [_Stencil] } ผ่าน { CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 2.0 #pragma multi_compile_particles #pragma multi_compile_fog #include "UnityCG.cginc_MainTex"inTex คงที่4 _TintColor; โครงสร้าง appdata_t { จุดยอด float4: ตำแหน่ง; fixed4 สี: COLOR; float2 texcoord: TEXCOORD0; UNITY_VERTEX_INPUT_INSTANCE_ID }; โครงสร้าง v2f { จุดยอด float4: SV_POSITION; fixed4 สี: COLOR; 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.vertex = UnityObjectToClipPos (v.vertex); #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.จุดยอด); กลับ o; } UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture); ลอย _InvFade; fixed4 Frag (v2f i): SV_Target { #ifdef SOFTPARTICLES_ON float sceneZ = LinearEyeDepth (SAMPLE_DEPTH_TEXTURE_PROJ (_CameraDepthTexture, UNITY_PROJ_COORD (i.projPos))); float partZ = i.projPos.z; float fade = อิ่มตัว (_InvFade * (sceneZ-partZ)); i.color.a *= จาง; #endif fixed4 col = 2.0f * i.color * tex2D(_MainTex, i.texcoord); UNITY_APPLY_FOG(i.fogCoord, col); กลับ col; } ENDCG } } } }
สร้างวัสดุใหม่สองแบบ อันหนึ่งเรียกว่า portalSmoke และอีกอันเรียกว่า portalParticles
สำหรับแต่ละอันให้เลือก shader นี้จากเมนูดร็อปดาวน์ ในพอร์ทัล อนุภาค สำหรับอนุภาคควันให้เลือกพื้นผิวของควันและสำหรับอนุภาคให้เลือกพื้นผิวของอนุภาค เปลี่ยนสีของควันเป็นสีน้ำเงินเข้มด้วยความโปร่งใสประมาณ 50% ไปที่องค์ประกอบการเรนเดอร์ของแต่ละระบบอนุภาคในพอร์ทัลของคุณ และเลือกวัสดุที่เกี่ยวข้องที่เราเพิ่งสร้างขึ้น
ขั้นตอนที่ 7: สร้าง Skybox
ตอนนี้เพื่อสร้างลุคแบบกลับหัวกลับหาง เราต้องแต้มทุกอย่างเป็นสีน้ำเงินเข้ม สำหรับสิ่งนี้เราจะใช้ skybox แบบโปร่งใสเพื่อสร้าง shader ใหม่แล้ววางในรหัสนี้:
Shader "พอร์ทัล / พอร์ทัลสกายบ็อกซ์" {
คุณสมบัติ { _Tint ("Tint Color", Color) = (.5,.5,.5,.5) [Gamma] _Exposure ("Exposure", Range (0, 8)) = 1.0 _Rotation ("การหมุน", ช่วง (0, 360)) = 0 [NoScaleOffset] _Tex ("Cubemap (HDR)", Cube) = "grey" {} _Stencil ("StencilNum", int) = 6 } SubShader { แท็ก { "Queue"="Background" "RenderType"="Background" "PreviewType"="Skybox" } ตัดออก ZWrite ปิด Blend SrcAlpha OneMinusSrcAlpha ลายฉลุ{ Ref 1 Comp[_Stencil] } ผ่าน { CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 2.0 #include "UnityCG.cginc" ตัวอย่างCUBE _Tex; half4 _Tex_HDR; half4 _Tint; ครึ่งหนึ่ง _Exposure; ลอย _หมุน; float3 RotateAroundYInDegrees (จุดยอด float3 องศาลอย) { float alpha = องศา * UNITY_PI / 180.0; ลอยซินา, โคซ่า; บาป(อัลฟา, ซีนา, โคซ่า); float2x2 m = float2x2(cosa, -sina, sina, cosa); ส่งคืน float3(mul(m, vertex.xz), vertex.y).xzy; } struct appdata_t { จุดยอด float4: ตำแหน่ง; UNITY_VERTEX_INPUT_INSTANCE_ID }; โครงสร้าง v2f { จุดยอด float4: 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 หมุนแล้ว = RotateAroundYInDegrees (v.vertex, _Rotation); o.vertex = UnityObjectToClipPos (หมุน); o.texcoord = v.vertex.xyz; กลับ o; } fixed4 Frag (v2f i): SV_Target { half4 tex = texCUBE (_Tex, i.texcoord); half3 c = DecodeHDR (เท็กซ์, _Tex_HDR); c = c * _Tint.rgb * unity_ColorSpaceDouble.rgb; c *= _การรับแสง; กลับ half4(c,.5); } ENDCG } } ปิดทางเลือก }
ตอนนี้สร้างวัสดุ skybox ใหม่ เรียกว่า "PortalSkybox" และเลือกพอร์ทัลนี้ Skybox shader จากเมนูพอร์ทัล ไปที่ Window, Lighting ที่ด้านบนและเลือก skybox ที่เราเพิ่งสร้างขึ้น ไปที่กล้องหลักและตั้งค่าสถานะที่ชัดเจนเป็น skybox ขณะที่เราอยู่ที่นี่ ให้เพิ่มส่วนประกอบบางอย่างในกล้องของเราเพื่อให้เราสามารถตรวจจับการชนกันได้ เพิ่มส่วนประกอบที่แข็งแรงให้กับกล้องและยกเลิกการเลือกแรงโน้มถ่วง เพิ่มกล่อง collider และทำเครื่องหมายว่าเป็นทริกเกอร์ ทำให้กล่องชนกันขนาด.5 x 1 x 4 ตั้งค่าระนาบการตัดบนกล้องเป็น.01
ขั้นตอนที่ 8: พอร์ทัลลอจิก
สิ่งสุดท้ายที่เราต้องทำคือสร้างตรรกะที่ควบคุมพอร์ทัลของเรา สร้างสคริปต์ C# ใหม่และเรียกมันว่า PortalController
ใช้ System. Collections;
ใช้ System. Collections. Generic; ใช้ UnityEngine; เนมสเปซ UnityEngine. XR.iOS { คลาสสาธารณะ PortalController: MonoBehaviour { วัสดุสาธารณะ วัสดุ; สาธารณะ MeshRenderer meshRenderer; UnityARVideo สาธารณะ UnityARVideo; บูลส่วนตัว isInside = false; บูลส่วนตัว isOutside = true; // ใช้สำหรับการเริ่มต้นเป็นโมฆะ Start () { OutsidePortal (); } โมฆะ OnTriggerStay (Collider col) { Vector3 playerPos = Camera.main.transform.position + Camera.main.transform.forward * (Camera.main.nearClipPlane * 4); ถ้า (transform. InverseTransformPoint (playerPos).z <= 0){ if (isOutside) { isOutside = false; isInside = จริง; พอร์ทัลภายใน (); } } else { if (isInside) { isInside = false; isOutside = จริง; พอร์ทัลภายนอก (); } } } เป็นโมฆะ OutsidePortal(){ StartCoroutine (DelayChangeMat (3)); } เป็นโมฆะ InsidePortal(){ StartCoroutine (DelayChangeMat (6)); } IEnumerator DelayChangeMat (int stencilNum) { UnityARVideo.shouldRender = false; ผลตอบแทนกลับมาใหม่ WaitForEndOfFrame (); meshRenderer.enabled = เท็จ; foreach (เสื่อวัสดุในวัสดุ) { mat. SetInt ("_Stencil", stencilNum); } ผลตอบแทนใหม่ WaitForEndOfFrame (); meshRenderer.enabled = จริง; UnityARVideo.shouldRender = true; } } }
ลากสคริปต์ใหม่นี้ไปยังหน้าต่างพอร์ทัลของคุณ สิ่งนี้จะเปลี่ยนเราเข้าและออกจากพอร์ทัลเมื่อใดก็ตามที่ collider บนกล้องของเรากำลังชนกับหน้าต่างพอร์ทัล ตอนนี้ในฟังก์ชันที่เปลี่ยนวัสดุทั้งหมด เราบอกให้ปลั๊กอิน ARkit ไม่แสดงเฟรม ดังนั้นไปที่กล้องหลักและเปิดสคริปต์ UnityARVideo สร้างบูลสาธารณะ shouldRender ที่ด้านบนและตั้งค่าให้เท่ากับ true ในฟังก์ชัน OnPreRender() จะรวมทุกอย่างไว้ในคำสั่ง if โดยที่ทุกอย่างภายในจะทำงานก็ต่อเมื่อ shouldRender เป็นจริงเท่านั้น สคริปต์ทั้งหมดควรมีลักษณะดังนี้:
การใช้ระบบ
ใช้ System. Runtime. InteropServices; ใช้ UnityEngine; ใช้ UnityEngine. Rendering; เนมสเปซ UnityEngine. XR.iOS { คลาสสาธารณะ UnityARVideo: MonoBehaviour { วัสดุสาธารณะ m_ClearMaterial; [HideInInspector] บูลสาธารณะ shouldRender = true; CommandBuffer ส่วนตัว m_VideoCommandBuffer; Texture2D ส่วนตัว _videoTextureY; Texture2D ส่วนตัว _videoTextureCbCr; Matrix4x4 ส่วนตัว _displayTransform; บูลส่วนตัว bCommandBufferInitialized; โมฆะสาธารณะเริ่มต้น () { UnityARSessionNativeInterface. ARFrameUpdatedEvent += UpdateFrame; bCommandBufferInitialized = false; } เป็นโมฆะ UpdateFrame (กล้อง UnityARCamera) { _displayTransform = ใหม่ 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); } เป็นโมฆะ InitializeCommandBuffer () { m_VideoCommandBuffer = ใหม่ CommandBuffer (); m_VideoCommandBuffer. Blit (null, BuiltinRenderTextureType. CurrentActive, m_ClearMaterial); GetComponent(). AddCommandBuffer(CameraEvent. BeforeForwardOpaque, m_VideoCommandBuffer); GetComponent(). AddCommandBuffer(CameraEvent. BeforeForwardOpaque, m_VideoCommandBuffer); bCommandBufferInitialized = true; } โมฆะ OnDestroy () { GetComponent (). RemoveCommandBuffer (CameraEvent. BeforeForwardOpaque, m_VideoCommandBuffer); UnityARessionNativeInterface. ARFrameUpdatedEvent -= UpdateFrame; bCommandBufferInitialized = false; } #if !UNITY_EDITOR โมฆะสาธารณะ OnPreRender() { if (shouldRender){ ARTextureHandles handles = UnityARSessionNativeInterface. GetARessionNativeInterface (). GetARVideoTextureHandles(); ถ้า (handles.textureY == System. IntPtr. Zero || handles.textureCbCr == System. IntPtr. Zero) { กลับ; } ถ้า (!bCommandBufferInitialized) { InitializeCommandBuffer (); } ความละเอียด currentResolution = Screen.currentResolution; // พื้นผิว Y ถ้า (_videoTextureY == null) { _videoTextureY = Texture2D. CreateExternalTexture (currentResolution.width, currentResolution.height, TextureFormat. R8, เท็จ, เท็จ, (System. IntPtr) handles.textureY); _videoTextureY.filterMode = FilterMode. Bilinear; _videoTextureY.wrapMode = TextureWrapMode ทำซ้ำ; m_ClearMaterial. SetTexture("_textureY", _videoTextureY); } // Texture CbCr ถ้า (_videoTextureCbCr == null) { _videoTextureCbCr = Texture2D. CreateExternalTexture (currentResolution.width, currentResolution.height, TextureFormat. RG16, false, false, (System. IntPtr) handles.textureCbCr); _videoTextureCbCr.filterMode = FilterMode. Bilinear; _videoTextureCbCr.wrapMode = TextureWrapMode ทำซ้ำ; m_ClearMaterial. SetTexture("_textureCbCr", _videoTextureCbCr); m_ClearMaterial. SetTexture("_textureCbCr", _videoTextureCbCr); } _videoTextureY. UpdateExternalTexture(handles.textureY); _videoTextureCbCr. UpdateExternalTexture(จัดการ.textureCbCr); m_ClearMaterial. SetMatrix("_DisplayTransform", _displayTransform); } } #else โมฆะสาธารณะ SetYTexure (Texture2D YTex) { _videoTextureY = YTex; } โมฆะสาธารณะ SetUVTexure (Texture2D UVTex) { _videoTextureCbCr = UVTex; } โมฆะสาธารณะ OnPreRender () { if (!bCommandBufferInitialized) { InitializeCommandBuffer (); } m_ClearMaterial. SetTexture("_textureY", _videoTextureY); m_ClearMaterial. SetTexture("_textureCbCr", _videoTextureCbCr); m_ClearMaterial. SetTexture("_textureCbCr", _videoTextureCbCr); m_ClearMaterial. SetMatrix("_DisplayTransform", _displayTransform); } #endif } }
ขั้นตอนที่ 9: เกือบเสร็จแล้ว
สุดท้ายเมื่อเราคลิกหน้าจอและวางพอร์ทัล เราต้องการให้พอร์ทัลหันเข้าหาเราเสมอ เมื่อต้องการทำสิ่งนี้ ให้ไปที่สคริปต์ "UnityARHitTestExample" บนพอร์ทัล แทนที่ทุกอย่างภายในด้วยสิ่งนี้:
การใช้ระบบ
ใช้ System. Collections. Generic; เนมสเปซ UnityEngine. XR.iOS { คลาสสาธารณะ UnityARHitTestExample: MonoBehaviour { การแปลงสาธารณะ m_HitTransform; โฟลตสาธารณะ maxRayDistance = 30.0f; LayerMask สาธารณะชนLayer = 1 < 0) { foreach (var hitResult ใน hitResults) { Debug. Log ("โดนแล้ว!"); m_HitTransform.position = UnityARMatrixOps. GetPosition (hitResult.worldTransform); m_HitTransform.rotation = UnityARMatrixOps. GetRotation (hitResult.worldTransform); Debug. Log (สตริง.รูปแบบ ("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 (Camera.main.transform); transform.eulerAngles = Vector3 ใหม่ (currAngle.x, transform.eulerAngles.y, currAngle.z); คืนค่าจริง; } } คืนค่าเท็จ } // เรียกใช้การอัปเดตหนึ่งครั้งต่อเฟรม โมฆะ อัปเดต () { #if UNITY_EDITOR // เราจะใช้สคริปต์นี้ที่ด้านแก้ไขเท่านั้น แม้ว่าจะไม่มีอะไรที่จะป้องกันไม่ให้มันทำงานบนอุปกรณ์ได้หาก (Input. GetMouseButtonDown (0)) { Ray ray = Camera.main. ScreenPointToRay (Input.mousePosition); RaycastHit ตี; // เราจะพยายามตีวัตถุเกมชนเครื่องบินที่สร้างขึ้นโดยปลั๊กอิน // คล้ายกับการเรียก HitTest ด้วย ARHitTestResultType. ARHitTestResultTypeExistingPlaneUsingExtent ถ้า (Physics. Raycast (ray, out hit, maxRayDistance, collisionLayer)) { // เราจะได้ตำแหน่งจากจุดติดต่อ m_HitTransform.position = hit.point; Debug. Log (สตริง.รูปแบบ ("x:{0:0.######} y:{1:0.######} z:{2:0.###### }", m_HitTransform.position.x, m_HitTransform.position.y, m_HitTransform.position.z)); //และการหมุนจากการแปลงของเครื่องบินชนกัน m_HitTransform.rotation = hit.transform.rotation; } } #else ถ้า (Input.touchCount > 0 && m_HitTransform != null) { var touch = Input. GetTouch(0); ถ้า (touch.phase == TouchPhase. Began || touch.phase == TouchPhase. Moved) { var screenPosition = Camera.main. ScreenToViewportPoint (touch.position); จุด ARPoint = ARPoint ใหม่ { x = screenPosition.x, y = screenPosition.y }; // จัดลำดับความสำคัญประเภทผลลัพธ์ ARHitTestResultType resultTypes = { ARHitTestResultType. ARHitTestResultTypeExistingPlaneUsingExtent, // หากคุณต้องการใช้ระนาบอนันต์ ให้ใช้สิ่งนี้: //ARHitTestResultType. ARHitTestResultTypeExistingPlane, ARHitTestResultTypeARHitTestResultTypeR foreach (ARHitTestResultType resultType ใน resultTypes) { if (HitTestWithResultType (point, resultType)) { return; } } } } #endif } } }
ขั้นตอนที่ 10: ใส่แอพในโทรศัพท์ของคุณ
ในที่สุดเราก็ทำเสร็จแล้ว ไปที่ไฟล์ สร้างการตั้งค่า และคลิกสร้าง เปิด Xcode แล้วเลือกโฟลเดอร์ที่สร้างจากบิลด์ เลือกทีมพัฒนาของคุณและใส่แอพลงในโทรศัพท์ของคุณ! คุณอาจต้องการเปลี่ยนสีของอนุภาคและกล่องสกายบ็อกซ์เพื่อให้เหมาะกับความต้องการของคุณ แจ้งให้เราทราบในความคิดเห็นหากคุณมีคำถามใด ๆ และขอขอบคุณที่มองหา!