Android XR

معماری محتوای فضایی در Android XR با Unity

بلندگو

  • Levana Chen

    مهندس نرم‌افزار

  • جنیفر استنتون

    مهندس نرم‌افزار ارشد

درباره

درباره سخنرانی

با نحوه لنگر انداختن و ماندگار کردن تجربه‌های سه‌بعدی در دنیای واقعی بااستفاده از Unity و Android XR آشنا شوید. این جلسه چارچوب Spatial Entities،‏ Cloud Anchors، و Geospatial API را پوشش می‌دهد و نشان می‌دهد چگونه برنامه‌های بافت‌آگاه بسازید که مکان‌های فیزیکی را به‌خاطر می‌آورند و داده‌های فضایی چندکاربره را در جلسات مختلف همگام‌سازی می‌کنند.

معماری پشت نهادهای فضایی را بررسی خواهیم کرد و با نحوه لنگر انداختن دارایی‌های دیجیتال به اشیاء فیزیکی، سطوح، و مکان‌های جغرافیایی آشنا خواهیم شد. با گردش‌کارهای Unity کاربردی برای نقشه‌برداری از فضاها، حفظ محتوا در جلسات، و ایجاد تجربه‌های مشترک و آگاه از مکان AR/XR آشنا خواهید شد.

خلاصه

  • ‫AR Foundation بااستفاده از افزونه‌های OpenXR، یک میانای برنامه‌سازی کاربردی اسکریپت‌نویسی یکپارچه در پلاتفرم‌های XR ارائه می‌دهد. این API به شما امکان می‌دهد ویژگی‌های دنیای واقعی مانند صفحه‌ها و مش‌ها را نمایش دهید و جستجو کنید.
  • لنگرهای پایدار محتوای دیجیتال را در جلسه‌ها و بازراه‌اندازی‌های دستگاه تثبیت می‌کنند. می‌توانید آن‌ها را با TrySaveAnchorAsync حفظ کنید و بااستفاده از GUIDهای سریالی‌شده دوباره بار کنید.
  • چارچوب «نهادهای فضایی» جایگزین افزونه‌های قابل‌ردیابی می‌شود تا پشتیبانی چندسکویی و عملکرد بهتری برای ردیابی مواردی مانند جعبه‌های مرزی و نشانگرها ارائه دهد.
  • مؤلفه‌های مدیر باید تا زمانی که اجازه‌های Android XR اعطا نشده است غیرفعال باشند. این کار از خرابی‌های مقداردهی اولیه زیرسیستم که به‌دلیل دسترسی محدود به داده‌های محیطی حساس ایجاد می‌شود جلوگیری می‌کند.
  • ‫Geospatial API از سرویس‌های Google Cloud ARCore و VPS برای قرار دادن محتوا در مکان‌های واقعی در فضای باز استفاده می‌کند.

منابع

Gemini Notebook

موضوع

  • android-xr
  • اتحاد
  • ar-foundation
  • openxr
  • spatial-entities
  • متن‌های پیوندی
  • geospatial-api

آوانویسی

مقدمه و نمای کلی AR Foundation

  • بسیار خوب.

  • خوش آمدید.

  • این «معماری محتوای فضایی در Android XR با Unity» است.

  • نام من جنیفر استنتون است.

  • من به‌عنوان مهندس نرم‌افزار ارشد در Unity کار می‌کنم.

  • من در تیم «ویژگی‌های XR» کار می‌کنم، به‌طور خاص روی AR Foundation و بسته‌های مرتبط که واقعیت افزوده و ترکیبی را به Unity می‌آورند.

  • من لوانا چن از تیم موتورهای بازی Google XR هستم.

  • تیم‌های ما بر ارائه افزایه‌ها و بسته‌هایی تمرکز کردند که عملکرد «واقعیت گسترده» را بهبود می‌بخشند و موتور بازی را به‌طور یکپارچه ادغام می‌کنند.

  • یکی از بزرگ‌ترین چالش‌هایی که از شما می‌شنویم این است که پشتیبانی از چندین پلاتفرم واقعیت گسترده با پایگاه کد یکسان کار زیادی می‌برد.

  • ‫AR Foundation لایه میانای برنامه‌سازی کاربردی واقعیت گسترده سطح بالای Unity است.

  • می‌توانید چندین پلاتفرم XR را بدون بازنویسی‌های عمده کد و نیاز به مدیریت چندین پایگاه کد هدف قرار دهید، و یک میانای برنامه‌سازی کاربردی اسکریپت‌نویسی برای ویژگی‌های واقعیت افزوده در هر پلاتفرمی به شما می‌دهد.

  • این کار به شما امکان می‌دهد روی ایجاد برنامه، بازی، یا تجربه خود تمرکز کنید و Unity جزئیات پلاتفرم را برای شما مدیریت می‌کند.

  • یکی از روش‌هایی که AR Foundation این کار را انجام می‌دهد ازطریق افزونه‌های OpenXR است.

  • این‌ها مجموعه‌ای از میاناهای برنامه‌سازی کاربردی استاندارد صنعتی باز هستند که توسط Khronos Group تعریف شده‌اند.

  • OpenXR همچنین «نهادهای فضایی» ایجاد کرده است.

  • این چارچوبی برای محتوای دیجیتال است تا دنیای فیزیکی را نمایش دهد و با آن تعامل کند.

  • «نهادهای فضایی» مدلی یکپارچه برای نمایش عناصر دنیای واقعی به‌عنوان اشیای دیجیتال ارائه می‌دهند.

  • خوشحالم که برخی‌از جدیدترین اطلاعات درباره AR Foundation را با شما هم‌رسانی می‌کنم تا بتوانید سفرتان را برای ایجاد تجربه‌های واقعیت گسترده آغاز کنید.

  • سپس، قابلیت‌های AR Foundation را بررسی می‌کنم تا محتوای دیجیتال شما بتواند با دنیای واقعی تعامل داشته باشد.

  • سپس راه‌اندازی پروژه را مرور می‌کنم، ازجمله بسته‌ها و وابستگی‌های دیگر، تا بتوانید این را در پروژه‌هایتان پیاده‌سازی کنید.

  • و سپس با بررسی برخی‌از ویژگی‌های منحصربه‌فرد Android XR، بحث را به پایان خواهم رساند.

