افزودن پشتیبانی از Android XR به پروژه Godot XR موجود

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

اگر پروژه XR موجودی در Godot دارید، می‌توانید پشتیبانی از Android XR را بدون شروع پروژه جدید و جداگانه اضافه کنید. برخی‌از مراحل برای همه پروژه‌ها الزامی است، درحالی‌که برخی دیگر بسته به ویژگی‌های واقعیت گسترده‌ای که پروژه شما استفاده می‌کند اختیاری است. درطول مراحل، پیوندهایی به چندین پروژه Godot XR منبع‌باز که پشتیبانی از Android XR را اضافه کرده‌اند، به‌همراه درخواست‌های واکشی مربوطه که تغییرات لازم برای فعال کردن برخی ویژگی‌ها را نشان می‌دهند، گنجانده‌ایم.

مراحل لازم برای همه پروژه‌ها

مراحل موضوعات زیر را تکمیل کنید، صرف‌نظر از اینکه پروژه شما از چه نوع ویژگی‌های «واقعیت گسترده» پشتیبانی می‌کند. سپس، ویژگی‌های ذکرشده در فهرست مراحل اختیاری را مرور کنید تا مشخص شود که آیا پروژه شما به کار بیشتری نیاز دارد یا نه.

به‌روزرسانی Godot و افزایه Godot OpenXR Vendors

این مراحل را دنبال کنید تا پروژه‌تان را به جدیدترین نسخه‌های لازم به‌روز کنید و تنظیمات پروژه‌تان را برای Android XR پیکربندی کنید:

  1. نسخه Godot را به ۴.۶.۲ یا بالاتر به‌روز کنید. اگر برای پروژه‌تان به راهنمایی بیشتری نیاز دارید، به مستندات مربوط به انتقال به نسخه جدید مراجعه کنید.
  2. نسخه ۵.۱ یا بالاتر Godot OpenXR Vendors Plugin را از Asset Store، Asset Library، یا مخزن GitHub بارگیری کنید.

  3. تنظیمات پروژه را برای Android XR پیکربندی کنید:

    1. پیش‌تنظیم صادر کردن را برای Android XR اضافه کنید.
    2. استفاده از Gradle Build را فعال کنید.

    فعال کردن

    1. در بخش ویژگی‌های XR،‏ OpenXR را برای حالت XR انتخاب کنید، و فعال کردن افزونه AndroidXR را انتخاب کنید.

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

افزودن پشتیبانی برای ردیابی دست

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

افزودن پشتیبانی از ردیابی دست: پیکربندی تنظیمات پروژه

ابتدا، این مراحل را دنبال کنید تا تنظیمات پروژه‌تان را برای فعال کردن ردیابی دست و افزونه‌های OpenXR مربوط به آن راه‌اندازی کنید.

  1. تنظیمات پروژه را باز کنید و به General > XR > OpenXR بروید.
  2. در بخش افزونه‌ها، ردیابی دست و نمایه تعامل دست را انتخاب کنید.

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

  3. زیربخش Meta را در بخش افزونه‌ها پیدا کنید و Hand Tracking Mesh و Hand Tracking Aim را انتخاب کنید.

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

افزودن پشتیبانی برای ردیابی دست: افزودن و پیکربندی گره‌های کنترل‌کننده

