using UnityEngine; using System.Collections.Generic; using System; public class OptitrackVisualizer : MonoBehaviour { [Header("OptiTrack 설정")] public OptitrackRawDataReceiver dataReceiver; [Header("시각화 설정")] public bool showGizmos = true; public float gizmoSize = 0.05f; public float handGizmoScale = 0.1f; // 손 기즈모 크기 비율 (1 = 100%) public Color boneColor = Color.red; public bool drawBoneConnections = true; public Color connectionColor = Color.yellow; private OptitrackSkeletonDefinition skeletonDef; private Dictionary boneTransforms = new Dictionary(); private List<(Transform, Transform)> boneConnections = new List<(Transform, Transform)>(); void Start() { if (dataReceiver == null) { dataReceiver = FindFirstObjectByType(); if (dataReceiver == null) { Debug.LogError("OptitrackRawDataReceiver를 찾을 수 없습니다."); return; } } // 스켈레톤 정의 가져오기 skeletonDef = dataReceiver.StreamingClient.GetSkeletonDefinitionByName(dataReceiver.SkeletonAssetName); if (skeletonDef == null) return; // 본 Transform 생성 foreach (var bone in skeletonDef.Bones) { GameObject boneObj = new GameObject(bone.Name); boneTransforms[bone.Id] = boneObj.transform; } // 본 계층 구조 설정 foreach (var bone in skeletonDef.Bones) { Transform boneTransform = boneTransforms[bone.Id]; if (bone.ParentId == 0) { boneTransform.SetParent(transform, false); } else if (boneTransforms.TryGetValue(bone.ParentId, out Transform parentTransform)) { boneTransform.SetParent(parentTransform, false); boneConnections.Add((parentTransform, boneTransform)); } } } void Update() { if (dataReceiver == null || skeletonDef == null) return; // 최신 스켈레톤 상태 가져오기 OptitrackSkeletonState skelState = dataReceiver.StreamingClient.GetLatestSkeletonState(skeletonDef.Id); if (skelState == null) return; // 각 본의 위치와 회전 업데이트 foreach (var bone in skeletonDef.Bones) { if (boneTransforms.TryGetValue(bone.Id, out Transform boneTransform)) { if (skelState.BonePoses.TryGetValue(bone.Id, out OptitrackPose pose)) { boneTransform.localPosition = pose.Position; boneTransform.localRotation = pose.Orientation; } } } } void OnDrawGizmos() { if (!showGizmos || !Application.isPlaying || skeletonDef == null) return; // 본 기즈모 그리기 Gizmos.color = boneColor; foreach (var bone in skeletonDef.Bones) { if (boneTransforms.TryGetValue(bone.Id, out Transform transform)) { float size = gizmoSize; string boneName = bone.Name.ToLower(); // 손과 손가락 기즈모 크기 조절 if (boneName.Contains("hand") || boneName.Contains("thumb") || boneName.Contains("index") || boneName.Contains("middle") || boneName.Contains("ring") || boneName.Contains("pinky")) { size *= handGizmoScale; } Gizmos.DrawWireSphere(transform.position, size); } } // 본 연결선 그리기 if (drawBoneConnections) { Gizmos.color = connectionColor; foreach (var (parent, child) in boneConnections) { Gizmos.DrawLine(parent.position, child.position); } } } }