استفاده از Spatial Containers در Godot

دستگاه‌های XR واجدشرایط
این راهنمایی به شما کمک می‌کند برای این نوع دستگاه‌های واقعیت گسترده تجربه بسازید.
هدست‌های واقعیت گسترده
عینک واقعیت گسترده سیمی

محفظه‌های فضایی به برنامه شما اجازه می‌دهند محتوای OpenXR سه‌بعدی را در یک جعبه مرزی حجمی سه‌بعدی تحت مدیریت سیستم در «حالت فضای کامل» ارائه دهد یا در زمان اجرا به یک تجربه تمام‌صفحه نامحدود منتقل شود.

این راهنما را دنبال کنید تا «محفظه‌های فضایی» را در پروژه‌تان پیکربندی و استفاده کنید.

چند محفظه فضایی که در «حالت فضای کامل» در Android XR اجرا می‌شوند.
شکل ۱. محفظه‌های فضایی در «حالت فضای کامل»، ازجمله محفظه زمین سه‌بعدی قفل‌شده به کف و مدل سه‌بعدی جفت‌شده با واسط کاربر دوبعدی.

نحوه عملکرد «محفظه‌های فضایی»

وقتی Spatial Container را در تنظیمات پروژه‌تان فعال می‌کنید:

  • کل صحنه سه‌بعدی فعال شما در یک محفظه فضایی اصلی واحد قرار می‌گیرد که مرکز آن در مبدأ صحنه (0, 0, 0) است. برای قرار دادن گره‌های Node3D در محفظه، لازم نیست آن‌ها را به‌طور جداگانه برچسب‌گذاری یا واگذار کنید.
  • برنامه شما بااستفاده از حالت مرزها (Bounded یا Immersive) و ابعاد اولیه مرزها که در تنظیمات پروژه‌تان پیکربندی شده است، در «حالت فضای کامل» مدیریت‌شده راه‌اندازی می‌شود. در حالت محدود، سیستم به‌طور خودکار هر هندسه سه‌بعدی را در صحنه شما که فراتر از ابعاد جعبه محدودکننده گسترش می‌یابد، برش می‌دهد.
  • به‌طور پیش‌فرض، سیستم Android XR کنترل‌های پنجره را ارائه می‌دهد تا کاربر بتواند محفظه محدودشده را در فضای سه‌بعدی بگیرد، جابه‌جا کند، و تغییر مکان دهد، یا آن را کوچک و بسته کند. در زمان اجرا، برنامه‌تان می‌تواند اندازه ظرف را تغییر دهد، بین حالت محدود (OpenXRSpatialContainerState.BOUNDED) و حالت فراگیر تمام‌صفحه (OpenXRSpatialContainerState.IMMERSIVE) جابه‌جا شود، و بااستفاده از تک‌نمونه OpenXRSpatialContainerExtension به تغییرات مرزها و وضعیت واکنش نشان دهد.

پیش‌نیازها

قبل‌از شروع، مطمئن شوید محیط توسعه نرم‌افزار و دستگاه هدف شما الزامات زیر را برآورده می‌کنند:

فعال کردن «محفظه‌های فضایی» در تنظیمات پروژه

تنظیمات پروژه‌تان را برای فعال کردن OpenXR، «محفظه‌های فضایی»، اجازه‌های زمان اجرای خودکار، و گذر ازطریق ترکیب آلفا پیکربندی کنید:

  1. پروژه > تنظیمات پروژه را باز کنید.
  2. کلید تنظیمات پیشرفته را در گوشه بالا سمت چپ پنجره تنظیمات پروژه فعال کنید.
  3. به General > XR > Shaders بروید و Enabled را انتخاب کنید.
  4. به General (موارد کلی) > XR > OpenXR بروید و تنظیمات زیر را پیکربندی کنید:
    • فعال را انتخاب کنید تا OpenXR برای پروژه روشن شود.
    • حالت ادغام محیط را روی ادغام آلفا تنظیم کنید.
  5. همچنین در بخش OpenXR، به بخش افزونه‌ها بروید و تنظیمات زیر را پیکربندی کنید:
    • درخواست خودکار اجازه‌های زمان اجرا را انتخاب کنید تا برنامه‌تان هنگام راه‌اندازی به‌طور خودکار از کاربر برای هرگونه اجازه XR اعلام‌شده در مانیفست Android درخواست کند.
    • در بخش فرعی Spatial Container، گزینه Enabled را انتخاب کنید.
    • حالت مرزها را روی محدود تنظیم کنید تا در جعبه مرز سه‌بعدی راه‌اندازی شود، یا فراگیر را انتخاب کنید تا در حالت فراگیر تمام‌صفحه راه‌اندازی شود.
    • مرزها را روی ابعاد اولیه عرض، ارتفاع، و عمق به متر تنظیم کنید، مثلاً Vector3(1.0, 1.0, 1.0).
  6. به General (موارد کلی) > Rendering (پرداخت) > Viewport (نمای دید) بروید و Transparent Background (پس‌زمینه شفاف) را انتخاب کنید.

