๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Unity/AR

[Unity AR] Unity AR Hand Tracking / ์‹ค์‹œ๊ฐ„ ํ•ธ๋“œ ํŠธ๋ž˜ํ‚น ๊ตฌํ˜„ - ManoMotion + AR Foundation

728x90
๋ฐ˜์‘ํ˜•

 

์•ˆ๋…•ํ•˜์„ธ์š”. ์ด๋ฒˆ ๊ธ€์€ Unity AR ํ™˜๊ฒฝ์—์„œ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์˜ค๋ธŒ์ ํŠธ์™€ ์ง์ ‘ "์†"์œผ๋กœ ์ƒํ˜ธ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋„๋ก ๋งŒ๋“ค์–ด๋ณด๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค. Unity ์ž์ฒด์—์„œ๋Š” "์† ์ถ”์ " ๊ด€๋ จํ•œ ํˆด์„ ์ œ๊ณตํ•˜์ง€ ์•Š๊ธฐ์— ์™ธ๋ถ€ SDK์ธ ManoMotion์„ ์ด์šฉํ•ฉ๋‹ˆ๋‹ค. ํ™˜๊ฒฝ์„ ๊ตฌ์ถ•ํ•˜๋Š”๋ฐ ๋ชจ๋“  ๊ณผ์ •์„ ๋‹ด์œผ๋ ค๋ฉด ๊ธ€ ํ•˜๋‚˜๋กœ๋Š” ๋ฒ…์ฐฐ ์ˆ˜ ์žˆ๊ธฐ์— ํ•ต์‹ฌ์ ์ธ ๋ถ€๋ถ„๊ณผ ์ œ๊ฐ€ ์ฐธ๊ณ ํ•œ ์˜์ƒ์„ ์ฒจ๋ถ€ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์˜์ƒ์€ ๋ชจ๋“  ๊ณผ์ •์„ ๋‹ด์•„์ฃผ๊ธฐ์— ๋ˆ„๊ตฌ๋‚˜ ์‰ฝ๊ฒŒ ์ฐธ๊ณ ํ•˜์‹ค ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

 

https://youtube.com/shorts/viodtUDVm_4?feature=share 

 

 

 

 

 

 ManoMotion ๋ฌด์—‡์ธ๊ฐ€?

 

ManoMotion์€ ์† ์ธ์‹ ๊ธฐ์ˆ ์„ ๊ฐœ๋ฐœํ•˜๋Š” ํšŒ์‚ฌ๋กœ, ์† ๋ชจ์…˜ ๋ฐ ์ œ์Šค์ฒ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ธํ„ฐ๋ž™์…˜ ํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•˜๊ธฐ ์œ„ํ•œ SDK๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋ฐ”์ผ ๊ธฐ๊ธฐ์˜ ์นด๋ฉ”๋ผ๋ฅผ ํ†ตํ•ด์„œ๋„ ์‚ฌ์šฉ์ž์˜ ์†์˜ ์œ„์น˜, ์›€์ง์ž„, ๋™์ž‘ ๋“ฑ์„ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ถ”์ ํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ „๋‹ฌํ•ด ์ค๋‹ˆ๋‹ค. Unity ๋ฐ Unreal ๊ฐ™์€ ๊ฒŒ์ž„ ์—”์ง„์—๋„ ํ†ตํ•ฉ๋˜์–ด ์‰ฝ๊ฒŒ ์•ฑ ๋˜๋Š” ๊ฒŒ์ž„์—๋„ ํ†ตํ•ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

