- 모든 컨트롤러 에디터를 IMGUI → UI Toolkit(UXML/USS)으로 전환 (Camera, Item, Event, Avatar, System, StreamDeck, OptiTrack, Facial) - StreamingleCommon.uss 공통 테마 + 개별 에디터 USS 스타일시트 - SystemController 서브매니저 분리 (OptiTrack, Facial, Recording, Screenshot 등) - 런타임 컨트롤 패널 (ESC 토글, 좌측 오버레이, 150% 스케일) - 웹 대시보드 서버 (StreamingleDashboardServer) + 리타게팅 통합 - 설정 도구(StreamingleControllerSetupTool) UXML 재작성 + 원클릭 설정 - SimplePoseTransfer UXML 에디터 추가 - 전체 UXML 한글화 + NanumGothic 폰트 적용 - Streamingle.Debug → Streamingle.Debugging 네임스페이스 변경 (Debug.Log 충돌 해결) - 불필요 코드 제거 (rawkey.cs, RetargetingHTTPServer, OptitrackSkeletonAnimator 등) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
82 lines
2.5 KiB
C#
82 lines
2.5 KiB
C#
using UnityEngine;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
/// <summary>
|
|
/// iFacialMocap/Rokoko 페이셜 모션캡처 관리
|
|
/// </summary>
|
|
[Serializable]
|
|
public class FacialMotionManager
|
|
{
|
|
[Tooltip("true면 씬의 모든 페이셜 모션 클라이언트를 자동으로 찾습니다")]
|
|
public bool autoFindFacialMotionClients = true;
|
|
|
|
[Tooltip("수동으로 지정할 페이셜 모션 클라이언트 목록 (autoFindFacialMotionClients가 false일 때 사용)")]
|
|
public List<StreamingleFacialReceiver> facialMotionClients = new List<StreamingleFacialReceiver>();
|
|
|
|
private Action<string> log;
|
|
private Action<string> logError;
|
|
|
|
public void Initialize(Action<string> log, Action<string> logError)
|
|
{
|
|
this.log = log;
|
|
this.logError = logError;
|
|
|
|
if (autoFindFacialMotionClients)
|
|
{
|
|
RefreshFacialMotionClients();
|
|
}
|
|
}
|
|
|
|
public void RefreshFacialMotionClients()
|
|
{
|
|
var allClients = UnityEngine.Object.FindObjectsOfType<StreamingleFacialReceiver>();
|
|
facialMotionClients = allClients.ToList();
|
|
log?.Invoke($"Facial Motion 클라이언트 {facialMotionClients.Count}개 발견");
|
|
}
|
|
|
|
public void ReconnectFacialMotion()
|
|
{
|
|
if (autoFindFacialMotionClients)
|
|
{
|
|
RefreshFacialMotionClients();
|
|
}
|
|
|
|
if (facialMotionClients == null || facialMotionClients.Count == 0)
|
|
{
|
|
logError?.Invoke("Facial Motion 클라이언트가 없습니다!");
|
|
return;
|
|
}
|
|
|
|
log?.Invoke($"Facial Motion 클라이언트 재접속 시도... ({facialMotionClients.Count}개)");
|
|
|
|
int reconnectedCount = 0;
|
|
foreach (var client in facialMotionClients)
|
|
{
|
|
if (client != null)
|
|
{
|
|
try
|
|
{
|
|
client.Reconnect();
|
|
reconnectedCount++;
|
|
log?.Invoke($"클라이언트 재접속 성공: {client.gameObject.name}");
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
logError?.Invoke($"클라이언트 재접속 실패 ({client.gameObject.name}): {e.Message}");
|
|
}
|
|
}
|
|
}
|
|
|
|
if (reconnectedCount > 0)
|
|
{
|
|
log?.Invoke($"=== Facial Motion 재접속 완료 ({reconnectedCount}/{facialMotionClients.Count}개) ===");
|
|
}
|
|
else
|
|
{
|
|
logError?.Invoke("재접속에 성공한 클라이언트가 없습니다!");
|
|
}
|
|
}
|
|
}
|