پیکربندی برون‌برد Android، اجازه‌ها، و «حالت فضای کامل»

سپس، پیش‌تنظیم صادر کردن Android، اجازه‌ها، و حالت شروع فعالیت را پیکربندی کنید تا برنامه‌تان در «حالت فضای کامل» با «محفظه‌های فضایی» فعال اجرا شود.

پیکربندی پیش‌تنظیم صادر کردن Android

  1. به Project (پروژه) > Export... (صادر کردن...) بروید و پیش‌تنظیم صادر کردن Android را انتخاب کنید.
  2. در بخش Gradle Build، Use Gradle Build را انتخاب کنید و Min SDK را روی 34 یا بالاتر تنظیم کنید.

    فعال کردن

  3. در بخش ویژگی‌های واقعیت گسترده، حالت واقعیت گسترده را روی OpenXR تنظیم کنید و فعال کردن افزونه AndroidXR را انتخاب کنید.

    گزینه‌ها را در

  4. در بخش ویژگی‌های Android XR، استفاده از ویژگی‌های آزمایشی را انتخاب کنید.

افزودن اجازه‌های درک صحنه برای قفل کردن کف

ایجاد و ارائه محفظه فضایی پایه به اجازه‌های زمان اجرای خطرناک نیاز ندارد (و وقتی استفاده از ویژگی‌های آزمایشی فعال باشد، android.permission.HEAD_TRACKING به‌طور خودکار به مانیفست اضافه می‌شود). بااین‌حال، اگر برنامه‌تان از ویژگی‌های درک صحنه مانند قفل کردن و لنگر انداختن محفظه فضایی به کف فیزیکی استفاده می‌کند، برنامه‌تان باید اجازه android.permission.SCENE_UNDERSTANDING_COARSE را در زمان اجرا اعلام و درخواست کند.

برای جزئیات مربوط به اجازه‌های Android XR، به آشنایی با اجازه‌ها برای XR مراجعه کنید. اگر برنامه‌تان از قفل کردن کف یا درک صحنه استفاده می‌کند، android.permission.SCENE_UNDERSTANDING_COARSE را اعلام و درخواست کنید:

  1. در پروژه > صادر کردن... > Android، به اجازه‌ها > اجازه‌های سفارشی بروید و android.permission.SCENE_UNDERSTANDING_COARSE را اضافه کنید.

  2. وقتی درخواست خودکار اجازه‌های زمان اجرا را در تنظیمات پروژه > عمومی > XR >‏ OpenXR > افزونه‌ها انتخاب می‌کنید، برنامه‌تان به‌طور خودکار هنگام شروع OpenXR اجازه را درخواست می‌کند. اگر لازم است به‌جای آن، اجازه را به‌صورت دستی در GDScript درخواست کنید، با OS.request_permission() تماس بگیرید:

    if not OS.get_granted_permissions().has("android.permission.SCENE_UNDERSTANDING_COARSE"):
        OS.request_permission("android.permission.SCENE_UNDERSTANDING_COARSE")
    

پیکربندی «حالت کل فضا»

«محفظه‌های فضایی» در Android XR فقط از «حالت فضای کامل» (XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED) پشتیبانی می‌کنند. مطمئن شوید فعالیت Android شما XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED را در الگوی ساخت سفارشی‌تان (android/build/AndroidManifest.xml، نصب‌شده بااستفاده از پروژه > نصب الگوی ساخت Android…) اعلام می‌کند:

<manifest ...>
    <application ...>
        <property
            android:name="android.window.PROPERTY_XR_ACTIVITY_START_MODE"
            android:value="XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED"
            tools:replace="android:value" />
        ...
    </application>
</manifest>

کار کردن با محفظه‌های فضایی در GDScript

OpenXRSpatialContainerExtension singleton و کلاس OpenXRSpatialContainerState افزونه‌های XR_EXT_spatial_container و XR_EXT_spatial_container_self_rendering را درمعرض GDScript قرار می‌دهند. در زمان اجرا، از OpenXRSpatialContainerExtension برای بررسی وضعیت و حدود محفظه فضایی اصلی، گوش دادن به سیگنال‌های محفظه، و درخواست انتقال بین حالت BOUNDED (جعبه مرزی سه‌بعدی) و حالت IMMERSIVE (نمای تمام‌صفحه بدون مرز) استفاده کنید.

