AR Portal กลับหัวกลับหางจาก Stranger Things: 10 ขั้นตอน (พร้อมรูปภาพ)
AR Portal กลับหัวกลับหางจาก Stranger Things: 10 ขั้นตอน (พร้อมรูปภาพ)

วีดีโอ: AR Portal กลับหัวกลับหางจาก Stranger Things: 10 ขั้นตอน (พร้อมรูปภาพ)

วีดีโอ: AR Portal กลับหัวกลับหางจาก Stranger Things: 10 ขั้นตอน (พร้อมรูปภาพ)
วีดีโอ: The Stranger Things Portal Scene Makes No Sense 2025, มกราคม
Anonim
AR Portal กลับหัวกลับหางจาก Stranger Things
AR Portal กลับหัวกลับหางจาก Stranger Things
AR Portal กลับหัวกลับหางจาก Stranger Things
AR Portal กลับหัวกลับหางจาก Stranger Things

คำแนะนำนี้จะผ่านการสร้างแอพมือถือเสมือนจริงสำหรับ 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

อนุภาค Shaders
อนุภาค 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 แล้วเลือกโฟลเดอร์ที่สร้างจากบิลด์ เลือกทีมพัฒนาของคุณและใส่แอพลงในโทรศัพท์ของคุณ! คุณอาจต้องการเปลี่ยนสีของอนุภาคและกล่องสกายบ็อกซ์เพื่อให้เหมาะกับความต้องการของคุณ แจ้งให้เราทราบในความคิดเห็นหากคุณมีคำถามใด ๆ และขอขอบคุณที่มองหา!