ویژگی‌های کلیدی AR Foundation

  • بنابراین، یکی از روش‌هایی که AR Foundation دنیای واقعی را به‌صورت دیجیتال نشان می‌دهد، صفحه‌ها هستند.

  • و این‌ها سطوح صاف در محیط فیزیکی هستند، مانند کف، دیوار، سقف، و حتی میز و کاناپه.

  • مش‌ها ساختارهای سه‌بعدی هستند که هندسه دنیای فیزیکی را نشان می‌دهند.

  • و سپس ما همچنین راه‌هایی برای تعامل با دنیای واقعی داریم، پرتوهای ری‌کست.

  • این نقاط تعیین می‌کنند که پرتو در کجا با محتوای دیجیتال تلاقی می‌کند.

  • آن را به‌عنوان یک اشاره‌گر لیزری درنظر بگیرید و اطلاعاتی درباره جایی که اشاره‌گر لیزری می‌تابد دریافت کنید.

  • همچنین لنگرهایی داریم که به تثبیت و جابه‌جایی نقطه‌ای در فضا کمک می‌کنند.

  • بعداً در این ارائه، لنگرها را بیشتر بررسی خواهم کرد.

  • بنابراین، هر چهار مورد به‌عنوان ویژگی‌های AR Foundation درنظر گرفته می‌شوند.

  • همچنین چند ویژگی دیگر وجود دارد که در این اسلاید ذکر نشده است.

  • به‌طور خاص، صفحه‌ها و لنگرها قابل‌ردیابی درنظر گرفته می‌شوند زیرا کلاس ARTrackable را گسترش می‌دهند و مدیران آن‌ها به‌روزرسانی‌ها را از زمان اجرا ردیابی می‌کنند.

  • بنابراین، بیایید به هواپیماها بپردازیم.

  • برای سطوح، مؤلفه ARPlane را داریم که سطوح صاف را به‌طور هم‌زمان شناسایی می‌کند.

  • آن‌ها برچسب‌های معنایی دارند که می‌توانید از آن‌ها پرس‌وجو کنید تا بدانید که آیا صفحه شما کف، میز، دیوار، و غیره است.

  • صفحه‌ها مرزهای پویایی نیز دارند، بنابراین، وقتی کاربر در دنیای واقعی حرکت می‌کند و می‌تواند سطوح بیشتری را ببیند، مرزهای صفحه به‌طور پویا و هم‌زمان گسترش می‌یابند، ادغام می‌شوند، و اصلاح می‌شوند.

  • همچنین می‌توانیم یک برخورددهنده مش به صفحه متصل کنیم تا فیزیک را مدیریت کند.

  • در اینجا می‌توانید نمونه‌ای از تشخیص سطح را ببینید.

  • این صحنه پرتوتابی نمونه‌های AR Foundation است که در دستگاه Android XR اجرا می‌شود.

  • این مدل چندضلعی‌های دوبعدی پویا را به‌صورت هم‌زمان تشخیص می‌دهد.

  • با دنبال کردن راهنمای راه‌اندازی پروژه ما یا بااستفاده از یکی از نمونه‌ها یا الگوهای ما می‌توانید برنامه‌ای بسازید که این عملکرد را داشته باشد.

  • بعدی، مش‌ها را داریم.

  • مش‌ها یکی از ویژگی‌های واقعیت افزوده هستند که مش‌های سه‌بعدی از محیط ارائه می‌دهند.

  • می‌توانیم یک برخورددهنده مش به این مش‌های تولیدشده متصل کنیم و این به محتوای دیجیتال شما اجازه می‌دهد با اشیاء دنیای واقعی تعامل داشته باشد.

  • مش‌ها امکان انسداد متقاعدکننده اشیا را فراهم می‌کنند.

  • بنابراین، شیء مجازی می‌تواند پشت شیء فیزیکی ظاهر شود.

  • اگر شیء دیجیتال شما می‌تواند در فضا حرکت کند، می‌توانید از همان هندسه برای پیدا کردن مسیری استفاده کنید که از اشیاء دنیای واقعی اجتناب می‌کند.

  • در مرحله بعد، پرتو افکنی را داریم.

  • «پرتوتابی» پرتوهای مجازی را به صحنه سه‌بعدی شما می‌تاباند تا تقاطع‌ها را بدون اینکه نگران محاسبات پیچیده ریاضی باشید پیدا کند.

  • پرتو پیش‌بینی‌شده پروژه می‌تواند به‌طور بالقوه با چندین شیء سه‌بعدی در محیط شما تلاقی داشته باشد.

  • می‌توانید پرتو افکنده را پیکربندی کنید تا فقط به انواع خاصی از محتوای دیجیتال برخورد کند.

  • برای مثال، می‌توانید آن را طوری پیکربندی کنید که به صفحه‌ها برخورد نکند و فقط با مش‌ها تلاقی داشته باشد.

