MediaPipe Unity 플러그인을 설치하고 설정해야 합니다. 설치 및 설정 지침은 Google의 공식 MediaPipe Unity 플러그인 문서를 참조하세요.
다음으로 아바타 모델을 로드하고 모델의 어깨 위치를 결정해야 합니다. 이는 모델의 적절한 위치에서 이 정보를 검색하는 방법에 따라 달라질 수 있습니다.
다음으로 MediaPipe Unity 플러그인에서 제공하는 “Pose Landmark”를 사용하여 어깨 랜드마크를 확인할 수 있습니다. 이를 통해 어깨의 방향을 계산할 수 있습니다.
아래는 샘플 코드입니다.
어깨
using UnityEngine;
using Mediapipe.Unity;
public class AvatarShoulderOrientation : MonoBehaviour
{
(SerializeField) private GameObject avatarModel;
(SerializeField) private PoseLandmarkList landmarkList;
private Vector3 leftShoulderPosition;
private Vector3 rightShoulderPosition;
void Start()
{
// Load the avatar model
// You may need to adjust the position and rotation to fit the model in the scene
Instantiate(avatarModel, Vector3.zero, Quaternion.identity);
// Get the left and right shoulder positions from the avatar model
// These positions may need to be adjusted based on the model's size and orientation
leftShoulderPosition = avatarModel.transform.Find("LeftShoulder").position;
rightShoulderPosition = avatarModel.transform.Find("RightShoulder").position;
// Add a pose landmark list to the scene to detect shoulder landmarks
landmarkList = gameObject.AddComponent<PoseLandmarkList>();
landmarkList.enableDetection = true;
landmarkList.SetLandmarkDetection(RightShoulder);
landmarkList.SetLandmarkDetection(LeftShoulder);
}
void Update()
{
// Get the shoulder landmarks from the PoseLandmarkList
var leftShoulderLandmark = landmarkList.GetLandmark(13); // Left shoulder landmark ID
var rightShoulderLandmark = landmarkList.GetLandmark(14); // Right shoulder landmark ID
// Calculate the shoulder direction based on the landmarks
var leftShoulderDirection = (leftShoulderLandmark.WorldPosition - leftShoulderPosition).normalized;
var rightShoulderDirection = (rightShoulderLandmark.WorldPosition - rightShoulderPosition).normalized;
// Set the avatar's shoulder orientation
avatarModel.transform.Find("LeftShoulder").rotation = Quaternion.LookRotation(leftShoulderDirection, Vector3.up);
avatarModel.transform.Find("RightShoulder").rotation = Quaternion.LookRotation(rightShoulderDirection, Vector3.up);
}
}
위의 코드는 매 프레임마다 PoseLandmarkList를 사용하여 아바타 모델의 어깨 방향을 업데이트하고, 어깨 위치를 확인하고, 방향을 계산하고, 아바타의 어깨 방향을 조정합니다.
고관절
다음 코드는 다음과 같은 작업을 수행합니다.
아바타의 엉덩이 랜드마크를 식별하기 위해 MediaPipe Unity 플러그인의 Pose Landmark Detection 기능을 사용하고 있습니다.
아바타의 고관절 정렬을 계산하고 정렬을 조정합니다.
using UnityEngine;
using Mediapipe.Unity;
public class AvatarHipJointOrientation : MonoBehaviour
{
(SerializeField) private GameObject avatarModel;
(SerializeField) private PoseLandmarkList landmarkList;
private Vector3 hipPosition;
void Start()
{
// Load the avatar model
// You may need to adjust the position and rotation to fit the model in the scene
Instantiate(avatarModel, Vector3.zero, Quaternion.identity);
// Get the hip position from the avatar model
// This position may need to be adjusted based on the model's size and orientation
hipPosition = avatarModel.transform.Find("Hip").position;
// Add a pose landmark list to the scene to detect hip landmark
landmarkList = gameObject.AddComponent<PoseLandmarkList>();
landmarkList.enableDetection = true;
landmarkList.SetLandmarkDetection(Hip);
}
void Update()
{
// Get the hip landmark from the PoseLandmarkList
var hipLandmark = landmarkList.GetLandmark(23); // Hip landmark ID
// Calculate the hip direction based on the landmark
var hipDirection = (hipLandmark.WorldPosition - hipPosition).normalized;
// Set the avatar's hip orientation
avatarModel.transform.Find("Hip").rotation = Quaternion.LookRotation(hipDirection, Vector3.up);
}
}
무릎
MediaPipe Unity 플러그인의 Pose Landmark Detection 기능을 사용하여 아바타 무릎의 랜드마크를 식별합니다.
아바타의 무릎 관절의 정렬을 계산하고 정렬을 조정합니다.
using UnityEngine;
using Mediapipe.Unity;
public class AvatarKneeJointOrientation : MonoBehaviour
{
(SerializeField) private GameObject avatarModel;
(SerializeField) private PoseLandmarkList landmarkList;
private Vector3 kneePosition;
void Start()
{
// Load the avatar model
// You may need to adjust the position and rotation to fit the model in the scene
Instantiate(avatarModel, Vector3.zero, Quaternion.identity);
// Get the knee position from the avatar model
// This position may need to be adjusted based on the model's size and orientation
kneePosition = avatarModel.transform.Find("Knee").position;
// Add a pose landmark list to the scene to detect knee landmark
landmarkList = gameObject.AddComponent<PoseLandmarkList>();
landmarkList.enableDetection = true;
landmarkList.SetLandmarkDetection(Knee);
// Reverse the orientation of the model's legs, so that the knee points forward by default
avatarModel.transform.Find("LeftThigh").localRotation *= Quaternion.Euler(180f, 0f, 0f);
avatarModel.transform.Find("RightThigh").localRotation *= Quaternion.Euler(180f, 0f, 0f);
avatarModel.transform.Find("LeftCalf").localRotation *= Quaternion.Euler(180f, 0f, 0f);
avatarModel.transform.Find("RightCalf").localRotation *= Quaternion.Euler(180f, 0f, 0f);
}
void Update()
{
// Get the knee landmark from the PoseLandmarkList
var kneeLandmark = landmarkList.GetLandmark(25); // Left knee landmark ID
// Calculate the knee direction based on the landmark
var kneeDirection = (kneeLandmark.WorldPosition - kneePosition).normalized;
// Set the avatar's left knee orientation
avatarModel.transform.Find("LeftKnee").rotation = Quaternion.LookRotation(kneeDirection, Vector3.up);
// Set the avatar's right knee orientation
avatarModel.transform.Find("RightKnee").rotation = Quaternion.LookRotation(kneeDirection, Vector3.up);
}
}
팔꿈치
저는 MediaPipe Unity 플러그인의 Pose Landmark Detection 기능을 사용하여 아바타의 팔꿈치 랜드마크를 식별하고 있습니다.
아바타의 팔꿈치 관절의 방향을 계산하고 방향을 조정합니다.
using UnityEngine;
using Mediapipe.Unity;
public class AvatarElbowJointOrientation : MonoBehaviour
{
(SerializeField) private GameObject avatarModel;
(SerializeField) private PoseLandmarkList landmarkList;
private Vector3 elbowPosition;
void Start()
{
// Load the avatar model
// You may need to adjust the position and rotation to fit the model in the scene
Instantiate(avatarModel, Vector3.zero, Quaternion.identity);
// Get the elbow position from the avatar model
// This position may need to be adjusted based on the model's size and orientation
elbowPosition = avatarModel.transform.Find("Elbow").position;
// Add a pose landmark list to the scene to detect elbow landmark
landmarkList = gameObject.AddComponent<PoseLandmarkList>();
landmarkList.enableDetection = true;
landmarkList.SetLandmarkDetection(Elbow);
// Reverse the orientation of the model's arms, so that the elbow points forward by default
avatarModel.transform.Find("LeftArm").localRotation *= Quaternion.Euler(180f, 0f, 0f);
avatarModel.transform.Find("RightArm").localRotation *= Quaternion.Euler(180f, 0f, 0f);
avatarModel.transform.Find("LeftForearm").localRotation *= Quaternion.Euler(180f, 0f, 0f);
avatarModel.transform.Find("RightForearm").localRotation *= Quaternion.Euler(180f, 0f, 0f);
}
void Update()
{
// Get the elbow landmark from the PoseLandmarkList
var elbowLandmark = landmarkList.GetLandmark(3); // Left elbow landmark ID
// Calculate the elbow direction based on the landmark
var elbowDirection = (elbowLandmark.WorldPosition - elbowPosition).normalized;
// Set the avatar's left elbow orientation
avatarModel.transform.Find("LeftElbow").rotation = Quaternion.LookRotation(elbowDirection, Vector3.up);
// Set the avatar's right elbow orientation
avatarModel.transform.Find("RightElbow").rotation = Quaternion.LookRotation(elbowDirection, Vector3.up);
}
}
손목
MediaPipe Unity 플러그인의 포즈 랜드마크 감지 기능을 사용하여 아바타의 손목 랜드마크를 식별합니다.
아바타의 손목 방향을 계산하고 방향을 조정합니다.
using UnityEngine;
using Mediapipe.Unity;
public class AvatarWristJointOrientation : MonoBehaviour
{
(SerializeField) private GameObject avatarModel;
(SerializeField) private PoseLandmarkList landmarkList;
private Vector3 wristPosition;
void Start()
{
// Load the avatar model
// You may need to adjust the position and rotation to fit the model in the scene
Instantiate(avatarModel, Vector3.zero, Quaternion.identity);
// Get the wrist position from the avatar model
// This position may need to be adjusted based on the model's size and orientation
wristPosition = avatarModel.transform.Find("Wrist").position;
// Add a pose landmark list to the scene to detect wrist landmark
landmarkList = gameObject.AddComponent<PoseLandmarkList>();
landmarkList.enableDetection = true;
landmarkList.SetLandmarkDetection(Wrist);
// Reverse the orientation of the model's arms, so that the wrist points forward by default
avatarModel.transform.Find("LeftArm").localRotation *= Quaternion.Euler(180f, 0f, 0f);
avatarModel.transform.Find("RightArm").localRotation *= Quaternion.Euler(180f, 0f, 0f);
avatarModel.transform.Find("LeftForearm").localRotation *= Quaternion.Euler(180f, 0f, 0f);
avatarModel.transform.Find("RightForearm").localRotation *= Quaternion.Euler(180f, 0f, 0f);
avatarModel.transform.Find("LeftElbow").localRotation *= Quaternion.Euler(180f, 0f, 0f);
avatarModel.transform.Find("RightElbow").localRotation *= Quaternion.Euler(180f, 0f, 0f);
}
void Update()
{
// Get the wrist landmark from the PoseLandmarkList
var wristLandmark = landmarkList.GetLandmark(15); // Left wrist landmark ID
// Calculate the wrist direction based on the landmark
var wristDirection = (wristLandmark.WorldPosition - wristPosition).normalized;
// Set the avatar's left wrist orientation
avatarModel.transform.Find("LeftHand").rotation = Quaternion.LookRotation(wristDirection, Vector3.up);
// Set the avatar's right wrist orientation
avatarModel.transform.Find("RightHand").rotation = Quaternion.LookRotation(wristDirection, Vector3.up);
}
}
발목
MediaPipe Unity 플러그인의 Pose Landmark Detection 기능을 사용하여 아바타의 발목 랜드마크를 식별합니다.
아바타의 발목 관절 정렬을 계산하고 정렬을 조정합니다.
using UnityEngine;
using Mediapipe.Unity;
public class AvatarAnkleJointOrientation : MonoBehaviour
{
(SerializeField) private GameObject avatarModel;
(SerializeField) private PoseLandmarkList landmarkList;
private Vector3 anklePosition;
void Start()
{
// Load the avatar model
// You may need to adjust the position and rotation to fit the model in the scene
Instantiate(avatarModel, Vector3.zero, Quaternion.identity);
// Get the ankle position from the avatar model
// This position may need to be adjusted based on the model's size and orientation
anklePosition = avatarModel.transform.Find("Ankle").position;
// Add a pose landmark list to the scene to detect ankle landmark
landmarkList = gameObject.AddComponent<PoseLandmarkList>();
landmarkList.enableDetection = true;
landmarkList.SetLandmarkDetection(Ankle);
// Reverse the orientation of the model's legs, so that the ankle points forward by default
avatarModel.transform.Find("LeftUpLeg").localRotation *= Quaternion.Euler(180f, 0f, 0f);
avatarModel.transform.Find("RightUpLeg").localRotation *= Quaternion.Euler(180f, 0f, 0f);
avatarModel.transform.Find("LeftLeg").localRotation *= Quaternion.Euler(180f, 0f, 0f);
avatarModel.transform.Find("RightLeg").localRotation *= Quaternion.Euler(180f, 0f, 0f);
avatarModel.transform.Find("LeftFoot").localRotation *= Quaternion.Euler(180f, 0f, 0f);
avatarModel.transform.Find("RightFoot").localRotation *= Quaternion.Euler(180f, 0f, 0f);
avatarModel.transform.Find("LeftToeBase").localRotation *= Quaternion.Euler(180f, 0f, 0f);
avatarModel.transform.Find("RightToeBase").localRotation *= Quaternion.Euler(180f, 0f, 0f);
}
void Update()
{
// Get the ankle landmark from the PoseLandmarkList
var ankleLandmark = landmarkList.GetLandmark(16); // Left ankle landmark ID
// Calculate the ankle direction based on the landmark
var ankleDirection = (ankleLandmark.WorldPosition - anklePosition).normalized;
// Set the avatar's left ankle orientation
avatarModel.transform.Find("LeftFoot").rotation = Quaternion.LookRotation(ankleDirection, Vector3.up);
// Set the avatar's right ankle orientation
avatarModel.transform.Find("RightFoot").rotation = Quaternion.LookRotation(ankleDirection, Vector3.up);
}
}
손
MediaPipe Unity 플러그인의 손 방향 감지 기능을 사용하여 아바타 손 랜드마크를 식별합니다.
아바타의 손 방향을 계산하고 방향을 조정합니다.
using UnityEngine;
using Mediapipe.Unity;
public class AvatarHandOrientation : MonoBehaviour
{
(SerializeField) private GameObject avatarModel;
(SerializeField) private HandLandmarkList landmarkList;
private Vector3 wristPosition;
void Start()
{
// Load the avatar model
// You may need to adjust the position and rotation to fit the model in the scene
Instantiate(avatarModel, Vector3.zero, Quaternion.identity);
// Get the wrist position from the avatar model
// This position may need to be adjusted based on the model's size and orientation
wristPosition = avatarModel.transform.Find("RightHand/Wrist").position;
// Add a hand landmark list to the scene to detect hand landmarks
landmarkList = gameObject.AddComponent<HandLandmarkList>();
landmarkList.enableDetection = true;
// Reverse the orientation of the model's right arm, so that the hand points forward by default
avatarModel.transform.Find("RightArm").localRotation *= Quaternion.Euler(180f, 0f, 0f);
avatarModel.transform.Find("RightForeArm").localRotation *= Quaternion.Euler(180f, 0f, 0f);
avatarModel.transform.Find("RightHand").localRotation *= Quaternion.Euler(180f, 0f, 0f);
}
void Update()
{
// Get the wrist landmark from the HandLandmarkList
var wristLandmark = landmarkList.GetLandmark(0); // Right wrist landmark ID
// Calculate the hand direction based on the landmarks
var handDirection = (landmarkList.GetLandmark(5).WorldPosition - landmarkList.GetLandmark(17).WorldPosition).normalized;
// Set the avatar's right hand orientation
avatarModel.transform.Find("RightHand").rotation = Quaternion.LookRotation(handDirection, Vector3.up);
// Set the avatar's right forearm orientation
var forearmDirection = (wristLandmark.WorldPosition - wristPosition).normalized;
avatarModel.transform.Find("RightForeArm").rotation = Quaternion.LookRotation(forearmDirection, -handDirection);
// Set the avatar's right arm orientation
var armDirection = (wristPosition - avatarModel.transform.Find("RightShoulder").position).normalized;
avatarModel.transform.Find("RightArm").rotation = Quaternion.LookRotation(armDirection, -forearmDirection);
}
}
발
MediaPipe Unity 플러그인의 발 랜드마크 감지 기능을 사용하여 아바타 발의 랜드마크를 식별합니다.
아바타 발 방향을 계산하고 방향을 조정합니다.
using UnityEngine;
using Mediapipe.Unity;
public class AvatarFootOrientation : MonoBehaviour
{
(SerializeField) private GameObject avatarModel;
(SerializeField) private FeetLandmarkList landmarkList;
private Vector3 anklePosition;
void Start()
{
// Load the avatar model
// You may need to adjust the position and rotation to fit the model in the scene
Instantiate(avatarModel, Vector3.zero, Quaternion.identity);
// Get the ankle position from the avatar model
// This position may need to be adjusted based on the model's size and orientation
anklePosition = avatarModel.transform.Find("RightLeg/RightFoot/Ankle").position;
// Add a feet landmark list to the scene to detect feet landmarks
landmarkList = gameObject.AddComponent<FeetLandmarkList>();
landmarkList.enableDetection = true;
// Reverse the orientation of the model's right leg, so that the foot points forward by default
avatarModel.transform.Find("RightLeg").localRotation *= Quaternion.Euler(180f, 0f, 0f);
avatarModel.transform.Find("RightFoot").localRotation *= Quaternion.Euler(180f, 0f, 0f);
}
void Update()
{
// Get the ankle landmark from the FeetLandmarkList
var ankleLandmark = landmarkList.GetLandmark(0); // Right ankle landmark ID
// Calculate the foot direction based on the landmarks
var footDirection = (landmarkList.GetLandmark(8).WorldPosition - landmarkList.GetLandmark(17).WorldPosition).normalized;
// Set the avatar's right foot orientation
avatarModel.transform.Find("RightFoot").rotation = Quaternion.LookRotation(footDirection, Vector3.up);
// Set the avatar's right leg orientation
var legDirection = (anklePosition - avatarModel.transform.Find("RightHip").position).normalized;
avatarModel.transform.Find("RightLeg").rotation = Quaternion.LookRotation(legDirection, -footDirection);
}
}
왼쪽 엉덩이
MediaPipe Unity 플러그인의 포즈 감지 기능을 사용하여 아바타의 랜드마크를 식별합니다.
아바타의 왼쪽 엉덩이 방향을 계산하고 방향을 조정합니다.
using UnityEngine;
using Mediapipe.Unity;
public class AvatarLeftHipOrientation : MonoBehaviour
{
(SerializeField) private GameObject avatarModel;
(SerializeField) private PoseLandmarkList landmarkList;
void Start()
{
// Load the avatar model
// You may need to adjust the position and rotation to fit the model in the scene
Instantiate(avatarModel, Vector3.zero, Quaternion.identity);
// Add a pose landmark list to the scene to detect pose landmarks
landmarkList = gameObject.AddComponent<PoseLandmarkList>();
landmarkList.enableDetection = true;
}
void Update()
{
// Get the left hip landmark from the PoseLandmarkList
var leftHipLandmark = landmarkList.GetLandmark((int)PoseLandmark.LeftHip);
// Get the left knee landmark from the PoseLandmarkList
var leftKneeLandmark = landmarkList.GetLandmark((int)PoseLandmark.LeftKnee);
// Get the left ankle landmark from the PoseLandmarkList
var leftAnkleLandmark = landmarkList.GetLandmark((int)PoseLandmark.LeftAnkle);
// Calculate the leg direction based on the landmarks
var legDirection = (leftAnkleLandmark.WorldPosition - leftHipLandmark.WorldPosition).normalized;
// Calculate the foot direction based on the landmarks
var footDirection = (leftAnkleLandmark.WorldPosition - leftKneeLandmark.WorldPosition).normalized;
// Set the avatar's left leg orientation
avatarModel.transform.Find("LeftLeg").rotation = Quaternion.LookRotation(legDirection, -footDirection);
}
}
오른쪽 엉덩이
MediaPipe Unity 플러그인의 포즈 감지 기능을 사용하여 아바타의 랜드마크를 식별합니다.
아바타의 오른쪽 엉덩이 방향을 계산하여 방향을 조정합니다.
using UnityEngine;
using Mediapipe.Unity;
public class AvatarRightHipOrientation : MonoBehaviour
{
(SerializeField) private GameObject avatarModel;
(SerializeField) private PoseLandmarkList landmarkList;
void Start()
{
// Load the avatar model
// You may need to adjust the position and rotation to fit the model in the scene
Instantiate(avatarModel, Vector3.zero, Quaternion.identity);
// Add a pose landmark list to the scene to detect pose landmarks
landmarkList = gameObject.AddComponent<PoseLandmarkList>();
landmarkList.enableDetection = true;
}
void Update()
{
// Get the right hip landmark from the PoseLandmarkList
var rightHipLandmark = landmarkList.GetLandmark((int)PoseLandmark.RightHip);
// Get the right knee landmark from the PoseLandmarkList
var rightKneeLandmark = landmarkList.GetLandmark((int)PoseLandmark.RightKnee);
// Get the right ankle landmark from the PoseLandmarkList
var rightAnkleLandmark = landmarkList.GetLandmark((int)PoseLandmark.RightAnkle);
// Calculate the leg direction based on the landmarks
var legDirection = (rightAnkleLandmark.WorldPosition - rightHipLandmark.WorldPosition).normalized;
// Calculate the foot direction based on the landmarks
var footDirection = (rightAnkleLandmark.WorldPosition - rightKneeLandmark.WorldPosition).normalized;
// Set the avatar's right leg orientation
avatarModel.transform.Find("RightLeg").rotation = Quaternion.LookRotation(legDirection, -footDirection);
}
}
손가락
MediaPipe Unity 플러그인의 손 추적 기능을 사용하여 아바타의 손가락 랜드마크를 식별합니다.
각 손가락의 방향을 계산하고 방향을 조정합니다.
using UnityEngine;
using Mediapipe.Unity.HandTracking;
public class AvatarFingerOrientation : MonoBehaviour
{
(SerializeField) private GameObject avatarModel;
(SerializeField) private HandTrackingLandmarkList landmarkList;
void Start()
{
// Load the avatar model
// You may need to adjust the position and rotation to fit the model in the scene
Instantiate(avatarModel, Vector3.zero, Quaternion.identity);
// Add a hand landmark list to the scene to detect hand landmarks
landmarkList = gameObject.AddComponent<HandTrackingLandmarkList>();
landmarkList.enableDetection = true;
}
void Update()
{
// Get the finger landmarks from the HandTrackingLandmarkList
var thumbLandmark = landmarkList.GetLandmark(HandLandmark.ThumbTip);
var indexLandmark = landmarkList.GetLandmark(HandLandmark.IndexTip);
var middleLandmark = landmarkList.GetLandmark(HandLandmark.MiddleTip);
var ringLandmark = landmarkList.GetLandmark(HandLandmark.RingTip);
var pinkyLandmark = landmarkList.GetLandmark(HandLandmark.PinkyTip);
// Calculate the direction of each finger based on the landmarks
var thumbDirection = (thumbLandmark.WorldPosition - indexLandmark.WorldPosition).normalized;
var indexDirection = (indexLandmark.WorldPosition - middleLandmark.WorldPosition).normalized;
var middleDirection = (middleLandmark.WorldPosition - ringLandmark.WorldPosition).normalized;
var ringDirection = (ringLandmark.WorldPosition - pinkyLandmark.WorldPosition).normalized;
var pinkyDirection = (pinkyLandmark.WorldPosition - ringLandmark.WorldPosition).normalized;
// Set the avatar's finger orientations
avatarModel.transform.Find("RightHand/Thumb").rotation = Quaternion.LookRotation(thumbDirection);
avatarModel.transform.Find("RightHand/Index").rotation = Quaternion.LookRotation(indexDirection);
avatarModel.transform.Find("RightHand/Middle").rotation = Quaternion.LookRotation(middleDirection);
avatarModel.transform.Find("RightHand/Ring").rotation = Quaternion.LookRotation(ringDirection);
avatarModel.transform.Find("RightHand/Pinky").rotation = Quaternion.LookRotation(pinkyDirection);
}
}
오른손과 손가락
이전에 작성한 코드에서 RightHand만 변경하면 왼손과 오른손을 모두 지원할 수 있습니다. 아래는 MediaPipe Unity 플러그인을 사용하여 3D 아바타의 오른손 손가락 방향을 계산하는 예제 코드입니다.
using UnityEngine;
using Mediapipe.Unity.HandTracking;
public class AvatarRightHandFingerOrientation : MonoBehaviour
{
(SerializeField) private GameObject avatarModel;
(SerializeField) private HandTrackingLandmarkList landmarkList;
void Start()
{
// Load the avatar model
// You may need to adjust the position and rotation to fit the model in the scene
Instantiate(avatarModel, Vector3.zero, Quaternion.identity);
// Add a hand landmark list to the scene to detect hand landmarks
landmarkList = gameObject.AddComponent<HandTrackingLandmarkList>();
landmarkList.enableDetection = true;
}
void Update()
{
// Get the finger landmarks from the HandTrackingLandmarkList
var thumbLandmark = landmarkList.GetLandmark(HandLandmark.ThumbTip);
var indexLandmark = landmarkList.GetLandmark(HandLandmark.IndexTip);
var middleLandmark = landmarkList.GetLandmark(HandLandmark.MiddleTip);
var ringLandmark = landmarkList.GetLandmark(HandLandmark.RingTip);
var pinkyLandmark = landmarkList.GetLandmark(HandLandmark.PinkyTip);
// Calculate the direction of each finger based on the landmarks
var thumbDirection = (thumbLandmark.WorldPosition - indexLandmark.WorldPosition).normalized;
var indexDirection = (indexLandmark.WorldPosition - middleLandmark.WorldPosition).normalized;
var middleDirection = (middleLandmark.WorldPosition - ringLandmark.WorldPosition).normalized;
var ringDirection = (ringLandmark.WorldPosition - pinkyLandmark.WorldPosition).normalized;
var pinkyDirection = (pinkyLandmark.WorldPosition - ringLandmark.WorldPosition).normalized;
// Set the avatar's finger orientations
avatarModel.transform.Find("RightHand/Thumb").rotation = Quaternion.LookRotation(thumbDirection);
avatarModel.transform.Find("RightHand/Index").rotation = Quaternion.LookRotation(indexDirection);
avatarModel.transform.Find("RightHand/Middle").rotation = Quaternion.LookRotation(middleDirection);
avatarModel.transform.Find("RightHand/Ring").rotation = Quaternion.LookRotation(ringDirection);
avatarModel.transform.Find("RightHand/Pinky").rotation = Quaternion.LookRotation(pinkyDirection);
}
}
머리와 목
앞서 작성한 코드에서 머리와 목을 추가하기만 하면 머리와 목의 방향도 계산할 수 있습니다. 아래는 MediaPipe Unity 플러그인을 사용하여 3D 아바타의 머리와 목 방향을 계산하는 샘플 코드입니다.
using UnityEngine;
using Mediapipe.Unity.FaceDetection;
public class AvatarHeadNeckOrientation : MonoBehaviour
{
(SerializeField) private GameObject avatarModel;
(SerializeField) private FaceDetectionSolution faceDetection;
void Start()
{
// Load the avatar model
// You may need to adjust the position and rotation to fit the model in the scene
Instantiate(avatarModel, Vector3.zero, Quaternion.identity);
// Add a FaceDetectionSolution to the scene to detect the face
faceDetection = gameObject.AddComponent<FaceDetectionSolution>();
faceDetection.enableFaceDetection = true;
}
void Update()
{
// Get the head and neck landmarks from the FaceDetectionSolution
var headLandmark = faceDetection.faceLandmarkList?.GetLandmark(FaceLandmark.HeadTop);
var neckLandmark = faceDetection.faceLandmarkList?.GetLandmark(FaceLandmark.NoseTip);
// Calculate the direction of the head based on the landmarks
var headDirection = (headLandmark?.WorldPosition - neckLandmark?.WorldPosition)?.normalized ?? Vector3.forward;
// Calculate the direction of the neck based on the landmarks
var neckDirection = (neckLandmark?.WorldPosition - Vector3.up)?.normalized ?? Vector3.up;
// Set the avatar's head and neck orientations
avatarModel.transform.Find("Head").rotation = Quaternion.LookRotation(headDirection, neckDirection);
avatarModel.transform.Find("Neck").rotation = Quaternion.LookRotation(neckDirection);
}
}