به‌جای اصلاح پویای گره‌های XRController3D موجود برای ردگیری دست، گره‌های کنترل‌کننده را برای ردگیری و نمایش مدل‌های دست و همچنین مدیریت ورودی از افزونه Hand Tracking Aim اضافه کنید:

  1. سه گره XRController3D دیگر به گره XROrigin3D اضافه کنید.

    1. یکی را «HandTrackingLeft» نام‌گذاری کنید و ویژگی ردیاب را روی /user/hand_tracker/left تنظیم کنید.
    2. نام دیگری را «HandTrackingRight» بگذارید و ویژگی ردیاب را روی /user/hand_tracker/right تنظیم کنید.
    3. نام آخرین مورد را «HandTrackingAimLeft» بگذارید و ویژگی ردیاب را روی /user/fbhandaim/left تنظیم کنید.

    اگر گره‌های XRController3D اصلی پروژه‌تان «XRController3D_left» و «XRController3D_right» نام‌گذاری شده باشند، صحنه شما چیزی شبیه به این خواهد بود:

    صحنه شما پس‌از افزودن گره‌های کنترل‌کننده ممکن است این‌گونه به‌نظر برسد.

  2. سیگنال tracking_changed را در HandTrackingLeft و HandTrackingRight به توابع جداگانه‌ای که قابلیت مشاهده ردیاب‌های کنترل‌کننده مربوطه را به‌روزرسانی می‌کنند (XRController3D_left و XRController3D_right در مثال قبلی) متصل کنید.

    برای مثال، تابع متصل به سیگنال در HandTrackingLeft می‌تواند به‌صورت زیر باشد:

    func _on_hand_tracking_left_hand_tracking_changed(tracking):
        $XROrigin3D/XRController3D_left.visible = not tracking
    
  3. ویژگی نمایش هنگام ردیابی را در گره‌های کنترل‌کننده ردیابی دست فعال کنید.

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

  4. چند گره OpenXRFbHandTrackingMesh را به‌عنوان گره‌های فرزند به گره‌های کنترل‌کننده ردیابی دست اضافه کنید.

  5. گره‌های XRHandModifier3D را به‌عنوان فرزند به این گره‌های OpenXRFbHandTrackingMesh اضافه کنید و مطمئن شوید که ویژگی ردیاب دست صحیح تنظیم شده است تا داده‌های ردیابی دست هم‌زمان روی مدل‌ها اعمال شود.

    صحنه شما ممکن است پس‌از افزودن گره‌های فرزند به گره‌های کنترل‌کننده این‌گونه به‌نظر برسد.

افزودن پشتیبانی برای ردگیری دست: راه‌اندازی نمایه «تعامل دست» در OpenXR Action Map

سپس، نمایه تعامل با دست را در نقشه کنش OpenXR راه‌اندازی خواهید کرد:

  1. منو OpenXR Action Map را در پایین ویرایشگر باز کنید.
  2. نمایه کنترل‌کننده ساده را حذف کنید تا از مشکلات سازگاری با کنترل‌کننده‌های Galaxy XR جلوگیری شود.
  3. روی افزودن نمایه کلیک کنید، تعامل با دست را انتخاب کنید، و سپس روی تأیید کلیک کنید.
  4. این نمایه را به هر شکلی که می‌خواهید به یک یا چند مجموعه کنش نگاشت کنید.

بسته به الزامات برنامه‌تان، ممکن است بخواهید نحوه مدیریت ورودی کاربر توسط برنامه با ردگیری دست را نیز تنظیم کنید.

افزودن پشتیبانی برای ردیابی دست: راه‌اندازی اشاره منو برای Android XR

درنهایت، می‌توانید اشاره منو را برای Android XR پیاده‌سازی کنید. این کد نمادی را نشان می‌دهد وقتی که دست چپ بازیکن در موقعیت صحیح برای انجام اشاره منو قرار دارد، و همچنین منو را وقتی که کاربر اشاره را انجام می‌دهد نشان می‌دهد یا پنهان می‌کند. برای انجام این کار، از گره HandTrackingAimLeft که قبلاً اضافه کرده‌اید استفاده خواهید کرد.

  1. یک چهارضلعی بیلبوردی به گره ردیابی دست چپ اضافه کنید که نمادی را که انتخاب کرده‌اید نمایش دهد (گره MenuIcon را در تصویر زیر از گره‌های کنترل‌کننده‌ای که قبلاً اضافه کرده‌اید ببینید).

    صحنه شما ممکن است پس‌از افزودن گره‌های فرزند به گره‌های کنترل‌کننده این‌گونه به‌نظر برسد.

  2. به سیگنال‌های button_pressed و button_released در HandTrackingAimLeft به توابعی مثل این متصل شوید:

    @onready var menu_icon: MeshInstance3D = $XROrigin3D/HandTrackingLeft/MenuIcon
    
    func _on_hand_tracking_aim_left_button_pressed(p_name):
      if p_name == "menu_pressed":
    toggle_menu()
      elif p_name == "menu_gesture":
        if OS.has_feature("androidxr"):
          menu_icon.visible = true
    
    func _on_hand_tracking_aim_left_button_released(p_name):
      if p_name == "menu_gesture":
        menu_icon.visible = false
    

مراحل اختیاری برای برخی‌از ویژگی‌ها

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

ثبت کردن نیشگون به‌عنوان فشار دادن دکمه