راه‌اندازی بسته‌ها و وابستگی‌ها

  • اکنون بیایید نگاهی به بسته‌های مربوطه بیندازیم.

  • همه این بسته‌ها باهم کار می‌کنند تا با یکدیگر ارتباط برقرار کنند و تجربه واقعیت گسترده کاملی ایجاد کنند.

  • همان‌طور که گفته شد، AR Foundation ویژگی‌هایی مثل صفحه‌ها و لنگرها را مدیریت می‌کند.

  • افزونه OpenXR میاناهای برنامه‌سازی کاربردی بومی را در پلاتفرم‌های مختلف XR مدیریت می‌کند، بنابراین اگر دستگاهتان از OpenXR استفاده می‌کند، بهتر است از این بسته استفاده کنید.

  • افزایه OpenXR را می‌توان به‌صورت اختیاری با بسته «نهادهای فضایی OpenXR» جفت کرد تا به‌طور خاص به افزونه‌های «نهادهای فضایی» دسترسی پیدا کرد، و در ادامه بیشتر درباره آن توضیح داده می‌شود.

  • اگر می‌دانید که به‌طور خاص دستگاه‌های Android XR را هدف‌یابی خواهید کرد، مثل هدست‌های XR و عینک‌های XR سیمی، بسته Unity OpenXR Android XR برای این کار لازم است.

  • و چون همه این‌ها از الگوی افزونه پیروی می‌کند، تأثیر آن بر کد شما باید حداقل باشد.

  • همه ویژگی‌ها در همه بسته‌های AR Foundation دردسترس نیستند.

  • برای مثال، اگر به این نمودار نگاه کنید، مش‌بندی درحال‌حاضر در بسته Unity OpenXR Spatial Entities دردسترس نیست.

  • «مدیریت افزونه XR» به شما امکان می‌دهد مدیریت کنید کدام ویژگی‌های OpenXR در پروژه‌تان انتخاب شوند.

  • بنابراین اگر در ویرایشگر Unity هستید، به «ویرایش»، «تنظیمات پروژه» می‌روید و سپس «مدیریت افزایه XR» در نوار کناری سمت راست قرار خواهد داشت.

  • و در اینجا می‌توانید ویژگی‌ها و گروه‌های ویژگی OpenXR را پیدا کنید تا بتوانید ویژگی‌ها و گروه‌های ویژگی‌ای را که می‌خواهید در ساختتان گنجانده شود انتخاب یا لغو انتخاب کنید.

  • برای مثال، در این نماگرفت، همه مواردی را که با بسته Android XR OpenXR ارائه می‌شوند می‌بینیم.

  • و سپس می‌توانید این‌ها را با نهادهای فضایی ترکیب و مطابقت دهید، مثلاً اگر بخواهید.

  • بنابراین، این پنجره «مدیر بسته» است.

  • برخی‌از بسته‌هایی را که ممکن است در راه‌اندازی پروژه «واقعیت گسترده» معمولی ببینید برجسته کرده‌ام.

  • همان‌طور که می‌بینید، AR Foundation را داریم که به آن اشاره شده است.

  • افزایه OpenXR را نیز داریم.

  • بسته Android XR را داریم.

  • همچنین برخی‌از پلاتفرم‌های دیگر را برجسته کرده‌ام زیرا مطمئناً می‌توانید پروژه‌ای بسازید که در چندین پلاتفرم کامپایل شود.

  • و سپس در پایین سمت چپ، چند بسته دیگر نیز داریم.

  • Composition Layers که با دستگاه‌های OpenXR کار می‌کند؛ Core Utils که برای هر چیزی که به واقعیت گسترده مربوط باشد بسیار مفید است؛ و سپس XR Hands و XR Interaction Toolkit برای دریافت ورودی شما که بسیار ضروری است.

  • بنابراین، در مرحله بعد، اعتبارسنجی پروژه را داریم.

  • بنابراین، این هم بخشی از «مدیریت افزونه واقعیت گسترده» است.

  • اعتبارسنجی پروژه می‌تواند ویژگی‌های تکراری و همچنین مشکلات دیگری را در پروژه شما شناسایی کند که برای اجرای آن باید برطرف کنید.

  • اما در این نماگرفت، ویژگی‌های تکراری را برجسته کرده‌ام.

  • بنابراین، آنچه این اساساً می‌گوید این است که دو ویژگی یکسان، مانند فکر می‌کنم ما لنگرها، شاید هواپیماها و ری‌کست‌ها را در اینجا داریم.

  • کاربر انتخاب کرده است که نسخه‌های تکراری این ویژگی‌ها را از چند بسته اضافه کند و فقط از کاربر خواسته می‌شود یکی از آن‌ها را انتخاب کند.