Unity ์•ˆ์—์„œ "์† ์ถ”์ " ์„ ์œ„ํ•ด MediaPipe๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ, ManoMotion์€ ์† ์ธ์‹๊ณผ ์ œ์Šค์ฒ˜ ๊ธฐ๋Šฅ์— ์ค‘์ ์„ ๋‘์—ˆ์ง€๋งŒ MediaPipe๋Š” ๊ฐ์ฒด ์ถ”์ , ๋™์ž‘ ์ธ์‹, ์–ผ๊ตด ๊ฐ์ง€ ๋“ฑ ๋‹ค์–‘ํ•œ ๋น„์ „ ๋ฐ ์˜ค๋””์˜ค ์ฒ˜๋ฆฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ์–ด ๋‘˜์˜ ๋ชฉ์ ๊ณผ ์ง€์›ํ•˜๋ ค๋Š” ๊ธฐ๋Šฅ์—์„œ ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋˜ํ•œ, ManoMotion SDK๋Š” ์ด๋ฏธ ๊ฐœ๋ฐœ๋œ ์•Œ๊ณ ๋ฆฌ์ฆ˜๊ณผ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์ถ•ํ•˜๋Š” ๋ฐ˜๋ฉด, MediaPipe๋Š” ์ œ๊ณต๋œ ๋„๊ตฌ์™€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ด์šฉํ•ด ๊ฐœ๋ฐœ์ž๊ฐ€ ํ•„์š”ํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋งŒ๋“ค๊ณ ์ž ํ•˜๋Š” ์•ฑ์— "์†"์œผ๋กœ ์ƒํ˜ธ์ž‘์šฉ ๊ด€๋ จ๋œ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ๋‹ค. ๋น ๋ฅด๊ฒŒ Start ํ•˜๋Š” ๋ฐ์—๋Š” ManoMotion SDK๊ฐ€ ์œ ๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด์ฃ .

 

 

 

 

 

 

 Unity์— ManoMotion ํ™˜๊ฒฝ ๊ตฌ์ถ•

 

https://developer.manomotion.com/

 

Manomotion Developer – Let your hands talk to technology!

POWER UP YOUR APP DEVELOPMENT Today, thanks to the AR ecosystem, spatial interaction and AR are highly related to the real life experiences of humans in the physical space where direct control and manipulation of the items with hands are crucial.

developer.manomotion.com

๋จผ์ € ManoMotion ์›น ์‚ฌ์ดํŠธ ํšŒ์›๊ฐ€์ž…์„ ํ•ด์ค๋‹ˆ๋‹ค.

 

 

ํšŒ์›๊ฐ€์ž… ์‹œ ๋‚˜ํƒ€๋‚˜๋Š” ์ฐฝ์ž…๋‹ˆ๋‹ค. ์ฃผ๋ชฉํ•ด์•ผ ํ•˜๋Š” ๊ฑด ๋นจ๊ฐ„์ƒ‰ ๋„ค๋ชจ๋กœ ๊ทธ๋ ค์ง„ Get Started / ๋ผ์ด์„ผ์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

 

Get Started๋ฅผ ํด๋ฆญํ•ด์„œ SDK๋ฅผ ๋‹ค์šด๋ฐ›์•„ ์ค๋‹ˆ๋‹ค.

 

 

๋ผ์ด์„ผ์Šค ์ •๋ณด์ž…๋‹ˆ๋‹ค. SDK๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋ผ์ด์„ ์Šค Key๊ฐ€ ํ•„์š”ํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ๋งŒ๋ฃŒ๋˜๋ฉด ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ๋„ ์ฐธ๊ณ ํ•˜์‹œ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ์ €๋„ ์ด ๊ธ€์„ ์“ธ ๋•Œ ์ง€๊ธˆ ๋ผ์ด์„ ์Šค๊ฐ€ ๋งŒ๋ฃŒ๋˜์–ด ๋ผ์ด์„ ์Šค๋ฅผ ํ™•์ธํ•  ์ˆ˜๊ฐ€ ์—†๋Š” ์ƒํ™ฉ์ž…๋‹ˆ๋‹ค.. 

์žฌ๋ฐœ๊ธ‰์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋ชป ์ฐพ๊ณ  ์žˆ์–ด์„œ.. ํ˜น์‹œ ์•„์‹œ๋Š” ๋ถ„ ์žˆ์œผ์‹œ๋ฉด ๋Œ“๊ธ€๋กœ ๊ผญ ์•Œ๋ ค์ฃผ์„ธ์š”!!

 

 

https://www.youtube.com/watch?v=wQlNT-oDreQ&t=351s 

 

 

 

 

 

 Hand Gesture๋กœ ์˜ค๋ธŒ์ ํŠธ ์ƒ์„ฑ

 

 

AR ํ™˜๊ฒฝ์„ ์œ„ํ•ด AR Session Origin๊ณผ AR Session์„ ์ƒ์„ฑํ•ด ์ค๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ARManomotionManager ๊ณผ ManomotionCanvas Prefab์„ ์ƒ์„ฑํ•ด ์ค๋‹ˆ๋‹ค. SDK๋ฅผ ๋‹ค์šด๋ฐ›์œผ์…จ๋‹ค๋ฉด ๊ฒ€์ƒ‰์ฐฝ์— ๋ฐ”๋กœ ์ฐพ์œผ์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

 