در Android XR، از نیشگون گرفتن برای بسیاری از کنش‌های بنیادی سیستم استفاده می‌شود، مانند انتخاب کردن موارد، پیمایش، جابه‌جا کردن یا تغییر اندازه پنجره‌ها، و جابه‌جا کردن عناصر میانای کاربر یا اشیاء در فضای دوبعدی و سه‌بعدی. برای هم‌راستا شدن با این الگوها و ترویج تجربه کاربری یکسان، برنامه‌تان باید نیشگون گرفتن را مشابه فشار دادن دکمه در کنترل‌کننده هنگام استفاده از ردیابی دست ثبت کند.

برای پیکربندی برنامه‌تان به این روش، از مقادیر اعشاری ارائه‌شده توسط نمایه «تعامل با دست» که ایجاد کرده‌اید برای ایجاد کنش مجازی استفاده کنید:

const PRESSED_THRESHOLD := 0.8
const RELEASED_THRESHOLD := 0.6

@onready var left_controller: XRController3D = $XROrigin/XRController3D_left

func _on_xr_controller_3d_left_input_float_changed(p_name: String, value: float):
    if p_name == "pinch":
        var xr_tracker = XRServer.get_tracker(left_controller.tracker)
        if _left_hand_pinching:
            if value < RELEASED_THRESHOLD:
                _left_hand_pinching = false
                xr_tracker.set_input("pinch_pressed", false)
        else:
            if value > PRESSED_THRESHOLD:
                _left_hand_pinching = true
                xr_tracker.set_input("pinch_pressed", true)

نکات کلیدی درباره کد

  • بررسی می‌کند که آیا مقدار float بیشتر یا کمتر از آستانه‌های خاص در سیگنال‌های XRController3D input_float_changed است یا نه.
  • کنش مجازی‌ای به‌نام pinch_pressed ایجاد می‌کند.

استفاده کردن از عملکردهای «ابزارهای واقعیت گسترده» همراه با ردیابی دست

بسیاری از پروژه‌های Godot XR از Godot XR Tools استفاده می‌کنند، ازجمله برخی از پروژه‌های متن‌باز که در این صفحه پیوند داده شده‌اند. برای اینکه برخی‌از عملکردهای XR Tools کار کند، مثل FunctionPointer برای تعاملات منو، به کد اضافی نیاز دارید تا کنشی را که به‌دنبال آن است وقتی کاربر به ردیابی دست تغییر می‌دهد عوض کند.

برای مثال، هنگام استفاده از FunctionPointer برای تعاملات منو، ویژگی active_button_action را به کنش ردیابی دست براساس سیگنال tracking_changed گره‌های XRController3D برای ردیابی دست به‌روز کنید (این گره‌ها در مراحل راه‌اندازی ردیابی دست قبلی، HandTrackingLeft و HandTrackingRight بودند).

const TRIGGER_POINTER_ACTION = "trigger_click"
const PINCH_POINTER_ACTION = "pinch_pressed"

@onready var func_point_left: XRToolsFunctionPointer = %FunctionPointerLeft

func _on_hand_tracking_left_tracking_changed(tracking: bool) -> void:
    if tracking:
        func_point_left.active_button_action = PINCH_POINTER_ACTION
else:
func_point_left.active_button_action = TRIGGER_POINTER_ACTION

نکات کلیدی درباره کد

استفاده از ردیابی دست همراه با جابه‌جایی مصنوعی

اگر پروژه شما از جابه‌جایی مصنوعی استفاده می‌کند، پشتیبانی از ردیابی دست همچنان امکان‌پذیر است. برای مثال، می‌توانید سیستم حرکتی‌ای بسازید که به بازیکنان اجازه می‌دهد با اشاره، مسیرهایی را برای پیمودن ترسیم کنند، یا می‌توانید به بازیکنان اجازه دهید با بالا و پایین بردن دست‌هایشان سرعت بگیرند و با اشاره‌های دیگر بپرند، بالا بروند، و سُر بخورند.

The Museum of All Things دارای حرکت مصنوعی بااستفاده از دسته‌های کنترل‌کننده است. ردیابی دست برای جابه‌جایی با افزودن «شستک‌های مجازی» پیاده‌سازی شد که بازیکن با نیشگون گرفتن در هوا آن‌ها را فعال می‌کند و دستش را در جهتی که می‌خواهد شستک حرکت کند حرکت می‌دهد.