لنگرهای محلی و پایداری

  • بنابراین، این ما را به لنگرهای محلی و پایداری می‌رساند.

  • لنگرها تضمین می‌کنند که محتوای دیجیتال در مکان‌های موردنظر در محیط باقی می‌ماند، صرف‌نظر از تغییراتی که در وضعیت ردیابی جلسه واقعیت افزوده ایجاد می‌شود.

  • پلاتفرم‌های واقعیت افزوده به‌طور خودکار موقعیت لنگرها را درطول زمان به‌روز می‌کنند تا مطمئن شوند که در موقعیت ثابتی باقی می‌مانند، و لنگرها بهترین راه برای اطمینان از این هستند که اگر از لنگر خود دور شوید و سپس به‌سمت آن برگردید، محتوای شما در جای خود باقی می‌ماند.

  • و وقتی کاربر برنامه‌اش را می‌بندد و بعداً آن را بازراه‌اندازی می‌کند و در جلسه جداگانه‌ای به آن برمی‌گردد چطور؟

  • لنگرهای پایدار به شما امکان می‌دهند لنگرها را در جلسه واقعیت افزوده ذخیره کنید و سپس آن‌ها را در جلسه‌های بعدی بار کنید.

  • این هشدارها در چرخه عمر برنامه و بازراه‌اندازی دستگاه باقی می‌مانند.

  • در اینجا نمونه لنگرهای ماندگار ما در پروژه «نمونه‌های AR Foundation» نشان داده شده است.

  • صحنه نمونه منویی دارد که همه عملکردهای پشتیبانی‌شده در آن پلاتفرم را دارد، مثل ذخیره و بار کردن لنگرها.

  • و این ما را به چرخه زندگی لنگرهای پایدار می‌رساند.

  • ابتدا یک لنگر به‌صورت محلی ایجاد می‌کنید، بنابراین هنوز در جایی ذخیره نشده است، در فضای ذخیره‌سازی دائمی ذخیره نشده است، فقط یک لنگر محلی است.

  • و سپس آن را در فضای ذخیره‌سازی نگه می‌دارید.

  • پس‌از آن، می‌توانید برنامه را بازراه‌اندازی کنید و سپس می‌توانید آن را از فضای ذخیره‌سازی بار کنید.

  • برخی پلاتفرم‌ها ازجمله Android XR از پاک کردن یا غیرثابت کردن لنگرها نیز پشتیبانی می‌کنند.

  • ارائه‌دهنده «نهادهای فضایی» از بار کردن خودکار همه لنگرهای ذخیره‌شده پشتیبانی می‌کند تا مجبور نباشید هر لنگر را به‌طور دستی با شناسه آن درخواست کنید.

  • در تنظیمات «مدیریت افزایه XR»، می‌توانید گزینه «بار کردن خودکار لنگرهای ذخیره‌شده» را در ویژگی «نهادهای فضایی: لنگرها» انتخاب کنید.

  • و ذخیره کردن لنگر فقط چند خط کد نیاز دارد.

  • ابتدا، در ویرایشگر Unity شروع می‌کنیم و با افزودن مؤلفه AR Anchor Manager به شیء بازی XR Origin، مطمئن می‌شویم که صحنه شما آماده است.

  • مدیر صحنه را با لنگرهای ردیابی‌شده از زمان اجرا به‌روز نگه می‌دارد.

  • خب، این ما را به کد می‌رساند.

  • برای افزودن لنگر، کافی است TryAddAnchorAsync را فراخوانی کنید و ژست جایی را که می‌خواهید لنگر را در آن قرار دهید ارسال کنید.

    async void CreateAnchorAsync(ARAnchorManager manager, Pose pose) {
        var result = await manager.TryAddAnchorAsync(pose);
        if (result.status.IsError()) {
            // handle error
            return;
        }
        var anchor = result.value;
    }
  • سپس، حذف لنگرها را داریم.

    void RemoveAnchor(ARAnchorManager manager, ARAnchor anchor) {
        var result = manager.TryRemoveAnchor(anchor.trackableId);
        if (result.status.IsError()) {
            // handle error
            return;
        }
    }
    
    void DestroyAnchorComponent(ARAnchor anchor) {
        Destroy(anchor);
    }
  • و به‌طور مشابه، تقریباً فقط یک خط کد است.

  • TryRemoveAnchor را فراخوانی می‌کنید، شناسه قابل‌ردیابی لنگر را ارسال می‌کنید.

  • وقتی لنگر ایجاد شد، شناسه قابل‌ردیابی به آن اختصاص داده شده است.

  • و سپس TrySaveAnchorAsync را داریم.

    async void SaveAnchorAsync(ARAnchorManager manager, ARAnchor anchor) {
        var result = await manager.TrySaveAnchorAsync(anchor);
        if (result.status.IsError()) {
            // handle error
            return;
        }
    
        // Save this value, then return it as an input parameter
        SerializableGuid guid = result.value;
    }
  • یک لنگر واقعیت افزوده را به‌عنوان ورودی ارسال می‌کنید.

  • این تابع یک SerializableGuid برمی‌گرداند که لنگر را در فضای ذخیره‌سازی پایدار شناسایی می‌کند.

  • بعداً می‌توانید هنگام بار کردن لنگر از GUID استفاده کنید.

  • و این ما را به بارگیری لنگرها می‌رساند.

    async void LoadAnchorAsync(ARAnchorManager manager, SerializableGuid guid) {
        var result = await manager.TryLoadAnchorAsync(guid);
        if (result.status.IsError()) {
            // handle error
            return;
        }
    
        ARAnchor anchor = result.value;
    }
  • تابع موردنظر برای فراخوانی در اینجا TryLoadAnchorAsync است و GUID سریالی‌شده قبلی را ارسال می‌کنید.

  • درنتیجه، یک لنگر واقعیت افزوده برمی‌گرداند.

  • و تقریباً همین است.

  • این عملکردها به شما امکان می‌دهند لنگرهای محلی و دائمی را به‌راحتی مدیریت کنید.

  • بنابراین، ردیابی لنگر در اکثر پلاتفرم‌های واقعیت افزوده کار نسبتاً پرهزینه‌ای است.

  • هنگام کار با لنگرها، این روال‌های مطلوب را درنظر بگیرید: از ایجاد چند لنگر بسیار نزدیک به یکدیگر خودداری کنید، درنظر بگیرید که آیا می‌توانید به‌جای ایجاد لنگر دیگر از لنگر نزدیک استفاده کنید، لنگرها را وقتی دیگر از آن‌ها استفاده نمی‌کنید بردارید، و درنهایت، اگر ویژگی واقعیت افزوده دیگری را برای کمک به محاسبه حالت مطلوب برای لنگر فعال می‌کنید، درنظر بگیرید که آیا می‌توانید آن ویژگی را پس‌از ایجاد موفقیت‌آمیز لنگر غیرفعال کنید.

  • و حالا، نوبت لوانا است.

کیت توسعه نرم‌افزار Android XR برای Unity

  • متشکرم، جنیفر.

  • و سپس، اجازه دهید شما را با مشارکت Google در سفر Android XR در Unity آشنا کنم.

  • بنابراین، علاوه‌بر افزایه‌های Unity OpenXR که جنیفر تاکنون معرفی کرده است، Google کیت توسعه نرم‌افزار Android XR را برای Unity با قابلیت‌های اضافی که در پلاتفرم Android XR دردسترس است ارائه می‌دهد.

  • این کیت توسعه نرم‌افزار حاوی ویژگی‌ها و بسته‌های زیادی است و در این گفتگو، بر بسته «افزونه Android XR برای Unity» تمرکز خواهیم کرد.

  • بنابراین، مشابه OpenXR Android XR و OpenXR Spatial Entities، بسته Android XR Extension for Unity درواقع یک ارائه‌دهنده OpenXR است.

  • و معماری این بسته به این شکل است و آن‌ها می‌توانند به‌صورت موازی یا مستقل کار کنند.

  • بنابراین، مانند همه ارائه‌دهندگان OpenXR دیگر، بسته Google مستقیماً بر روی میانای استاندارد OpenXR OpenXR ساخته شده است.

  • بنابراین، در اینجا مجموعه‌ای از ویژگی‌ها را به‌عنوان مقایسه بین همه ارائه‌دهندگان دیگر نشان می‌دهیم.

  • بنابراین، می‌توانید برای تصمیم‌گیری درباره اینکه چه زمانی و چرا یکی را بر دیگری ترجیح دهید، کمک بگیرید.

  • بنابراین، ممکن است سؤالی درباره نشانگر موجودیت فضایی و قابل‌ردیابی که در این جدول نشان داده شده است داشته باشید.

  • بنابراین، این نکته جانبی را درنظر داشته باشید: برای کسانی که قبلاً برنامه‌ها و تجربه‌هایی را در Android XR ساخته‌اند، این ویژگی‌ها را ازطریق افزونه‌های قابل‌ردیابی ارائه کرده‌ایم که فقط در Android XR کار می‌کنند.

  • و سپس، همان‌طور که جنیفر اشاره کرد، به‌عنوان گروه باز OpenXR کار کردیم و سپس «افزونه موجودیت‌های فضایی» را در سمت راست منتشر کردیم و تجربه‌ای سازگار و چندسکویی ارائه دادیم.

  • و درحال‌حاضر، افزونه قابل‌ردیابی را به‌نفع چارچوب «نهادهای فضایی» منسوخ می‌کنیم.

  • نه تنها دومی عملکرد بسیار بهتری دارد، بلکه از چندپلاتفرمی نیز پشتیبانی می‌کند.

