用多个手指同时拖动不同的对象

Drag different object simultaneously with multiple finger

我按照这个教程 https://www.youtube.com/watch?v=SrCUO46jcxk

对于多点触控,它可以工作。并尝试用多个手指同时在每个对象上添加拖动功能。 这是我的按钮代码,我添加了一些代码以使其可同时拖动每个对象,但它仅适用于单个对象。我尝试了所有相关 post 和教程,但无法执行,请帮助??

using System.Collections;
using UnityEngine;

public class Button : MonoBehaviour{

 public Color defaultColour;
 public Color selectedColour;
 private Material mat;

 private Vector3 screenPoint;
 private Vector3 offset;


 void Start(){
  mat = GetComponent<Renderer> ().material;
 }

 void OnTouchDown(){
  mat.color = selectedColour;
  Debug.Log ("Touch Down");

  screenPoint = Camera.main.WorldToScreenPoint (transform.position);
  offset = transform.position - Camera.main.ScreenToWorldPoint (new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));


  }

 void OnTouchUp(){
  mat.color = defaultColour;
  Debug.Log ("Touch Up");
 }

 void OnTouchStay(){
  mat.color = selectedColour;
  Debug.Log ("Touch Stay");

  Vector3 curScreenPoint = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, screenPoint.z);
  Vector3 curPosition = Camera.main.ScreenToWorldPoint (curScreenPoint) + offset;
  transform.position = curPosition;


 }

 void OnTouchExit(){
  mat.color = defaultColour;
  Debug.Log ("Touch Exit");
 }
}

此代码用于输入触摸功能

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TouchInput : MonoBehaviour {

     public LayerMask touchInputMask;
    private static List<GameObject> touchList = new List<GameObject>();
    private GameObject[] touchesOld;
    private RaycastHit hit;



    void Update () {

        #if UNITY_EDITOR
        if(Input.GetMouseButton(0) || Input.GetMouseButtonDown(0) || Input.GetMouseButtonUp(0)){
            touchesOld = new GameObject[touchList.Count];
            touchList.CopyTo(touchesOld);
            touchList.Clear();

            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            if(Physics.Raycast(ray, out hit, touchInputMask)){
                GameObject recipient = hit.transform.gameObject;
                touchList.Add(recipient);

                if (Input.GetMouseButtonDown(0)){
                    recipient.SendMessage("OnTouchDown",hit.point,SendMessageOptions.DontRequireReceiver);

                }
                if (Input.GetMouseButtonUp(0)){
                    recipient.SendMessage("OnTouchUp",hit.point,SendMessageOptions.DontRequireReceiver);

                }
                if (Input.GetMouseButton(0)){
                    recipient.SendMessage("OnTouchStay",hit.point,SendMessageOptions.DontRequireReceiver);



                }

            }

            foreach (GameObject g in touchesOld){
                if (!touchList.Contains(g)){
                    g.SendMessage("OnTouchExit",hit.point,SendMessageOptions.DontRequireReceiver);
                }
            }
        }

        #endif


        if (Input.touchCount > 0){
            touchesOld = new GameObject[touchList.Count];
            touchList.CopyTo(touchesOld);
            touchList.Clear();

            foreach (Touch touch in Input.touches){

                Ray ray = Camera.main.ScreenPointToRay (touch.position);
                //RaycastHit hit;

                if (Physics.Raycast(ray, out hit, touchInputMask)){
                    GameObject recipient = hit.transform.gameObject;
                    touchList.Add(recipient);

                    if (touch.phase == TouchPhase.Began){
                        recipient.SendMessage("OnTouchDown",hit.point,SendMessageOptions.DontRequireReceiver);

                    }
                    if (touch.phase == TouchPhase.Ended){
                        recipient.SendMessage("OnTouchUp",hit.point,SendMessageOptions.DontRequireReceiver);
                    }
                    if (touch.phase == TouchPhase.Stationary || touch.phase == TouchPhase.Moved){
                        recipient.SendMessage("OnTouchStay",hit.point,SendMessageOptions.DontRequireReceiver);


                    }
                    if (touch.phase == TouchPhase.Canceled){
                        recipient.SendMessage("OnTouchExit",hit.point,SendMessageOptions.DontRequireReceiver);
                    }
                }
            }
            foreach (GameObject g in touchesOld){
                if (!touchList.Contains(g)){
                    g.SendMessage("OnTouchExit",hit.point,SendMessageOptions.DontRequireReceiver);
                }
            }
        }
    }

}