ARManomotionManager ์ธ์ŠคํŽ™ํ„ฐ ๋ชจ์Šต์ž…๋‹ˆ๋‹ค. ์œ„ ์‚ฌ์ง„์ฒ˜๋Ÿผ ์—ฐ๊ฒฐํ•ด ์ค๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ฐ์ž ๋ฐœ๊ธ‰๋ฐ›์•˜๋˜ ๋ผ์ด์„ผ์Šค Key๋ฅผ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.

 

 

 

Project Settings๋ฅผ ์—ด์–ด Player ํ•ญ๋ชฉ์œผ๋กœ ๋„˜์–ด๊ฐ€ ์ œ๊ณต๋ฐ›์•˜๋˜ Bundle ID๋„ ์จ๋„ฃ์–ด ์ค๋‹ˆ๋‹ค.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class SpawnObjcectOnClick : MonoBehaviour
{
    
    [SerializeField] private GameObject[] arObject;
    private int currentIndex = 0;
 
   // GameObject[] childObjects = new GameObject[arObject.transform.childCount];
   
 
    // Update is called once per frame
    void Update()
    {
        ManomotionManager.Instance.ShouldCalculateGestures(true);
 
        GestureInfo gestureInfo = ManomotionManager.Instance.Hand_infos[0].hand_info.gesture_info;
 
        ManoGestureTrigger currentGesture = gestureInfo.mano_gesture_trigger;
    
    
        if (currentGesture == ManoGestureTrigger.CLICK)
        {
            SpawnObject();
        }
    }
 
    private void SpawnObject()
    {
        ManomotionManager.Instance.ShouldCalculateSkeleton3D(true);
 
        TrackingInfo trackingInfo = ManomotionManager.Instance.Hand_infos[0].hand_info.tracking_info;
 
        float depthEstimation = trackingInfo.depth_estimation;
 
        Vector3 jointPosition = ManoUtils.Instance.CalculateNewPositionSkeletonJointDepth(new Vector3(trackingInfo.skeleton.joints[8].x, trackingInfo.skeleton.joints[8].y, trackingInfo.skeleton.joints[8].z), depthEstimation);
 
        //Instantiate(arObject, jointPosition, Quaternion.identity);
 
        Instantiate(arObject[currentIndex], jointPosition, Quaternion.identity);
        
        Handheld.Vibrate();
 
        currentIndex++;
 
    }
}
cs
SpawnObjcectOnClick ํด๋ž˜์Šค๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ํด๋ฆญ ์ œ์Šค์ฒ˜๋ฅผ ์ˆ˜ํ–‰ํ•  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ์ƒ์„ฑ๋œ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด์„œ ์ƒ์„ฑํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

1. Updata() ํ•จ์ˆ˜์—์„œ ๋งค ํ”„๋ ˆ์ž„๋งˆ๋‹ค Manomotion ์ œ์Šค์ฒ˜ ์ธ์‹์„ ํ™œ์„ฑํ™”ํ•˜๊ณ , ํ˜„์žฌ ์ธ์‹๋œ ์ œ์Šค์ฒ˜๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
ํ˜„์žฌ ์ œ์Šค์ฒ˜๊ฐ€ ManoGestureTrigger.CLICK์ธ ๊ฒฝ์šฐ SpawnObject() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ƒˆ๋กœ์šด ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

2. SpawnObject() ๋ฉ”์„œ๋“œ๋Š” Manomotion 3D ์Šค์ผˆ๋ ˆํ†ค ์ถ”์ ์„ ํ™œ์„ฑํ™”ํ•˜๊ณ , ์†์˜ ๊นŠ์ด ์ถ”์ • ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
์ถ”์ •๋œ ๊นŠ์ด์™€ ์†์˜ ๊ด€์ ˆ ์œ„์น˜๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒ์„ฑ ์œ„์น˜๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ 'arObject' ๋ฐฐ์—ด์—์„œ ํ˜„์žฌ ์ธ๋ฑ์Šค์— ํ•ด๋‹นํ•˜๋Š” ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

3. ์ƒ์„ฑ๋œ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ง„๋™์‹œํ‚ค๊ณ , ๋ฐฐ์—ด ์ธ๋ฑ์Šค๋ฅผ ์ฆ๊ฐ€์‹œํ‚ต๋‹ˆ๋‹ค.

 

 

 