ساختمان با نهادهای فضایی

  • و سپس، بیایید نگاهی دقیق‌تر به نهادهای فضایی بیندازیم.

  • بنابراین، علاوه‌بر آنچه جنیفر درباره صفحه‌ها، پرتو افکنی، و لنگرها گفت، می‌توانید این ویژگی را که توسط ارائه‌دهندگان موجودیت فضایی پشتیبانی می‌شود نیز پیدا کنید، مانند نشانگرها که می‌توانند رمزینه‌های دوبعدی استاندارد را شناسایی و رمزگشایی کنند و موقعیت آن‌ها را در فضای سه‌بعدی ردیابی کنند، و تصویر که گرافیک‌های دوبعدی شناخته‌شده را تشخیص می‌دهد و آن‌ها را در فضای سه‌بعدی ردیابی می‌کند.

  • و سپس جعبه مرزی که شیء فیزیکی را شناسایی می‌کند، مانند صفحه‌کلید، رایانه کیفی، یا موشواره، و جعبه مرزی آن‌ها را در حالت سه‌بعدی ردیابی می‌کند.

  • و در مثال بعدی، ویژگی چارگوش مرزی را که توسط بسته «افزونه‌های» Google ارائه شده است پیکربندی خواهیم کرد.

  • بنابراین، این نما برای همه ویژگی‌های OpenXR تقریباً یکسان است.

  • بنابراین، فقط باید ابتدا به پلاتفرم Android XR بروید و سپس ارائه‌دهنده OpenXR را فعال کنید و ویژگی OpenXR را که می‌خواهید با آن بسازید انتخاب کنید، برای مثال، ویژگی جعبه مرزی موجودیت فضایی در اینجا نشان داده شده است، و سپس مشکلات اعتبارسنجی پروژه را برطرف کنید.

  • این کار به شما کمک می‌کند همه وابستگی‌های موردنیاز یک ویژگی خاص را پیدا کنید و سپس تداخل‌های ناشی از مشارکت چند ویژگی در یک زیرسیستم را حل کنید.

  • گاهی اوقات، بیشتر اوقات، اگر بخواهید از لنگر، صفحه، یا جعبه مرزی در اینجا استفاده کنید، فقط باید یک ویژگی را انتخاب کنید.

  • و درنهایت می‌توانید فقط صحنه نمونه یا صحنه آزمایشی‌تان را بسازید.

  • برای دسترسی به شیء قابل‌ردیابی در زمان اجرا، می‌توانید به‌سادگی مؤلفه مدیر جعبه مرزی واقعیت افزوده را اضافه کنید، این مؤلفه مشابه مؤلفه مدیر لنگر واقعیت افزوده است، و سپس از میانای AR Foundation برای دسترسی به آن استفاده کنید.

  • همچنین می‌توانید نمونه موجودیت فضایی ارائه‌شده توسط بسته افزونه ما را به‌عنوان الگو برای شروع وارد کنید.

  • بنابراین، تفاوت اصلی هنگام استفاده از ویژگی AR Foundation در Android XR در اینجا آمده است.

  • برای کمک به درک محیط اطراف کاربر، برنامه‌تان معمولاً باید به داده‌های حساس مربوط به محیط دسترسی داشته باشد.

  • و برای محافظت از کاربر، Android XR سیستم را محدود می‌کند-- دسترسی به داده‌ها در پشت اجازه‌ها.

  • ممکن است قبلاً با آن آشنا شده باشید، مثل درخواست اجازه معمولی Android، مثلاً دسترسی به دوربین یا دسترسی به مکان، و چیزهایی ازاین‌قبیل.

  • و سپس بهترین روش در اینجا غیرفعال کردن مؤلفه مدیر در هنگام راه‌اندازی است، یا از ویرایشگر، همان‌طور که در سمت راست می‌بینید، یا از دستورگان، مانند رویداد Awake.

    void Awake() {
        planeManager = GetComponent<ARPlaneManager>();
        planeManager.enabled = false;
        boundingBoxManager = GetComponent<ARBoundingBoxManager>();
        boundingBoxManager.enabled = false;
        permissionUtil = GetComponent<AndroidXRPermissionUtil>();
    }
    
    void OnEnable() {
        StartCoroutine(WaitForPermissions());
    }
  • سپس، پس‌از اینکه همه اجازه‌های لازم را اعطا کردید، می‌توانید مدیر را از اسکریپت فعال کنید، مانند کاری که کمک‌کننده WaitForPermissions در اینجا انجام می‌دهد.

    IEnumerator WaitForPermissions() {
        planeManager.enabled = false;
        boundingBoxManager.enabled = false;
    
        yield return new WaitUntil(() =>
            permissionUtil.AllPermissionGranted());
    
        // Enable after granted permissions and
        // restart subsystems.
        planeManager.enabled = true;
        boundingBoxManager.enabled = true;
    
        // Save permission status.
        permissionGranted = true;
    }
  • با انجام این کار، می‌توانید از عدم مقداردهی اولیه زیرسیستم به‌دلیل کافی نبودن اجازه‌ها جلوگیری کنید.

  • و این ویژگی خاصی در اینجا است.

  • همان‌طور که جنیفر درباره لنگر بااستفاده از AR Foundation توضیح داد، برای گسترش قابلیت لنگر در Android XR، بسته ما ویژگی جدیدی به‌نام لنگرهای قابل‌هم‌رسانی نیز ارائه می‌دهد.

  • این ویژگی آنچه را که ویژگی لنگر AR Foundation درحال‌حاضر پشتیبانی می‌کند تکرار می‌کند و همچنین با برخی قابلیت‌های اضافی، مانند لنگرهای جغرافیایی، همراه است.

  • و همان‌طور که می‌توانید تصور کنید، لنگر پل واقعی است که دنیای مجازی و فیزیکی را به هم متصل می‌کند.

  • و درحالی‌که جنیفر ما را در ایجاد، ذخیره، و بار کردن آن‌ها راهنمایی کرده است، همه این‌ها در فضایی محلی، مانند اتاق نشیمن کاربر شما، اتفاق افتاده است.

  • اما بقیه دنیا چطور؟

  • و چطور می‌توانیم آن را با یکدیگر هم‌رسانی کنیم؟

