Unity Finger touch and move

 avatar
unknown
plain_text
3 years ago
8.9 kB
2
Indexable
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WalkPad : MonoBehaviour
{
    [SerializeField]
    public GameObject touchpad;
    private Renderer m_renderer;
    //public Mapbox.Unity.Map.AbstractMap map;
    public GameObject cam;
    public float movingSpeed;
    public float movingSpeedFoward;

    /// <summary>
    /// Reference to the managers of the hands. 
    /// First item is left hand, second item is right hand
    /// </summary>
    private OVRHand[] m_hands;

    /// <summary>
    /// True if an index tip is inside the cube, false otherwise.
    /// First item is left hand, second item is right hand
    /// </summary>
    private bool[] m_isIndexStaying;

    // Start is called before the first frame update
    void Start()
    {
        //取得物件
        m_renderer = GetComponent<Renderer>();

        m_hands = new OVRHand[]
        {
            GameObject.Find("OVRCameraRig/TrackingSpace/LeftHandAnchor/OVRHandPrefab").GetComponent<OVRHand>(),
            GameObject.Find("OVRCameraRig/TrackingSpace/RightHandAnchor/OVRHandPrefab").GetComponent<OVRHand>()
        };

        //表示還沒有碰撞到
        m_isIndexStaying = new bool[2] { false, false };

        //設定 is trigger 好像會穿透
        //we don't want the cube to move over collision, so let's just use a trigger
        GetComponent<Collider>().isTrigger = true;
    }

    // Update is called once per frame
    void Update()
    {
        //right hand
        //偵測右手的中指掐,觸發後讓地圖移動一點
        if (m_hands[1].GetFingerIsPinching(OVRHand.HandFinger.Middle))
        {
            //movingCameraForward();
            movingCameraLeft();
        }

        //偵測右手的食指掐,觸發後讓地圖移動一點
        if (m_hands[1].GetFingerIsPinching(OVRHand.HandFinger.Index))
        {
            //update the position
            //movingCameraBackward();
            movingCameraRight();

        }

        //偵測左手的中指掐,觸發後讓地圖移動一點
        if (m_hands[0].GetFingerIsPinching(OVRHand.HandFinger.Middle))
        {
            //movingCameraForward();
            movingCameraUpward();
        }

        //偵測左手的食指掐,觸發後讓地圖移動一點
        if (m_hands[0].GetFingerIsPinching(OVRHand.HandFinger.Index))
        {
            //update the position
            //movingCameraBackward();
            movingCameraDownward();

        }

    }

    private void changeVectorTogether(Vector3 changeVector)
    {
        cam.gameObject.transform.position += changeVector;
        touchpad.transform.position += changeVector;
    }

    //往前移動
    private void movingCameraForward()
    {
        //Vector3 changeVector = new Vector3(1*movingSpeed, 0, 0);
        //changeVectorTogether(changeVector);

        //cam.gameObject.transform.position += Vector3.forward* Time.deltaTime* movingSpeedFoward;
        //touchpad.transform.position += Vector3.forward * Time.deltaTime * movingSpeedFoward;

        cam.gameObject.transform.Translate(transform.forward * Time.deltaTime * movingSpeedFoward, Space.World);
        touchpad.gameObject.transform.Translate(transform.forward * Time.deltaTime * movingSpeedFoward, Space.World);

        //cam.gameObject.transform.forward * Time.deltaTime * movingSpeedFoward;

        //touchpad.transform.position += touchpad.transform.forward * Time.deltaTime * movingSpeedFoward; ;
        //cam.gameObject.transform.position += transform.forward * Time.deltaTime * movingSpeedFoward;
        //touchpad.transform.position += transform.forward * Time.deltaTime * movingSpeedFoward; ;
    }


    //往後移動
    private void movingCameraBackward()
    {
        //Vector3 changeVector = new Vector3(-1 * movingSpeed, 0, 0);
        //changeVectorTogether(changeVector);
        cam.gameObject.transform.position = Vector3.back * Time.deltaTime;
        touchpad.transform.position += Vector3.back * Time.deltaTime;
    }

    //往上移動
    private void movingCameraUpward()
    {
        Vector3 changeVector = new Vector3(0, 1 * movingSpeed, 0);
        changeVectorTogether(changeVector);
    }

    //往下移動
    private void movingCameraDownward()
    {
        Vector3 changeVector = new Vector3(0, -1 * movingSpeed, 0);
        changeVectorTogether(changeVector);
    }

    //往左旋轉
    private void movingCameraLeft()
    {
        cam.gameObject.transform.Rotate(new Vector3(0f, 2f, 0f));
        touchpad.transform.Rotate(new Vector3(0f, 2f, 0f));
    }

    //往右旋轉
    private void movingCameraRight()
    {
        cam.gameObject.transform.Rotate(new Vector3(0f, -2f, 0f));
        touchpad.transform.Rotate(new Vector3(0f, -2f, 0f));
    }


    /// 偵測觸碰物件 Trigger enter.
    /// Notice that this gameobject must have a trigger collider
    private void OnTriggerEnter(Collider collider)
    {
        //get hand associated with trigger
        int handIdx = GetIndexFingerHandId(collider);

        //ps. 如果沒有觸碰到物件,回傳 -1,所以如果非 -1 代表觸碰到物件了
        //if there is an associated hand, it means that an index of one of two hands is entering the object
        if (handIdx != -1)
        {

            //食指
            if(handIdx == 0)
            {
                movingCameraForward();
                m_renderer.material.color = Color.yellow;
            }

            //中指
            if (handIdx == 1)
            {
                movingCameraForward();
                //movingCameraBackward();
                m_renderer.material.color = Color.red;
            }

            //大拇指
            if (handIdx == 2)
            {
                //movingCameraLeft();
                //m_renderer.material.color = Color.green;
            }

            //無名指
            if (handIdx == 3)
            {
                //movingCameraRight();
                //m_renderer.material.color = Color.white;
            }

            m_isIndexStaying[handIdx] = true;
        }
    }

    /// <summary>
    /// Gets the hand id associated with the index finger of the collider passed as parameter, if any
    /// </summary>
    /// <param name="collider">Collider of interest</param>
    /// <returns>0 if the collider represents the finger tip of left hand, 1 if it is the one of right hand, -1 if it is not an index fingertip</returns>
    private int GetIndexFingerHandId(Collider collider)
    {
        //Checking Oculus code, it is possible to see that physics capsules gameobjects always end with _CapsuleCollider
        if (collider.gameObject.name.Contains("_CapsuleCollider"))
        {
            //get the name of the bone from the name of the gameobject, and convert it to an enum value
            string boneName = collider.gameObject.name.Substring(0, collider.gameObject.name.Length - 16);
            OVRPlugin.BoneId boneId = (OVRPlugin.BoneId)Enum.Parse(typeof(OVRPlugin.BoneId), boneName);

            //(食指) if it is the tip of the Index finger
            if (boneId == OVRPlugin.BoneId.Hand_Index3)
            {
                //check if it is left or right hand, 
                //Notice that absurdly, we don't have a way to detect the type of the hand 
                //so we have to use the hierarchy to detect current hand

                //左手
                //if (collider.transform.IsChildOf(m_hands[0].transform))
                //{
                    return 0;
                //}
                //右手
                //else if (collider.transform.IsChildOf(m_hands[1].transform))
                //{
                //    return 1;
                //}
            }

            //(中指) if it is the tip of the Middle finger
            if (boneId == OVRPlugin.BoneId.Hand_Middle3)
            {

                return 1;

                //左手
                //if (collider.transform.IsChildOf(m_hands[0].transform))
                //{return 0;}
                ////右手
                //else if (collider.transform.IsChildOf(m_hands[1].transform))
                //{return 1;}
            }

            //(拇指) if it is the tip of the Middle finger
            if (boneId == OVRPlugin.BoneId.Hand_Thumb3)
            {
                return 2;
            }

            //(無名指) if it is the tip of the Middle finger
            if (boneId == OVRPlugin.BoneId.Hand_Ring3)
            {
                return 3;
            }

        }

        //
        return -1;
    }
}