์˜์ƒ๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ ์ €๋Š” Ar Object ๋ณ€์ˆ˜๋ฅผ ๋ฐฐ์—ด๋กœ ๋งŒ๋“ค์–ด ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๋„ฃ์–ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

 

 

https://www.youtube.com/watch?v=9PRYIxb3tYk&list=PLSc07dYXbtBl8PTbnWSjbvREVmkbebPOv&index=4 

 

 

 

 

 

 "์†"์œผ๋กœ ์ง์ ‘ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์žก๊ณ  ์˜ฎ๊ธฐ๊ธฐ

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class GrabInteraction : MonoBehaviour
{
    [SerializeField] private GameObject handPointer;
    private float skeletonConfience = 0.0001f;
 
 
    // Update is called once per frame
    void Update()
    {
        bool hasConfience = ManomotionManager.Instance.Hand_infos[0].hand_info.tracking_info.skeleton.confidence > skeletonConfience;
 
        if (hasConfience )
        {
            var palmCenter = ManomotionManager.Instance.Hand_infos[0].hand_info.tracking_info.palm_center;
 
            var depthEstimation = ManomotionManager.Instance.Hand_infos[0].hand_info.tracking_info.depth_estimation;
 
            Vector3 positionPointer = ManoUtils.Instance.CalculateNewPositionDepth(palmCenter, depthEstimation);
 
            handPointer.transform.position = positionPointer;
            handPointer.SetActive(true);
        }
 
        else
        {
            handPointer.transform.DetachChildren();
            handPointer.SetActive(false);
 
 
        }
    }
}
cs
GrabInteraction ํด๋ž˜์Šค๋Š” ์† ์ถ”์ ์„ ๊ธฐ๋ฐ˜์œผ๋กœ Hand Pointer๋ฅผ ์—…๋ฐ์ดํŠธ ๊ธฐ๋Šฅ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

1. hasConfience ๋ณ€์ˆ˜๋Š” ์†์˜ ์ถ”์  ์ •๋ณด์—์„œ ์Šค์ผˆ๋ ˆํ†ค์˜ ์‹ ๋ขฐ๋„๊ฐ€ skeltonConfience ๋ณด๋‹ค ํฐ์ง€ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

2. ๋งŒ์•ฝ ์‹ ๋ขฐ๋„๊ฐ€ ์ถฉ๋ถ„ํžˆ ํฌ๋‹ค๋ฉด ์†์˜ ์ค‘์‹ฌ(palmCenter)๊ณผ ๊นŠ์ด ์ถ”์ • ์ •๋ณด(depthEstimation)๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์† ํฌ์ธํ„ฐ์˜ ์œ„์น˜(positionPointer)๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.

3. ๊ณ„์‚ฐ๋œ ์œ„์น˜๋กœ ์† ํฌ์ธํ„ฐ์˜ ์œ„์น˜๋ฅผ ์ด๋™ํ•˜๊ณ , ์† ํฌ์ธํ„ฐ๋ฅผ ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค. 

4. ๋งŒ์•ฝ ์‹ ๋ขฐ๋„๊ฐ€ ์ถฉ๋ถ„ํ•˜์ง€ ์•Š๋‹ค๋ฉด, ์† ํฌ์ธํ„ฐ์™€์˜ ๋ถ€๋ชจ-์ž์‹ ๊ด€๊ณ„๋ฅผ ํ•ด์ œํ•˜๊ณ  ์† ํฌ์ธํ„ฐ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค.

 

 

 

GrabInteraction ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋„ฃ์–ด์ฃผ๊ณ , Hand Pointer๋กœ ์‚ฌ์šฉํ•  ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค. 

์ด์ œ Hand Pointer ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ์†์˜ ์ค‘์‹ฌ์— ์œ„์น˜ํ•˜๊ณ , ์†์ด ์›€์ง์ผ ๋•Œ๋งˆ๋‹ค Hand Pointer๋„ ๋”ฐ๋ผ์„œ ์›€์ง์ด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
[RequireComponent(typeof(BoxCollider), typeof(Rigidbody))]
public class ObjectManipulator : MonoBehaviour
{
 
    [SerializeField] private Material[] materials = new Material[2];
    private Renderer objcectRenderer;
    private string handTag = "Player";
    private bool isGrabbing;
    private float skeletonConfidence = 0.0001f;
 
 
    // Start is called before the first frame update
    void Start()
    {
        objcectRenderer= GetComponent<Renderer>();
 
    }
 