Geospatial API

  • و اینجا است که Geospatial API وارد عمل می‌شود.

  • این ویژگی به شما امکان می‌دهد لنگر جغرافیایی فضایی را براساس مکان واقعی در جهان ایجاد کنید، مثل کتاب‌فروشی موردعلاقه‌تان یا محل ملاقات در پارکی بزرگ.

  • بنابراین، Geospatial API می‌تواند ردیاب موقعیت جغرافیایی دقیقی را ازطریق VPS (که به‌عنوان سیستم موقعیت‌یابی مجازی نیز شناخته می‌شود) به شما ارائه دهد، چیزی شبیه به GPS، اما از داده‌های «نمای خیابان» در فضای باز استفاده می‌کند تا نتایج ردیابی بسیار دقیق‌تری ارائه دهد.

  • بنابراین، اگر قبلاً با ویژگی جغرافیایی ARCore تجربه داشته باشید، ممکن است برخی‌از شما با این نما آشنا باشید.

  • بنابراین، برای دسترسی به Geospatial API در Android XR، ابتدا باید به پس‌زمینه‌ای که در پلاتفرم Google Cloud میزبانی می‌شود متصل شویم.

  • ازآنجایی‌که زیرینای جغرافیایی درواقع توسط سرویس ARCore در Google Cloud پشتیبانی می‌شود، می‌توانید دقیقاً همان مراحل را برای پیکربندی پروژه Google Cloud خود با دسترسی به ARCore API دنبال کنید.

  • همه این‌ها سپس استفاده از ویژگی Android XR Google Cloud را که توسط بسته افزونه ما ارائه می‌شود فعال می‌کند.

  • وقتی Geospatial API را فعال کردید و کلید API را از پروژه Google Cloud گرفتید، می‌توانید این ویژگی را فعال کنید و اصالت‌سنجی را ازطریق منو تنظیمات OpenXR که در اینجا نشان داده شده است پیکربندی کنید، و-- یا به‌طور جایگزین، می‌توانید آن را به‌صورت دستی ازطریق میانای برنامه‌سازی کاربردی اسکریپت‌سازی به‌نام TrySetAuthenticationAsync پیکربندی کنید.

    async Task TrySetAuthentication() {
        googleCloudFeature =
            OpenXRSettings.Instance
                .GetFeature<XRGoogleCloudFeature>();
        var result = await googleCloudFeature
            .TrySetAuthenticationAsync(
                strategy, credential);
        if (result.IsSuccess()) {
            // Ready to use for geospatial tracker.
        } else if (result.IsUnsupported())  {
            // Google Cloud feature is not supported
        } else if (result.IsKeylessError()) {
            // Confirm if keyless has been set up properly.
        } else {
            // Handling other common OpenXR errors.
        }
    }
  • توجه داشته باشید که پلتفرم Android XR درحال‌حاضر فقط از اصالت‌سنجی کلید میانای برنامه‌سازی کاربردی پشتیبانی می‌کند، اما در آینده از اطلاعات کاربری بیشتری پشتیبانی خواهد شد.

  • بنابراین، پس‌از اصالت‌سنجی، می‌توانید از مدیر جغرافیایی-فضایی برای دسترسی به قابلیت‌های جغرافیایی-فضایی استفاده کنید.

  • توصیه می‌شود قبل‌از ادغام، ابتدا Google Map را ازنظر پوشش VPS بررسی کنید.

  • بنابراین، هنگام استفاده از این ویژگی باید دسترسی به شبکه نیز داشته باشید.

  • بنابراین، XR Geospatial Manager مشابه مؤلفه AR Session ارائه‌شده توسط AR Foundation کار می‌کند.

  • بنابراین، با یک ویژگی حالت ایستا ارائه می‌شود تا پشتیبانی سیستم و وضعیت ردیابی ردیاب جغرافیایی را نشان دهد.

  • می‌توانید رویداد تغییر وضعیت را با یک فراخوانی برگشتی مانند این ثبت کنید.

    void OnGeospatialStateChanged(XRGeospatialStateChangedEventArgs eventArgs) {
        bool isInitFailed = eventArgs.CurrState == XRGeospatialState.InitializationFailed;
        if (isInitFailed && XRGeospatialManager.InitializationResult.IsCloudAuthError()) {
            // Handle cloud authentication issues.
        } else if (isInitFailed) {
            // Check XRGeospatialManager.InitializationResult for other common OpenXR errors.
        } else {
            // Iterate runtime state change, and handle accordingly.
        }
    }
    
    private void OnEnable() {
        XRGeospatialManager.OnStateChanged += OnGeospatialStateChanged;
    }
  • و وقتی وضعیت جغرافیایی-فضایی درحال اجرا شد، می‌توانید از این نمونه مدیر برای همه عملکردهای زیر استفاده کنید.

  • ابتدا، برای بررسی دردسترس بودن VPS با مکان GPS ارائه‌شده، در اینجا از میانای برنامه‌سازی کاربردی مکان Unity برای دریافت مقدار GPS استفاده می‌کنیم و سپس دردسترس بودن VPS را بررسی می‌کنیم.

    async Task CheckVPSAvailability(CancellationToken token) {
        var location = Input.location.lastData;
        try {
            var result = await geospatialManager.TryCheckVPSAvailabilityAsync(
                location.latitude, location.longitude);
            token.ThrowIfCancellationRequested();
            if (result.status.nativeStatusCode == (int)XrResultAndroid.GeospatialCoordinateInvalid) {
                // Invalid coordinates, try with another location.
            } else if (result.status.IsError()) {
                // Handle common OpenXR error: result.status.ToOpenXRStatus()
            }  else if (result.value == XRVPSAvailability.Available)  {
                // You may use this pose to attach geospatial anchors.
                var currentGeospatialPose = new XRGeospatialPose(location);
            }
        }
    }
  • بنابراین اگر نمی‌خواهید پشتیبانی VPS را ازطریق نقشه بررسی کنید، این اساساً جایگزینی برای آن است، اما برای بررسی وضعیت واقعی GPS باید به فضای باز بروید.

  • و سپس، می‌توانید بااستفاده از TryLocate، حالت را بین حالت Unity و حالت جغرافیایی تبدیل کنید.

    // Geospatial Pose -> Unity Pose
    var geospatialPose =
        new XRGeospatialPose(Input.location.lastData);
    if (geospatialManager.TryLocate(
            geospatialPose, out XRPoseResult result)) {
        if (result.IsPositionValid ||
            result.IsPositionTracked) {
            transform.position = result.Pose.position;
        }
        if (result.IsRotationValid ||
            result.IsRotationTracked) {
            transform.rotation = result.Pose.rotation;
        }
    }
    // Unity Pose -> Geospatial Pose
    Pose pose = new Pose(
        transform.position, transform.rotation);
    if (geospatialManager.TryLocate(
          pose, out XRGeospatialPoseResult result)) {
        if (result.IsPositionValid ||
            result.IsRotationValid) {
            // You may use for anchor attachment.
        }
    }
  • و با گرفتن نتیجه از بررسی VPS یا تبدیل وضعیت، می‌توانید لنگر فضایی را به وضعیت جغرافیایی فضایی معین یا روی نوع سطح شناخته‌شده‌ای، مانند زمین یا پشت‌بام، متصل کنید.

    async void PlaceAnchor(XRGeospatialPose pose) {
        try {
            Result<ARShareableAnchor> anchorResult;
            XRGeospatialSurfaceType typeToPlace = /* Choose your target type */;
            if (typeToPlace == XRGeospatialSurfaceType.Default) {
                anchorResult = geospatialManager.TryAttachGeospatialAnchor(pose);
            } else {
                pose.Altitude = 0;
                anchorResult = await geospatialManager.TryAttachSurfaceAnchorAsync(typeToPlace, pose);
            }
            if (anchorResult.status.IsSuccess()) {
                // ARShareableAnchorManager will track the anchor and update it.
            } else {
                // Handle OpenXR failures.
            }
        }
    }
  • و وقتی همه این‌ها را کنار هم قرار می‌دهید، می‌توانید تجربه فضایی واقعاً جادویی‌ای را با دنیای واقعی در جلو و مرکز بسازید.

  • بنابراین در اینجا، پیکانی قرار می‌دهیم تا مخاطبانمان را به مکان هدف در دنیای واقعی هدایت کنیم.

  • بسیارخوب.

  • بنابراین، Android XR SDK تنها بسته‌ای نیست که به توسعه‌دهندگان Unity ارائه کرده‌ایم.

  • کیت توسعه نرم‌افزار Android XR از Google برای Unity اکنون شامل چارچوب تعامل Android XR و بسته صوتی Android XR نیز می‌شود.

  • و بسیار هیجان‌زده هستیم که Android XR SDK را با پشتیبانی از ویژگی‌های بیشتر و همچنین افزودن «نهاد فضایی» بیشتر گسترش دهیم.