اتصال به سیگنال‌های Spatial Container

OpenXRSpatialContainerExtension.is_enabled() را بررسی کنید تا مطمئن شوید افزونه Spatial Container در دستگاه فعلی پشتیبانی و فعال است، و به مرزهای محفظه و سیگنال‌های وضعیت در _ready() متصل شوید.

OpenXRSpatialContainerExtension سیگنال‌های وضعیت زیر را برای محفظه فضایی منتشر می‌کند:

  • spatial_container_visibility_changed: با (spatial_container, is_visible) وقتی محفظه نشان داده می‌شود (true) یا پنهان می‌شود (false) منتشر می‌شود. وقتی is_visible false است، پویانمایی‌ها، صدا، یا به‌روزرسانی‌های شبیه‌سازی را موقتاً متوقف کنید.
  • ‫spatial_container_interactability_changed: با (spatial_container, is_interactive) وقتی محفظه تمرکز ورودی کاربر را به‌دست می‌آورد (true) یا ازدست می‌دهد (false) منتشر می‌شود. فعال یا غیرفعال کردن برجسته‌سازی‌های تعاملی و مدیریت ورودی هنگام تغییر تمرکز.
  • spatial_container_bounds_mode_changed: با (spatial_container, bounds_mode) زمانی که محفظه بین OpenXRSpatialContainerState.BOUNDED و OpenXRSpatialContainerState.IMMERSIVE جابه‌جا می‌شود، منتشر می‌شود. عناصر دیداری محیط (مانند اسکای‌باکس یا گذرگاه) و کنترل‌های میانای کاربر مختص حالت را روشن/خاموش کنید.
func _ready() -> void:
    if OpenXRSpatialContainerExtension.is_enabled():
        OpenXRSpatialContainerExtension.spatial_container_bounds_changed.connect(
            _on_bounds_changed
        )
        OpenXRSpatialContainerExtension.spatial_container_bounds_mode_changed.connect(
            _on_bounds_mode_changed
        )
        OpenXRSpatialContainerExtension.spatial_container_visibility_changed.connect(
            _on_visibility_changed
        )
        OpenXRSpatialContainerExtension.spatial_container_interactability_changed.connect(
            _on_interactability_changed
        )

func _on_visibility_changed(_rid: RID, is_visible: bool) -> void:
    # Pause or resume simulation and audio based on visibility
    pass

func _on_interactability_changed(_rid: RID, is_interactive: bool) -> void:
    # Enable or disable input handling and focus highlights
    pass

مقیاس‌بندی محتوای سه‌بعدی به مرزهای ظرف

وقتی در حالت BOUNDED هستید، محتوای سه‌بعدی‌تان را به‌طور یکنواخت با کوچک‌ترین بعد bounds مقیاس‌بندی کنید تا نسبت ابعادی آن حفظ شود و همیشه در کوچک‌ترین طرف ظرف جا شود. هنگام انتقال به حالت IMMERSIVE، صحنه را به مقیاس ۱:۱ بازیابی کنید:

func _on_bounds_changed(_rid: RID, bounds: Vector3) -> void:
    var uniform_scale: float = min(bounds.x, bounds.y, bounds.z)
    content_root.scale = Vector3.ONE * uniform_scale

func _on_bounds_mode_changed(
    _rid: RID, bounds_mode: OpenXRSpatialContainerState.BoundsMode
) -> void:
    if bounds_mode == OpenXRSpatialContainerState.IMMERSIVE:
        content_root.scale = Vector3.ONE

جابه‌جایی بین حالت‌های محدود و فراگیر

request_main_spatial_container_bounds_mode را با OpenXRSpatialContainerState.BOUNDED یا OpenXRSpatialContainerState.IMMERSIVE فراخوانی کنید تا بین حجم سه‌بعدی محدودشده و نمای فراگیر تمام‌صفحه جابه‌جا شوید:

# Request transitioning to immersive mode (or pass BOUNDED to return)
OpenXRSpatialContainerExtension.request_main_spatial_container_bounds_mode(
    OpenXRSpatialContainerState.IMMERSIVE
)

همچنین مراجعه کنید به


‫OpenXR™‎ و نشان‌واره OpenXR علامت‌های تجاری متعلق به The Khronos Group Inc. ‎ هستند و به‌عنوان علامت تجاری در چین، اتحادیه اروپا، ژاپن، و پادشاهی متحد (UK) ثبت شده‌اند.