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

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

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

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

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

به‌روزرسانی گودو و افزونه‌ی فروشندگان گودو OpenXR

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

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

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

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

    فعال کردن

    1. در بخش ویژگی‌های XR ، برای حالت XR ، OpenXR را انتخاب کنید و سپس Enable AndroidXR Plugin را انتخاب کنید.

    گزینه‌ها را در قسمت پیکربندی کنید

اضافه شدن پشتیبانی برای ردیابی دست

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

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

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

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

    گزینه‌ها را در قسمت پیکربندی کنید

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

    گزینه‌ها را در قسمت پیکربندی کنید

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

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

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

    1. نام یکی را «HandTrackingLeft» بگذارید و ویژگی tracker را روی /user/hand_tracker/left تنظیم کنید.
    2. نام یک شیء دیگر را «HandTrackingRight» بگذارید و ویژگی ردیاب را روی /user/hand_tracker/right تنظیم کنید.
    3. نام آخرین مورد را «HandTrackingAimLeft» قرار دهید و ویژگی tracker را روی /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. ویژگی Show When Tracked را روی گره‌های کنترلر ردیابی دست فعال کنید.

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

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

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

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

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

در مرحله بعد، نمایه تعامل دست (Hand Interaction) را در نقشه اکشن OpenXR تنظیم خواهید کرد:

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

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

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

در نهایت، می‌توانید یک ژست منو برای اندروید 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
    

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

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

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

در اندروید 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 بزرگتر یا کوچکتر از آستانه‌های خاص در سیگنال‌های input_float_changed XRController3D است یا خیر.
  • یک اکشن مجازی به نام pinch_pressed ایجاد می‌کند.

از توابع XR Tools به همراه ردیابی دست استفاده کنید

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

برای مثال، هنگام استفاده از FunctionPointer برای تعاملات منو، ویژگی active_button_action را بر اساس سیگنال tracking_changed گره‌های XRController3D برای ردیابی دست، به اکشن hand-tracking به‌روزرسانی کنید (این گره‌ها در مراحل قبلی راه‌اندازی ردیابی دست ، 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

نکات کلیدی در مورد کد

استفاده از ردیابی دست به همراه حرکت مصنوعی

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

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

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

  • یک صحنه XRVirtualThumbstick هنگام تشخیص پینچ (فشار دادن انگشت روی شیء) نمونه‌سازی می‌شود.
  • در حالی که پینچ نگه داشته می‌شود، فاصله و جهت نسبی از محل اصلی پینچ به یک Vector2 تبدیل شده و عملاً به ورودی معمولی تامب‌استیک نگاشت می‌شود.
  • بازخورد بصری این ورودی نیز به شکل دو شبکه چهارتاییِ بیلبوردی به بازیکن داده می‌شود که موقعیت شستی را نشان می‌دهد.

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

پشتیبانی از گذرگاه را اضافه کنید

شما می‌توانید پشتیبانی از گذرگاه (passthrough) را به برنامه خود اضافه کنید تا کاربران بتوانند محیط واقعی اطراف خود را ببینند.

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

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

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

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

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

    گزینه‌ها را در قسمت پیکربندی کنید

  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 باید به صورت دستی بازیابی شود.
  • برای مشاهده‌ی یک مثال کامل از یک پروژه با استفاده از passthrough و Light Estimation، به Expedition to Blobotopia در GitLab مراجعه کنید.