در اینجا برخی‌از نکات کلیدی از درخواست کششی که این پشتیبانی را پیاده‌سازی کرده است آورده شده است:

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

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

افزودن پشتیبانی از عبور مستقیم

می‌توانید پشتیبانی از حالت واقع‌نمایی را به برنامه‌تان اضافه کنید تا کاربران بتوانند محیط واقعی اطرافشان را ببینند.

برای انجام این کار برای برنامه‌تان، تغییرات کد زیر را اعمال کنید:

  • environment_blend_mode مربوط به OpenXR XRInterface را روی XR_ENV_BLEND_MODE_ALPHA_BLEND تنظیم کنید.
  • background_mode گره WorldEnvironment را روی BG_COLOR تنظیم کنید.
  • background_color گره WorldEnvironment را روی هر رنگی که کاملاً شفاف است تنظیم کنید.
  • خصوصیت Viewport transparent_bg را روی true تنظیم کنید.

استفاده از افزونه تخمین نور

هنگام فعال کردن حالت گذار، استفاده از افزونه Android XR Light Estimation OpenXR را درنظر بگیرید. این افزونه ویژگی‌های WorldEnvironment و DirectionalLight3D را تغییر می‌دهد تا نورپردازی محیط واقعی کاربر را بهتر شبیه‌سازی کند، به‌طوری‌که اشیای مجازی بهتر با شرایط نورپردازی دنیای واقعی ترکیب شوند. می‌توانید این افزونه را در تنظیمات پروژه‌تان فعال کنید.

  1. تنظیمات پروژه را باز کنید و به General > XR > OpenXR بروید.
  2. در بخش Androidxr، تخمین نور را انتخاب کنید.

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

  3. گره OpenXRAndroidLightEstimation را به درخت صحنه اضافه کنید و آن را به WorldEnvironment و DirectionalLight3D صحنه متصل کنید.

    گزینه‌های

مثال: فعال یا غیرفعال کردن عبور و تخمین نور

کد زیر حالت شفاف و تخمین نور را فعال یا غیرفعال می‌کند:

@onready var world_environment = $WorldEnvironment
@onready var directional_light = $DirectionalLight3D
@onready var directional_light_orig_transform: Transform3D = directional_light.transform

func set_passthrough_enabled(p_enabled: bool) -> void:
    var xr_interface = XRServer.find_interface("OpenXR")
    if xr_interface == null:
        return

    var supported_blend_modes = xr_interface.get_supported_environment_blend_modes()
    if not supported_blend_modes.has(XRInterface.XR_ENV_BLEND_MODE_ALPHA_BLEND):
        return

    # Passthrough
    if p_enabled:
        xr_interface.set_play_area_mode(XRInterface.XR_PLAY_AREA_STAGE)
        xr_interface.environment_blend_mode = XRInterface.XR_ENV_BLEND_MODE_ALPHA_BLEND
        world_environment.environment.background_mode = Environment.BG_COLOR
        world_environment.environment.background_color = Color(0.0, 0.0, 0.0, 0.0)
        get_viewport().transparent_bg = true
    else:
        xr_interface.set_play_area_mode(XRInterface.XR_PLAY_AREA_ROOMSCALE)
        xr_interface.environment_blend_mode = XRInterface.XR_ENV_BLEND_MODE_OPAQUE
        world_environment.environment.background_mode = Environment.BG_SKY
        get_viewport().transparent_bg = false

    # Light Estimation
    if OS.has_feature("androidxr"):
        var light_estimation = Engine.get_singleton("OpenXRAndroidLightEstimationExtension")
        if p_enabled and light_estimation.is_light_estimation_supported():
            light_estimation.start_light_estimation()
        elif light_estimation.is_light_estimation_started():
            light_estimation.stop_light_estimation()
            directional_light.transform = directional_light_orig_transform
نکات کلیدی درباره کد
  • هنگام غیرفعال کردن تخمین نور، جهت اصلی DirectionalLight3D باید به‌صورت دستی بازیابی شود.
  • برای مشاهده نمونه کاملی از پروژه‌ای که از حالت شفاف و «تخمین نور» استفاده می‌کند، Expedition to Blobotopia را در GitLab بررسی کنید.