    // Update is called once per frame
    void Update()
    {
        ManomotionManager.Instance.ShouldCalculateGestures(true);
 
        var currentGesture = ManomotionManager.Instance.Hand_infos[0].hand_info.gesture_info.mano_gesture_trigger;
 
        if(currentGesture == ManoGestureTrigger.GRAB_GESTURE)
        {
            isGrabbing = true;
 
        }
 
        else if (currentGesture == ManoGestureTrigger.RELEASE_GESTURE)
        {
            isGrabbing = false;
            transform.parent = null;
        }
 
        bool hasConfidence = ManomotionManager.Instance.Hand_infos[0].hand_info.tracking_info.skeleton.confidence > skeletonConfidence;
 
        if(!hasConfidence)
        {
            objcectRenderer.sharedMaterial = materials[0];
 
        }
    }
 
    private void OnTriggerEnter(Collider other)
    {
        if(other.gameObject.CompareTag(handTag))
        {
            objcectRenderer.sharedMaterial = materials[1];
            Handheld.Vibrate();
        }
 
        else if(isGrabbing)
        {
            transform.parent = other.gameObject.transform;
        }
    }
 
    private void OnTriggerStay(Collider other)
    {
        if(other.gameObject.CompareTag(handTag) && isGrabbing)
        {
            transform.parent = other.gameObject.transform;
        }
    }
 
    private void OnTriggerExit(Collider other)
    {
        transform.parent = null;
        objcectRenderer.sharedMaterial = materials[0];
    }
}
 
cs
ObjectManipulator ํด๋ž˜์Šค๋Š” "์†" ๊ณผ์˜ ์ถฉ๋Œ์„ ๊ฐ์ง€ํ•˜์—ฌ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์žก๊ณ  ๋†“๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
RequireComponent() ์˜ํ•ด ์ปดํฌ๋„ŒํŠธ ์ƒ์„ฑ ์‹œ `BoxCollider`์™€ `Rigidbody` ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ž๋™ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

