Godot에 기존 XR 프로젝트가 있는 경우 별도의 새 프로젝트를 시작하지 않고도 Android XR 지원을 추가할 수 있습니다. 일부 단계는 모든 프로젝트에 필요하지만, 다른 단계는 프로젝트에서 사용하는 XR 기능에 따라 선택사항입니다. 이 단계에서는 Android XR 지원이 추가된 여러 오픈소스 Godot XR 프로젝트 링크와 특정 기능을 사용 설정하는 데 필요한 변경사항을 보여주는 관련 풀 요청을 포함했습니다.
모든 프로젝트에 필요한 단계
프로젝트에서 지원하는 XR 기능의 유형과 관계없이 다음 주제의 단계를 완료하세요. 그런 다음 선택 단계 목록에 설명된 기능을 검토하여 프로젝트에 추가 작업이 필요한지 확인합니다.
Godot 및 Godot OpenXR 공급업체 플러그인 업데이트
다음 단계에 따라 프로젝트를 필요한 최신 버전으로 업데이트하고 Android XR용 프로젝트 설정을 구성하세요.
- Godot 버전을 4.6.2 이상으로 업데이트합니다. 프로젝트에 추가 지원이 필요한 경우 새 버전으로 이전에 관한 문서를 참고하세요.
Asset Store, Asset Library 또는 GitHub의 저장소에서 Godot OpenXR Vendors Plugin 버전 5.1 이상을 다운로드합니다.
Android XR용 프로젝트 설정을 구성합니다.
- Android XR용 내보내기 사전 설정을 추가합니다.
- Gradle 빌드 사용을 사용 설정합니다.
- XR Features 섹션에서 XR Mode에 OpenXR을 선택하고 Enable AndroidXR Plugin을 선택합니다.
핸드 트래킹 지원 추가
컨트롤러를 사용할 수 있지만 Android XR 헤드셋과 XR 글라스의 기본 입력 방식은 핸드 트래킹입니다. 가능하다면 Godot 프로젝트에 손 추적 지원을 추가해야 합니다.
핸드 트래킹 지원 추가: 프로젝트 설정 구성
먼저 다음 단계에 따라 프로젝트 설정을 설정하여 손 추적 및 관련 OpenXR 확장 프로그램을 사용 설정합니다.
- 프로젝트 설정을 열고 일반 > XR > OpenXR로 이동합니다.
확장 프로그램 섹션에서 손 추적 및 손 상호작용 프로필을 선택합니다.
확장 프로그램 섹션에서 Meta 하위 섹션을 찾아 손 추적 메시와 손 추적 조준을 선택합니다.
핸드 트래킹 지원 추가: 컨트롤러 노드 추가 및 구성
손 추적을 위해 기존 XRController3D 노드를 동적으로 수정하는 대신 손 모델을 추적하고 표시하며 손 추적 조준 확장 프로그램의 입력을 처리하는 컨트롤러 노드를 추가합니다.
XROrigin3D노드에XRController3D노드 3개를 추가합니다.- 하나의 이름을 'HandTrackingLeft'로 지정하고 트래커 속성을
/user/hand_tracker/left로 설정합니다. - 다른 하나는 'HandTrackingRight'으로 이름을 지정하고 추적기 속성을
/user/hand_tracker/right로 설정합니다. - 마지막은 'HandTrackingAimLeft'로 이름을 지정하고 추적기 속성을
/user/fbhandaim/left로 설정합니다.
프로젝트의 원래
XRController3D노드 이름이 'XRController3D_left' 및 'XRController3D_right'인 경우 장면은 다음과 같이 표시됩니다.
- 하나의 이름을 'HandTrackingLeft'로 지정하고 트래커 속성을
HandTrackingLeft 및 HandTrackingRight의 신호를 연결
tracking_changed하여 해당 컨트롤러 트래커(위 예의 XRController3D_left 및 XRController3D_right)의 표시 상태를 업데이트하는 개별 함수에 연결합니다.예를 들어 HandTrackingLeft의 신호에 연결된 함수는 다음과 같을 수 있습니다.
func _on_hand_tracking_left_hand_tracking_changed(tracking): $XROrigin3D/XRController3D_left.visible = not tracking핸드 트래킹 컨트롤러 노드에서 추적 시 표시 속성을 사용 설정합니다.
이제 사용자가 핸드 트래킹을 사용하는지 컨트롤러를 사용하는지에 따라 컨트롤러 모델과 핸드 트래킹 모델 간에 시각적으로 전환할 수 있습니다.
OpenXRFbHandTrackingMesh노드를 핸드 트래킹 컨트롤러 노드의 하위 요소로 추가합니다.XRHandModifier3D노드를 이러한OpenXRFbHandTrackingMesh노드의 하위 요소로 추가하여 올바른 Hand Tracker 속성이 설정되었는지 확인하여 모델에 실시간 핸드 트래킹 데이터를 적용합니다.
손 추적 지원 추가: OpenXR 작업 맵에서 손 상호작용 프로필 설정
다음으로 OpenXR 작업 맵에서 손 상호작용 프로필을 설정합니다.
- 편집기 하단에서 OpenXR 작업 맵 메뉴를 엽니다.
- Galaxy XR 컨트롤러와의 호환성 문제를 방지하려면 Simple Controller 프로필을 삭제하세요.
- 프로필 추가를 클릭하고 손 상호작용을 선택한 다음 확인을 클릭합니다.
이 프로필을 원하는 대로 하나 이상의 동작 세트에 매핑합니다.
앱의 요구사항에 따라 앱이 핸드 트래킹으로 사용자 입력을 처리하는 방식을 조정할 수도 있습니다.
핸드 트래킹 지원 추가: Android XR의 메뉴 동작 설정
마지막으로 Android XR용 메뉴 동작을 구현할 수 있습니다. 이렇게 하면 플레이어의 왼쪽 손이 메뉴 동작을 수행하기에 적절한 위치에 있을 때 아이콘이 표시되고, 사용자가 동작을 수행할 때 메뉴가 표시되거나 숨겨집니다. 이를 처리하기 위해 앞에서 추가한 HandTrackingAimLeft 노드를 사용합니다.
선택한 아이콘을 표시하는 빌보드 쿼드를 왼쪽 핸드 트래킹 노드에 추가합니다 (이전에 추가한 컨트롤러 노드의 다음 이미지에 있는 MenuIcon 노드 참고).
HandTrackingAimLeft의
button_pressed및button_released신호를 다음과 같은 함수에 연결합니다.@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에서는 기본 시스템 작업에 핀칭이 사용됩니다. 예를 들어 항목 선택, 스크롤, 창 이동 또는 크기 조절, 2D 및 3D 공간에서 UI 요소 또는 객체 이동 등이 있습니다. 이러한 패턴에 맞추고 일관된 사용자 환경을 촉진하려면 핸드 트래킹을 사용할 때 앱이 컨트롤러의 버튼 누름과 유사하게 핀치를 등록해야 합니다.
이 방식으로 앱을 구성하려면 생성한 손 상호작용 프로필에서 제공하는 부동 소수점 값을 사용하여 가상 작업을 만드세요.
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)
코드에 관한 핵심 사항
XRController3Dinput_float_changed신호에서float값이 특정 임곗값보다 크거나 작은지 확인합니다.pinch_pressed이라는 가상 작업을 만듭니다.
핸드 트래킹과 함께 XR 도구 기능 사용
이 페이지에 링크된 일부 오픈소스 프로젝트를 비롯한 많은 Godot XR 프로젝트에서 Godot XR 도구를 활용합니다. 메뉴 상호작용을 위한 FunctionPointer와 같은 일부 XR 도구 기능이 작동하려면 사용자가 핸드 트래킹으로 전환할 때 찾고 있는 작업을 전환하는 추가 코드가 필요합니다.
예를 들어 메뉴 상호작용에 FunctionPointer를 사용하는 경우 XRController3D 노드의 tracking_changed 신호를 기반으로 active_button_action 속성을 핸드 트래킹 작업으로 업데이트합니다 (이러한 노드는 이전 핸드 트래킹 설정 단계에서 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
코드에 관한 핵심 사항
- 이 코드는 핀치를 버튼 누름으로 등록하기 위해 만들 수 있는
pinch_pressed가상 작업을 사용합니다.
핸드 트래킹을 인공 이동과 함께 사용
프로젝트에서 인공 이동을 사용하는 경우에도 핸드 트래킹 지원이 가능합니다. 예를 들어 플레이어가 제스처로 이동 경로를 그려 이동할 수 있는 이동 시스템을 빌드하거나, 플레이어가 손을 위아래로 움직여 가속하고 점프, 등반, 글라이딩을 위한 추가 제스처를 사용할 수 있도록 할 수 있습니다.
The Museum of All Things는 컨트롤러의 스틱을 사용하여 인공 이동을 합니다. 손 추적 이동은 플레이어가 공중에서 손가락을 모아 트리거하고 엄지스틱이 이동하려는 방향으로 손을 움직이는 '가상 엄지스틱'을 추가하여 구현되었습니다.
이 지원을 구현한 풀 요청의 주요 내용은 다음과 같습니다.
- 핀치가 감지되면
XRVirtualThumbstick장면이 인스턴스화됩니다. - 핀치가 유지되는 동안 원래 핀치 위치로부터의 상대 거리와 방향이
Vector2로 변환되고 가상으로 일반 엄지 스틱 입력에 매핑됩니다. - 이 입력에 대한 시각적 피드백도 엄지 스틱 위치를 보여주는 두 개의 빌보드 쿼드 메시 형태로 플레이어에게 제공됩니다.
유사한 접근 방식을 시도하여 기존 엄지 스틱 기반 이동 코드를 최소한의 변경으로 작동시킬 수 있습니다. 하지만 프로젝트에 핸드 트래킹을 위한 맞춤 이동 솔루션이 필요할 수 있습니다.
패스스루 지원 추가
사용자가 실제 주변 환경을 볼 수 있도록 앱에 패스스루 지원을 추가할 수 있습니다.
앱에서 이를 수행하려면 다음 코드를 변경하세요.
- OpenXR
XRInterface의environment_blend_mode을XR_ENV_BLEND_MODE_ALPHA_BLEND로 설정합니다. WorldEnvironment노드의background_mode를BG_COLOR로 설정합니다.WorldEnvironment노드의background_color를 완전히 투명한 색상으로 설정합니다.Viewport transparent_bg속성을true로 설정합니다.
조명 추정 확장 프로그램 사용
패스스루를 사용 설정할 때는 Android XR Light Estimation OpenXR 확장 프로그램을 사용하는 것이 좋습니다. 이 확장 프로그램은 WorldEnvironment 및 DirectionalLight3D의 속성을 조정하여 사용자의 실제 환경의 조명을 더 잘 모방하므로 가상 객체가 실제 조명 조건과 더 잘 어울립니다. 프로젝트 설정에서 이 확장 프로그램을 사용 설정할 수 있습니다.
- 프로젝트 설정을 열고 일반 > XR > OpenXR로 이동합니다.
Androidxr 섹션에서 Light Estimation을 선택합니다.
장면 트리에
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의 원래 방향을 수동으로 복원해야 합니다. - 패스스루와 조명 추정을 사용하는 프로젝트의 전체 예는 GitLab의 Expedition to Blobotopia를 참고하세요.