现在终于执行这个过程,我可以用两种方式执行这个过程

  1. 使用touchScript库,它具有丰富的功能,我们可以一次拖动、旋转、平移和缩放多个对象。 https://www.youtube.com/watch?v=HHLBJ1Ss2S0

    注意:这是较旧的视频,现在有所变化但几乎相同。 [资产商店免费提供 TouchScript]

  2. 其他选项,在空游戏对象或相机中附加以下代码(添加标签层)

    使用System.Collections; 使用 System.Collections.Generic; 使用统一引擎; 使用 UnityEngine.UI;

    public 结构对象 { public Vector3 屏幕点; public Vector3偏移; }

    public class TouchInput : MonoBehaviour {

    public LayerMask touchInputMask;
    private static List<GameObject> touchList = new List<GameObject>();
    public static Dictionary<int,objectst> touchobjects = new Dictionary<int,objectst>();
    
    private GameObject[] touchesOld;
    private RaycastHit hit;
    public Text Count, IndexLift;
    
    private Vector3 targetPos;
    
    
    
    
    
    void Update () {
    
    
        int nbTouches = Input.touchCount;
    
        if(nbTouches > 0)
        {
            nbTouches = 5;
    
            print(nbTouches + " touch(es) detected");
    
            touchesOld = new GameObject[touchList.Count];
            touchList.CopyTo(touchesOld);
            touchList.Clear();
    
            for (int i = 0; i < nbTouches ; i++)
            {
    
    
                Touch touch = Input.GetTouch(i);
    
    
                print("Touch index " + touch.fingerId + " detected at position " + touch.position);
    
                Ray ray = Camera.main.ScreenPointToRay (touch.position);
    
    
                if (Physics.Raycast(ray, out hit, touchInputMask)){
                    GameObject recipient = hit.transform.gameObject;
                    touchList.Add(recipient);
    
                    //recipient.;
    
                    if (touch.phase == TouchPhase.Began){
    
                        objectst tempobj = new objectst ();
                        tempobj.screenPoint = Camera.main.WorldToScreenPoint (recipient.transform.position);
                        tempobj.offset = recipient.transform.position - Camera.main.ScreenToWorldPoint (new Vector3 (touch.position.x, touch.position.y, tempobj.screenPoint.z));           
    
                        touchobjects.Add(touch.fingerId,tempobj);
    
    
    
    
                    }
    
                    if (touch.phase == TouchPhase.Stationary || touch.phase == TouchPhase.Moved){
    
    
                        Vector3 curScreenPoint = new Vector3 (touch.position.x, touch.position.y,
                            touchobjects[touch.fingerId].screenPoint.z);
                        Vector3 curPosition = Camera.main.ScreenToWorldPoint (curScreenPoint) + touchobjects[touch.fingerId].offset;
                        recipient.transform.position = curPosition;
    
    
    
                    }
                    if (touch.phase == TouchPhase.Ended){
    
                        Vector3 curScreenPoint = new Vector3 (touch.position.x, touch.position.y,
                            touchobjects[touch.fingerId].screenPoint.z);
                        Vector3 curPosition = Camera.main.ScreenToWorldPoint (curScreenPoint) - touchobjects[touch.fingerId].offset;
                        recipient.transform.position = curPosition; 
    
                    }
                    if (touch.phase == TouchPhase.Canceled){
    
                    }
                }
    
    
            }
            foreach (GameObject g in touchesOld){
              if (!touchList.Contains(g)){
                    g.SendMessage("OnTouchExit",hit.point,SendMessageOptions.DontRequireReceiver);
            }
    
        }
        }
    
    }
    

    }