【问题标题】:How to change from an object on canvas RectTransform coordinates to screen coordinates?如何从画布上的对象 RectTransform 坐标更改为屏幕坐标?
【发布时间】:2019-11-07 18:07:37
【问题描述】:

我有这段代码正在更新:

    if (Input.touchCount > 0)
    {
        Touch touch = Input.GetTouch(0);

        if(touch.phase == TouchPhase.Began)
        {
            touchPosition = touch.position;

            if(arRaycastManager.Raycast(touchPosition, hits, UnityEngine.XR.ARSubsystems.TrackableType.PlaneWithinPolygon))
            {
                Pose hitPose = hits[0].pose;//ok
            }
        }
     }

但现在我必须使用操纵杆让指针在屏幕上移动,然后按下按钮来做某事。

像这样:

    float h = Input.GetAxis("Horizontal");
    float v = Input.GetAxis("Vertical");
    fakeFinger.GetComponent<RectTransform>().anchoredPosition += new 
    Vector2(h * vel * Time.deltaTime, v * vel * Time.deltaTime);
    //this move a pointer on my screen... I had to use RectTransform... dont know if its right

    if (considerjoystickbuttonpressedok)
    {
        touchPosition = new Vector2(fakeFinger.GetComponent<RectTransform>().anchoredPosition.x,
                                    fakeFinger.GetComponent<RectTransform>().anchoredPosition.y);
         //still dont know if its right above...

        if (arRaycastManager.Raycast(touchPosition, hits, UnityEngine.XR.ARSubsystems.TrackableType.PlaneWithinPolygon))
        {
            Pose hitPose = hits[0].pose;//NOT OK!
        }
    }

关于如何解决这个问题的任何想法?

【问题讨论】:

    标签: c# unity3d canvas


    【解决方案1】:
    public Vector3 GetScreenPosition()
    {
        RectTransform rectTransform = (RectTransform)transform;
        Vector4 worldLocation = transform.localToWorldMatrix * new Vector4(rectTransform.anchoredPosition3D.x,
                                                       rectTransform.anchoredPosition3D.y,
                                                       rectTransform.anchoredPosition3D.z,
                                                       1);
    
        return yourCamera.WorldToScreenPoint(new Vector3(worldLocation.x, worldLocation.y, worldLocation.z));
    }
    

    【讨论】:

    • 您好@Brian 先生,谢谢您的回答。它帮助我找到了方向,但还没有完全完成。请看这张图片:ibb.co/VLTGnzF 这里我们有一个“触摸开始”和一个“触摸结束”位置,点击屏幕,我在那里测量我的 Mac,“手指距离”,没问题。我使用操纵杆将指针(手指)放在世界上相同的位置,测量我的 Mac。在左边,所以我们有“欢乐开始”和“欢乐结束”的位置......以及“欢乐的距离”。完全不同...但是迄今为止最好的结果...我将使用另一个注释来放置代码:
    • 哦,天哪,无法将代码发布为评论,回答了我自己的问题...我认为 stackoverflow 社区会杀了我...
    • 无论如何,我将 GetScreenPosition() 方法更改为我能得到的最好的方法,这是制作上面截图的版本。我想我误解了使用哪个转换
    【解决方案2】:
        using System.Collections.Generic;
        using UnityEngine;
        using UnityEngine.XR.ARFoundation;
    
        public class SomeClassOnMyARSessionOriginThatContainsMyARCamera : MonoBehaviour
        {     
         public ARCameraManager arCameraManager;//its another child go
         public ARRaycastManager arRaycastManager;
         private static List<ARRaycastHit> hits = new List<ARRaycastHit>();
         private Vector2 touchPosition = default;
    
         public GameObject startPoint;
         public GameObject endPoint;
         public GameObject startPointbyJoy;
         public GameObject endPointbyJoy;
    
         public GameObject finger;//It´s a UICanvas
         public float vel;
    
         void Update()
         {        
            float h = Input.GetAxis("Horizontal");
            float v = Input.GetAxis("Vertical");
            finger.GetComponent<RectTransform>().anchoredPosition += new Vector2(h * vel * Time.deltaTime, v * vel * Time.deltaTime);
    
            if (Input.GetKey(KeyCode.JoystickButton13))
            {
                Vector3 fingerScreenPos = GetScreenPosition(finger);
                touchPosition = new Vector2(fingerScreenPos.x, fingerScreenPos.y);//here I use that method
    
                if (arRaycastManager.Raycast(touchPosition, hits, UnityEngine.XR.ARSubsystems.TrackableType.PlaneWithinPolygon))
                {
                    startPointbyJoy.SetActive(true);
                    Pose hitPose = hits[0].pose;
                    startPointbyJoy.transform.SetPositionAndRotation(hitPose.position, hitPose.rotation);
                }
            }
            if (Input.GetKey(KeyCode.JoystickButton12))
            {            
                Vector3 fingerScreenPos = GetScreenPosition(finger);
                touchPosition = new Vector2(fingerScreenPos.x, fingerScreenPos.y);//here I use that method
    
                if (arRaycastManager.Raycast(touchPosition, hits, UnityEngine.XR.ARSubsystems.TrackableType.PlaneWithinPolygon))
                {
                    endPointbyJoy.SetActive(true);
                    Pose hitPose = hits[0].pose;
                    endPointbyJoy.transform.SetPositionAndRotation(hitPose.position, hitPose.rotation);
                }
            }
    
            if (Input.touchCount > 0)//these are OK
            {
                Touch touch = Input.GetTouch(0);
                if (touch.phase == TouchPhase.Began)
                {
                    touchPosition = touch.position;
                    if (arRaycastManager.Raycast(touchPosition, hits, UnityEngine.XR.ARSubsystems.TrackableType.PlaneWithinPolygon))
                    {
                        startPoint.SetActive(true);
                        Pose hitPose = hits[0].pose;
                        startPoint.transform.SetPositionAndRotation(hitPose.position, hitPose.rotation);
    
                    }
                }
                if(touch.phase == TouchPhase.Moved)
                {
                    touchPosition = touch.position;                
                    if(arRaycastManager.Raycast(touchPosition, hits, UnityEngine.XR.ARSubsystems.TrackableType.PlaneWithinPolygon))
                    {                    
                        endPoint.SetActive(true);
                        Pose hitPose = hits[0].pose;
                        endPoint.transform.SetPositionAndRotation(hitPose.position, hitPose.rotation);
                    }
                }
            }
        }
    
        public Vector3 GetScreenPosition(GameObject finger)
        {
        //HERE. Which "transform" should I get? The UICancas finger?
        //The go this script is attached to?
            RectTransform rectTransform = (RectTransform)finger.transform;
            Vector4 worldLocation = rectTransform.localToWorldMatrix * new  Vector4(rectTransform.anchoredPosition3D.x,
                                                            rectTransform.anchoredPosition3D.y,
                                                            rectTransform.anchoredPosition3D.z,
                                                           1);
    
            //is it different using a arcamera?
            return arCameraManager.GetComponent<Camera>().WorldToScreenPoint(new Vector3(worldLocation.x, worldLocation.y, worldLocation.z));
         }
        }
    

    【讨论】:

    • 是的,如果我这样做是正确的,我会做和你在这里做的一样的事情。我会使用更改脚本之类的代码作为“RectTransform rectTransform = finger.transform”,但没关系。
    猜你喜欢
    • 2015-08-01
    • 2013-02-24
    • 1970-01-01
    • 1970-01-01
    • 2017-03-04
    • 2021-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多