جمع‌بندی و منابع

  • بسیار خوب، به پایان جلسه نزدیک می‌شویم.

  • می‌توانید نقشه راه Unity را به‌صورت آنلاین دنبال کنید تا ببینید چه چیزی در راه است.

  • فراموش نکنید که Unity 7، نسل بعدی Unity، اوایل سال آینده عرضه می‌شود.

  • و در این فاصله، می‌توانید این ابزارها را امتحان کنید و بااستفاده از الگوی «واقعیت ترکیبی» پروژه‌ای ایجاد کنید یا به پروژه نمونه‌های AR Foundation در GitHub ما نگاهی بیندازید.

  • همچنین برای کسب اطلاعات بیشتر درباره Spatial Entity و پشتیبانی بسته Unity ما، می‌توانید به صفحه مربوطه در سایت توسعه‌دهندگان Android مراجعه کنید.

  • و درنهایت، از همه شما سپاس‌گزاریم.

  • بی‌صبرانه منتظریم ببینیم چه چیزهایی می‌توانید با AR Foundation و Spatial Entity در Android XR بسازید.

کد

تکه‌کدها

قطعه کد C# ‎ در زمان ۱۰:۳۴ در «لنگرهای محلی و پایداری»
async void CreateAnchorAsync(ARAnchorManager manager, Pose pose) {
    var result = await manager.TryAddAnchorAsync(pose);
    if (result.status.IsError()) {
        // handle error
        return;
    }
    var anchor = result.value;
}
قطعه کد C# ‎ در دقیقه ۱۰:۴۳ در «لنگرهای محلی و پایداری»
void RemoveAnchor(ARAnchorManager manager, ARAnchor anchor) {
    var result = manager.TryRemoveAnchor(anchor.trackableId);
    if (result.status.IsError()) {
        // handle error
        return;
    }
}

