KINDNICK_URP/Assets/Scripts/iFacialMocap/UnityRecieve_FACEMOTION3D_and_iFacialMocap.cs
2025-04-25 21:14:54 +09:00

282 lines
6.5 KiB
C#

using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Collections.Generic;
using System;
using System.Collections;
using System.Globalization;
public class UnityRecieve_FACEMOTION3D_and_iFacialMocap : MonoBehaviour
{
[Header("Connection Settings")]
public bool gameStartWithConnect = true;
public string iOS_IPAddress = "255.255.255.255";
public int LOCAL_PORT = 49983;
[Header("Target Objects")]
public List<SkinnedMeshRenderer> meshTargetList;
public List<GameObject> headObjectArray;
public List<GameObject> rightEyeObjectArray;
public List<GameObject> leftEyeObjectArray;
public List<GameObject> headPositionObjectArray;
private UdpClient client;
private bool StartFlag = true;
private UdpClient udp;
private Thread thread;
private string messageString = "";
private bool isReconnecting = false;
private bool isConnected = false;
void Start()
{
if (!string.IsNullOrEmpty(iOS_IPAddress) && LOCAL_PORT != 0)
{
StartConnection();
}
}
void StartConnection()
{
Debug.Log("연결 시작 중...");
if (StartFlag)
{
StartFlag = false;
isConnected = true;
if (gameStartWithConnect)
{
Connect_to_iOS_App();
}
CreateUdpServer();
}
}
void CreateUdpServer()
{
try
{
if (LOCAL_PORT <= 0 || LOCAL_PORT > 65535)
{
throw new ArgumentException("유효하지 않은 포트 번호입니다.");
}
udp = new UdpClient(LOCAL_PORT);
udp.Client.ReceiveTimeout = 5000;
thread = new Thread(new ThreadStart(ThreadMethod));
thread.IsBackground = true;
thread.Start();
Debug.Log("UDP 서버 생성 완료");
}
catch (Exception e)
{
Debug.LogError($"UDP 서버 생성 실패: {e.Message}");
isConnected = false;
}
}
void Connect_to_iOS_App()
{
SendMessage_to_iOSapp("iFacialMocap_sahuasouryya9218sauhuiayeta91555dy3719", 49983);
SendMessage_to_iOSapp("FACEMOTION3D_OtherStreaming", 49993);
}
void StopStreaming_iOS_App()
{
SendMessage_to_iOSapp("StopStreaming_FACEMOTION3D", 49993);
}
void SendMessage_to_iOSapp(string sendMessage, int send_port)
{
try
{
client = new UdpClient();
client.Connect(iOS_IPAddress, send_port);
byte[] dgram = Encoding.UTF8.GetBytes(sendMessage);
client.Send(dgram, dgram.Length);
client.Send(dgram, dgram.Length);
client.Send(dgram, dgram.Length);
client.Send(dgram, dgram.Length);
client.Send(dgram, dgram.Length);
}
catch { }
}
void Update()
{
try
{
SetAnimation_inside_Unity_settings();
}
catch
{ }
}
void SetBlendShapeWeightFromStrArray(string[] strArray2)
{
string mappedShapeName = strArray2[0].Replace("_R", "Right").Replace("_L", "Left");
float weight = float.Parse(strArray2[1], CultureInfo.InvariantCulture);
foreach (SkinnedMeshRenderer meshTarget in meshTargetList)
{
var shared_mesh = meshTarget.sharedMesh;
int index = shared_mesh.GetBlendShapeIndex(mappedShapeName);
if (index > -1)
{
meshTarget.SetBlendShapeWeight(index, weight);
}
}
}
void SetAnimation_inside_Unity_settings()
{
try
{
string[] strArray1 = messageString.Split('=');
if (strArray1.Length >= 2)
{
foreach (string message in strArray1[0].Split('|'))
{
string[] strArray2 = new string[3];
if (message.Contains("&"))
{
strArray2 = message.Split('&');
}
else
{
strArray2 = message.Split('-');
}
if (strArray2.Length == 2)
{
SetBlendShapeWeightFromStrArray(strArray2);
}
}
foreach (string message in strArray1[1].Split('|'))
{
string[] strArray2 = message.Split('#');
if (strArray2.Length == 2)
{
string[] commaList = strArray2[1].Split(',');
if (strArray2[0] == "head")
{
foreach (GameObject headObject in headObjectArray)
{
headObject.transform.localRotation = Quaternion.Euler(float.Parse(commaList[0], CultureInfo.InvariantCulture), -float.Parse(commaList[1], CultureInfo.InvariantCulture), -float.Parse(commaList[2], CultureInfo.InvariantCulture));
}
foreach (GameObject headPositionObject in headPositionObjectArray)
{
headPositionObject.transform.localPosition = new Vector3(-float.Parse(commaList[3], CultureInfo.InvariantCulture), float.Parse(commaList[4], CultureInfo.InvariantCulture), float.Parse(commaList[5], CultureInfo.InvariantCulture));
}
}
else if (strArray2[0] == "rightEye")
{
foreach (GameObject rightEyeObject in rightEyeObjectArray)
{
rightEyeObject.transform.localRotation = Quaternion.Euler(float.Parse(commaList[0], CultureInfo.InvariantCulture), -float.Parse(commaList[1], CultureInfo.InvariantCulture), float.Parse(commaList[2], CultureInfo.InvariantCulture));
}
}
else if (strArray2[0] == "leftEye")
{
foreach (GameObject leftEyeObject in leftEyeObjectArray)
{
leftEyeObject.transform.localRotation = Quaternion.Euler(float.Parse(commaList[0], CultureInfo.InvariantCulture), -float.Parse(commaList[1], CultureInfo.InvariantCulture), float.Parse(commaList[2], CultureInfo.InvariantCulture));
}
}
}
}
}
}
catch
{
}
}
void ThreadMethod()
{
while (isConnected)
{
try
{
IPEndPoint remoteEP = null;
byte[] data = udp.Receive(ref remoteEP);
messageString = Encoding.ASCII.GetString(data);
}
catch (SocketException)
{
}
catch (ThreadAbortException)
{
break;
}
catch (Exception e)
{
Debug.LogError($"데이터 수신 중 오류 발생: {e.Message}");
}
Thread.Sleep(5);
}
}
void OnApplicationQuit()
{
if (StartFlag == false)
{
StartFlag = true;
StopUDP();
}
}
public void StopUDP()
{
if (gameStartWithConnect == true)
{
StopStreaming_iOS_App();
}
if (udp != null)
{
udp.Dispose();
udp = null;
}
if (thread != null && thread.IsAlive)
{
thread.Abort();
thread = null;
}
}
}
public static class FM3D_and_iFacialMocap_GetAllChildren
{
public static List<GameObject> GetAll(this GameObject obj)
{
List<GameObject> allChildren = new List<GameObject>();
allChildren.Add(obj);
GetChildren(obj, ref allChildren);
return allChildren;
}
public static void GetChildren(GameObject obj, ref List<GameObject> allChildren)
{
Transform children = obj.GetComponentInChildren<Transform>();
if (children.childCount == 0)
{
return;
}
foreach (Transform ob in children)
{
allChildren.Add(ob.gameObject);
GetChildren(ob.gameObject, ref allChildren);
}
}
}