1. `materials`๋ผ๋Š” `Material` ๋ฐฐ์—ด๊ณผ ์—ฌ๋Ÿฌ ๋ณ€์ˆ˜๋“ค์ด ์„ ์–ธ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. `objcectRenderer`๋Š” ๋ Œ๋”๋Ÿฌ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ฐธ์กฐํ•˜๊ณ , `handTag`๋Š” ์†์„ ๋‚˜ํƒ€๋‚ด๋Š” ํƒœ๊ทธ๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. `isGrabbing`์€ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์žก๊ณ  ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ถˆ๋ฆฌ์–ธ ๋ณ€์ˆ˜์ž…๋‹ˆ๋‹ค. `skeletonConfidence`๋Š” ์Šค์ผˆ๋ ˆํ†ค์˜ ์‹ ๋ขฐ๋„ ์ž„๊ณ„๊ฐ’์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
2. `Start()` ๋ฉ”์„œ๋“œ์—์„œ `objcectRenderer`๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.
3. `Update()` ๋ฉ”์„œ๋“œ๋Š” ๋งค ํ”„๋ ˆ์ž„๋งˆ๋‹ค ํ˜ธ์ถœ๋˜๋ฉฐ, Manomotion ์ œ์Šค์ฒ˜ ์ธ์‹์„ ํ™œ์„ฑํ™”ํ•˜๊ณ  ํ˜„์žฌ ์ธ์‹๋œ ์ œ์Šค์ฒ˜๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
4. ํ˜„์žฌ ์ œ์Šค์ฒ˜๊ฐ€ `ManoGestureTrigger.GRAB_GESTURE`์ธ ๊ฒฝ์šฐ `isGrabbing`์„ true๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
5. ํ˜„์žฌ ์ œ์Šค์ฒ˜๊ฐ€ `ManoGestureTrigger.RELEASE_GESTURE`์ธ ๊ฒฝ์šฐ `isGrabbing`์„ false๋กœ ์„ค์ •ํ•˜๊ณ , ์˜ค๋ธŒ์ ํŠธ์˜ ๋ถ€๋ชจ๋ฅผ null๋กœ ์„ค์ •ํ•˜์—ฌ ์˜ค๋ธŒ์ ํŠธ์˜ ๋ถ€๋ชจ-์ž์‹ ๊ด€๊ณ„๋ฅผ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค.
6. `hasConfidence` ๋ณ€์ˆ˜๋Š” ์†์˜ ์ถ”์  ์ •๋ณด์—์„œ ์Šค์ผˆ๋ ˆํ†ค์˜ ์‹ ๋ขฐ๋„๊ฐ€ `skeletonConfidence`๋ณด๋‹ค ํฐ์ง€ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
7. ๋งŒ์•ฝ ์‹ ๋ขฐ๋„๊ฐ€ ์ถฉ๋ถ„ํ•˜์ง€ ์•Š๋‹ค๋ฉด, `objcectRenderer`์˜ `sharedMaterial`์„ `materials[0]`์œผ๋กœ ์„ค์ •ํ•˜์—ฌ ์˜ค๋ธŒ์ ํŠธ์˜ ๋จธํ‹ฐ๋ฆฌ์–ผ์„ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.
8. `OnTriggerEnter()` ๋ฉ”์„œ๋“œ๋Š” ํŠธ๋ฆฌ๊ฑฐ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ถฉ๋Œํ•œ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ์˜ ํƒœ๊ทธ๊ฐ€ `handTag`์™€ ์ผ์น˜ํ•œ๋‹ค๋ฉด, `objcectRenderer`์˜ `sharedMaterial`์„ `materials[1]`๋กœ ์„ค์ •ํ•˜๊ณ , ์ง„๋™์„ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค. 9. ๊ทธ๋ ‡์ง€ ์•Š๊ณ  `isGrabbing`์ด true์ธ ๊ฒฝ์šฐ, ์˜ค๋ธŒ์ ํŠธ์˜ ๋ถ€๋ชจ๋ฅผ ์ถฉ๋Œํ•œ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ๋กœ ์„ค์ •ํ•˜์—ฌ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์žก์€ ์ƒํƒœ๋กœ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.
10. `OnTriggerStay()` ๋ฉ”์„œ๋“œ๋Š” ํŠธ๋ฆฌ๊ฑฐ ์ถฉ๋Œ์ด ์ง€์†๋˜๋Š” ๋™์•ˆ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ์ถฉ๋Œํ•œ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ์˜ ํƒœ๊ทธ๊ฐ€ `handTag`์™€ ์ผ์น˜ํ•˜๊ณ  `isGrabbing`์ด true์ธ ๊ฒฝ์šฐ, ์˜ค๋ธŒ์ ํŠธ์˜ ๋ถ€๋ชจ๋ฅผ ์ถฉ๋Œํ•œ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ๋กœ ์„ค์ •ํ•˜์—ฌ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์žก์€ ์ƒํƒœ๋กœ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.
11. `OnTriggerExit()` ๋ฉ”์„œ๋“œ๋Š” ํŠธ๋ฆฌ๊ฑฐ ์ถฉ๋Œ์ด ์ข…๋ฃŒ๋  ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ์˜ค๋ธŒ์ ํŠธ์˜ ๋ถ€๋ชจ๋ฅผ null๋กœ ์„ค์ •ํ•˜๊ณ , `objcectRenderer`์˜ `sharedMaterial`์„ `materials[0]`์œผ๋กœ ์„ค์ •ํ•˜์—ฌ ์˜ค๋ธŒ์ ํŠธ์˜ ๋จธํ‹ฐ๋ฆฌ์–ผ์„ ์ดˆ๊ธฐ ์ƒํƒœ๋กœ ๋˜๋Œ๋ฆฝ๋‹ˆ๋‹ค.

 

 

 

GrabInteraction ํด๋ž˜์Šค์—์„œ handPointer๋กœ ์ง€์ •ํ•œ ์˜ค๋ธŒ์ ํŠธ Tag๋ฅผ Player๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.

 

 

 

์ด์ œ ์žก์„ ์˜ค๋ธŒ์ ํŠธ์— ObjectManipulator ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค. Materials[0]์—๋Š” ์˜ค๋ธŒ์ ํŠธ์˜ ์›๋ž˜ Material์„ ๋„ฃ์–ด์ฃผ๊ณ , Materials[1]์—๋Š” ์†์œผ๋กœ ์žก์„ ๋•Œ ๋ณ€ํ•  Material์„ ๋„ฃ์–ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. 

 

 

https://www.youtube.com/watch?v=RY_IbVgqPS0 

 

 

 

 

728x90
๋ฐ˜์‘ํ˜•