void DestroyAnchorComponent(ARAnchor anchor) {
    Destroy(anchor);
}
قطعه کد C# ‎ در دقیقه ۱۱:۰۰ در «لنگرهای محلی و پایداری»
async void SaveAnchorAsync(ARAnchorManager manager, ARAnchor anchor) {
    var result = await manager.TrySaveAnchorAsync(anchor);
    if (result.status.IsError()) {
        // handle error
        return;
    }

    // Save this value, then return it as an input parameter
    SerializableGuid guid = result.value;
}
قطعه کد C# ‎ در دقیقه ۱۱:۱۷ در «لنگرهای محلی و پایداری»
async void LoadAnchorAsync(ARAnchorManager manager, SerializableGuid guid) {
    var result = await manager.TryLoadAnchorAsync(guid);
    if (result.status.IsError()) {
        // handle error
        return;
    }

    ARAnchor anchor = result.value;
}
قطعه کد C# ‎ در ۱۶:۴۵ در «ساخت با نهادهای فضایی»
void Awake() {
    planeManager = GetComponent<ARPlaneManager>();
    planeManager.enabled = false;
    boundingBoxManager = GetComponent<ARBoundingBoxManager>();
    boundingBoxManager.enabled = false;
    permissionUtil = GetComponent<AndroidXRPermissionUtil>();
}

void OnEnable() {
    StartCoroutine(WaitForPermissions());
}
قطعه C# ‎ در دقیقه ۱۶:۵۸ در «ساخت با نهادهای فضایی»
IEnumerator WaitForPermissions() {
    planeManager.enabled = false;
    boundingBoxManager.enabled = false;

    yield return new WaitUntil(() =>
        permissionUtil.AllPermissionGranted());

    // Enable after granted permissions and
    // restart subsystems.
    planeManager.enabled = true;
    boundingBoxManager.enabled = true;

    // Save permission status.
    permissionGranted = true;
}
قطعه کد C# ‎ در دقیقه ۱۹:۱۲ در «Geospatial API»
async Task TrySetAuthentication() {
    googleCloudFeature =
        OpenXRSettings.Instance
            .GetFeature<XRGoogleCloudFeature>();
    var result = await googleCloudFeature
        .TrySetAuthenticationAsync(
            strategy, credential);
    if (result.IsSuccess()) {
        // Ready to use for geospatial tracker.
    } else if (result.IsUnsupported())  {
        // Google Cloud feature is not supported
    } else if (result.IsKeylessError()) {
        // Confirm if keyless has been set up properly.
    } else {
        // Handling other common OpenXR errors.
    }
}
قطعه C# ‎ در ۲۰:۲۴ در «Geospatial API»
void OnGeospatialStateChanged(XRGeospatialStateChangedEventArgs eventArgs) {
    bool isInitFailed = eventArgs.CurrState == XRGeospatialState.InitializationFailed;
    if (isInitFailed && XRGeospatialManager.InitializationResult.IsCloudAuthError()) {
        // Handle cloud authentication issues.
    } else if (isInitFailed) {
        // Check XRGeospatialManager.InitializationResult for other common OpenXR errors.
    } else {
        // Iterate runtime state change, and handle accordingly.
    }
}

private void OnEnable() {
    XRGeospatialManager.OnStateChanged += OnGeospatialStateChanged;
}
قطعه کد C# ‎ در دقیقه ۲۰:۳۸ در «Geospatial API»
async Task CheckVPSAvailability(CancellationToken token) {
    var location = Input.location.lastData;
    try {
        var result = await geospatialManager.TryCheckVPSAvailabilityAsync(
            location.latitude, location.longitude);
        token.ThrowIfCancellationRequested();
        if (result.status.nativeStatusCode == (int)XrResultAndroid.GeospatialCoordinateInvalid) {
            // Invalid coordinates, try with another location.
        } else if (result.status.IsError()) {
            // Handle common OpenXR error: result.status.ToOpenXRStatus()
        }  else if (result.value == XRVPSAvailability.Available)  {
            // You may use this pose to attach geospatial anchors.
            var currentGeospatialPose = new XRGeospatialPose(location);
        }
    }
}
قطعه کد C# ‎ در دقیقه ۲۱:۰۳ در «Geospatial API»
// Geospatial Pose -> Unity Pose
var geospatialPose =
    new XRGeospatialPose(Input.location.lastData);
if (geospatialManager.TryLocate(
        geospatialPose, out XRPoseResult result)) {
    if (result.IsPositionValid ||
        result.IsPositionTracked) {
        transform.position = result.Pose.position;
    }
    if (result.IsRotationValid ||
        result.IsRotationTracked) {
        transform.rotation = result.Pose.rotation;
    }
}
قطعه C# ‎ در دقیقه ۲۱:۰۳ در «Geospatial API»
// Unity Pose -> Geospatial Pose
Pose pose = new Pose(
    transform.position, transform.rotation);
if (geospatialManager.TryLocate(
      pose, out XRGeospatialPoseResult result)) {
    if (result.IsPositionValid ||
        result.IsRotationValid) {
        // You may use for anchor attachment.
    }
}
قطعه کد C# ‎ در دقیقه ۲۱:۱۱ در «Geospatial API»
async void PlaceAnchor(XRGeospatialPose pose) {
    try {
        Result<ARShareableAnchor> anchorResult;
        XRGeospatialSurfaceType typeToPlace = /* Choose your target type */;
        if (typeToPlace == XRGeospatialSurfaceType.Default) {
            anchorResult = geospatialManager.TryAttachGeospatialAnchor(pose);
        } else {
            pose.Altitude = 0;
            anchorResult = await geospatialManager.TryAttachSurfaceAnchorAsync(typeToPlace, pose);
        }
        if (anchorResult.status.IsSuccess()) {
            // ARShareableAnchorManager will track the anchor and update it.
        } else {
            // Handle OpenXR failures.
        }
    }
}