• Unity3D的几种坐标系


    1. World Space(世界坐标):我们在场景中添加物体(如:Cube),他们都是以世界坐标显示在场景中的。transform.position可以获得该位置坐标。            
    2. Screen Space(屏幕坐标,鼠标坐标):以像素来定义的,以屏幕的左下角为(0,0)点,右上角为(Screen.width,Screen.height),Z的位置是以相机的世界单位来衡量的。注:鼠标位置坐标属于屏幕坐标,Input.mousePosition可以获得该位置坐标,手指触摸屏幕也为屏幕坐标,Input.GetTouch(0).position可以获得单个手指触摸屏幕坐标。

    3. ViewPort Space(视口坐标):视口坐标是标准的和相对于相机的。相机的左下角为(0,0)点,右上角为(1,1)点,Z的位置是以相机的世界单位来衡量的。(用的不多,反正我暂时没有用到~呵呵~)

    4. 绘制GUI界面的坐标系:这个坐标系与屏幕坐标系相似,不同的是该坐标系以屏幕的左上角为(0,0)点,右下角为(Screen.width,Screen.height)。

    5. LineRender坐标:以屏幕中心为原点,向上向右增加。
    • 世界坐标→屏幕坐标:camera.WorldToScreenPoint(transform.position);这样可以将世界坐标转换为屏幕坐标。其中camera为场景中的camera对象。

    • 屏幕坐标→视口坐标:camera.ScreenToViewportPoint(Input.GetTouch(0).position);这样可以将屏幕坐标转换为视口坐标。其中camera为场景中的camera对象。

    • 视口坐标→屏幕坐标:camera.ViewportToScreenPoint();

    • 视口坐标→世界坐标:camera.ViewportToWorldPoint();

    案例1——在鼠标点击的位置上绘制一张图片出来(关于绘制GUI界面坐标系与屏幕坐标系之间的关系)。

    using UnityEngine;
    using System.Collections;
    
    public class ScreenToGUI : MonoBehaviour {
    
        // Use this for initialization
        void Start () {
        
        }
        
        // Update is called once per frame
        void Update () {
        
        }
      
          //图片  
        public Texture img;    
         //储存鼠标的位置坐标    
        private Vector2 pos;
        void OnGUI()
        {
            //鼠标左击,获取当前鼠标的位置       
            if (Input.GetMouseButton(0))
            {
                pos = Input.mousePosition; //屏幕坐标
            }
            //绘制图片,屏幕坐标和GUI界面坐标只在Y轴上方向相反,只要被Screen.height减就可以互相转换。      
            GUI.DrawTexture(new Rect(pos.x, Screen.height - pos.y, 100, 100), img);
        }
    
    }

    案例2——角色头顶的名字(世界坐标转GUI界面坐标)

    先世界坐标转屏幕坐标,再屏幕坐标转GUI界面坐标

    代码如下:

    using UnityEngine;
    using System.Collections;
    
    public class Blood : MonoBehaviour {
        public static float ScaleWidht = 0f;
        public static float ScaleHeight = 0f;
        private Rect _drawRect = new Rect();
        public float Width = 0f;
        public float Height = 10f;
        public const float DesignStageWidth = 800;
        public const float DesignStageHeight = 480;
    
        public Vector2 pos2;
        public float size_z;
        // Use this for initialization
        void Start () {
            ScaleWidht = Screen.width / DesignStageWidth;
            ScaleHeight = Screen.height / DesignStageHeight;
            Height = 2f;
    
            size_z = transform.gameObject.collider.bounds.size.z;
        }
    
    
        // Update is called once per frame
        void Update () {
            //世界坐标转换到屏幕坐标
            print(transform.forward);
            pos2 = Camera.main.WorldToScreenPoint(transform.position + transform.forward * (size_z / 2)); 
            //计算角色头顶坐标
            pos2 = new Vector2(pos2.x, Screen.height  - pos2.y - Height); 
    
    
    
            //Vector3 worldPosition = new Vector3(transform.position.x, transform.position.y + Height, transform.position.z);
            //worldPosition = Camera.mainCamera.WorldToScreenPoint(worldPosition);
            //_drawRect = new Rect((worldPosition.x - 100 * ScaleWidht) / ScaleWidht, (Screen.height - worldPosition.y - 50 * ScaleHeight) / ScaleHeight, 200, 50);
        }
    
        void OnGUI()
        {
            //GUILayout.BeginArea(_drawRect);
            //    GUILayout.Label("======哈哈======");
            //GUILayout.EndArea();
    
            GUI.Label(new Rect(pos2.x, pos2.y, 100, 50), "=BETTER=");
        }
    }

     案例3——类似屏幕解锁功能的实现(屏幕坐标转换为世界坐标)

    首先是创建LineRenderer。GameObject -> Create Empty ->更名为“LineRendererObj”,

    给LineRendererObj添加“Line Renderer”组件,Component ->Effects ->Line Renderer;

    将它的Positions 的size 设置为0

    接下来是代码touch.CS:

    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    
    public class touch : MonoBehaviour {
        private Event e;
    
        public Texture2D Point;
        public Color c1 = Color.yellow;
        public Color c2 = Color.red;
        public int lengthOfLineRenderer;
        public GameObject LineRendererPrefab;
    
        private LineRenderer lineRenderer;
        /// <summary>
        /// 保存创建的Line Renderer
        /// </summary>
        private List<LineRenderer> lineRendArray =new List<LineRenderer>();
    
        private Vector3 screenPoint;
        private Vector3 scanPos;
    
        private Color[] color;
    
        /// <summary>
        /// 记录宫格所在GUI位置
        /// </summary>
        public List<Rect> AreaRect = new List<Rect>();
        /// <summary>
        /// 记录宫格中心点
        /// </summary>
        public List<Vector2> CenterPointList = new List<Vector2>();
        /// <summary>
        /// 宫格标签
        /// </summary>
        public int RectFlag;
        /// <summary>
        /// 记录正确的滑动顺序
        /// </summary>
        public List<int> KeyOrder = new List<int>();
        /// <summary>
        /// 记录玩家滑动顺序
        /// </summary>
        public List<int> PlayerKeyOrder = new List<int>();
    
        /// <summary>
        /// 判断开始鼠标位置是否可画
        /// </summary>
        public bool CheckStartRect=false;
    
        /// <summary>
        /// 判断结束鼠标位置是否可画
        /// </summary>
        public bool CheckEndRect = false;
    
        /// <summary>
        /// 行数
        /// </summary>
        public int Row = 4;
        /// <summary>
        /// 列数
        /// </summary>
        public int Column = 4;
    
        void Start()
        {
            e = Event.current;
    
            scanPos = LineRendererPrefab.transform.position;
            lineRenderer = (LineRenderer)LineRendererPrefab.GetComponent("LineRenderer");
            lineRenderer.material = new Material(Shader.Find("Particles/Additive"));
            lengthOfLineRenderer = 0;
            lineRenderer.SetColors(c1, c2);
            lineRenderer.SetWidth(0.7F, 0.7F);
            lineRenderer.SetVertexCount(0);
    
            color = new Color[8];
            color[0] = Color.yellow;
            color[1] = Color.blue;
            color[2] = Color.cyan;
            color[3] = Color.gray;
            color[4] = Color.green;
            color[5] = Color.grey;
            color[6] = Color.magenta;
            color[7] = Color.red;
    
            for (int RowCount = 0; RowCount < Row; RowCount++)
            {
                for (int columnCount = 0; columnCount < Column; columnCount++)
                {
                    Rect IconRect = new Rect(columnCount * Screen.width / Column + Screen.width / Column / 2 - Point.width / 2, RowCount * Screen.height / Row + Screen.height / Row / 2 - Point.height / 2, Point.width, Point.height);
                    AreaRect.Add(IconRect);
    
                    Vector2 CenterP = IconRect.center;//得到每个的中心点
                    CenterPointList.Add(CenterP);
                }
            }
        }
    
        void OnGUI()
        {
            e = Event.current;
            for (int RowCount = 0; RowCount < Row; RowCount++)
            {
                for (int columnCount = 0; columnCount < Column; columnCount++)
                {
                    Rect IconRect = new Rect(columnCount * Screen.width / Column + Screen.width / Column / 2 - Point.width / 2, RowCount * Screen.height / Row + Screen.height / Row / 2 - Point.height / 2, Point.width, Point.height);
                    GUI.Label(IconRect, Point);
                }
            }
        }
    
        void Update()
        {
            if (e != null)
            {
                if (e.type == EventType.MouseDown)
                {
                    for (int i = 0; i < AreaRect.Count; i++)
                    {
                        if (AreaRect[i].Contains(new Vector3(Input.mousePosition.x, Screen.height - Input.mousePosition.y, Input.mousePosition.z)))
                        {
                            CheckStartRect = true;
                            print("Contains");
                            PlayerKeyOrder.Add(i);
                            RectFlag = i;
                            break;
                        }
                        else
                        {
                            CheckStartRect = false;
                        }
                    }
    
                    if (CheckStartRect)
                    {
                        print("MouseDown_____");
    
                        //Vector3 curPosition = mousePToLineRendererP(); 
                        Vector3 curPosition = centerPToLineRendererP(RectFlag);
                        GameObject newObj;
                        newObj = (GameObject)Instantiate(LineRendererPrefab, LineRendererPrefab.transform.position, LineRendererPrefab.transform.rotation);
                        lineRenderer = (LineRenderer)newObj.GetComponent("LineRenderer");
    
                        int n = Random.Range(1, 8);
                        c1 = color[n - 1];
                        n = Random.Range(1, 8);
                        c2 = color[n - 1];
                        lineRenderer.SetColors(c1, c2);
    
                        lineRenderer.SetVertexCount(1);
                        lineRenderer.SetWidth(0.7F, 0.7F);
                        lineRenderer.SetPosition(0, curPosition);
                        lineRendArray.Add(lineRenderer);
                        lengthOfLineRenderer++;
                    }
                }
    
                if (e.type == EventType.MouseDrag&&CheckStartRect)
                {
                    print("MouseDrag_____");
                    Vector3 curPosition = mousePToLineRendererP(); 
                    DrawRenderLine(lineRendArray[lengthOfLineRenderer - 1], curPosition);
                }
    
                if (e.type == EventType.MouseUp && CheckStartRect)
                {
                    for (int i = 0; i < AreaRect.Count; i++)
                    {
                        if (AreaRect[i].Contains(new Vector3(Input.mousePosition.x, Screen.height - Input.mousePosition.y, Input.mousePosition.z)))
                        {
                            CheckEndRect = true;
                            PlayerKeyOrder.Add(i);
                            RectFlag = i;
                            print("EndContains");
                            break;
                        }
                        else
                        {
                            CheckEndRect = false;
                        }
                    }
    
                    if (CheckEndRect)
                    {
                        Vector3 curPosition = centerPToLineRendererP(RectFlag);
                        DrawRenderLine(lineRendArray[lengthOfLineRenderer - 1], curPosition);
                    }
                    else
                    {
                        PlayerKeyOrder.RemoveAt(PlayerKeyOrder.Count - 1);
                        Destroy(lineRendArray[lengthOfLineRenderer - 1].gameObject);
                        //lengthOfLineRenderer--;
                    }
    
                }
            }        
        }
    
        void DrawRenderLine(LineRenderer line, Vector3 vect3)
        {
            Vector3 newPos = vect3;
            line.SetVertexCount(2);
    
            line.SetPosition(1, newPos);
            print("new point: " + newPos);
        }
    
        //public Vector2 RectCenterPoint(Rect AreaRect)       //计算一个Rect的中心点
        //{
        //    Vector2 CenterPoint=Vector2.zero;
        //    print("Rect:"+AreaRect);
        //    CenterPoint.x=AreaRect.xMin+AreaRect.width/2;
            
        //    CenterPoint.y=AreaRect.yMin+AreaRect.height/2;
        //    print("CenterPoint:"+CenterPoint);
        //    return CenterPoint;
        //}
    
        /// <summary>
        /// 鼠标所在位置转换为LineRenderer的位置
        /// </summary>
        /// <returns></returns>
        public Vector3 mousePToLineRendererP()      
        {
            screenPoint = Camera.main.WorldToScreenPoint(scanPos);
            Vector3 curScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z);
            Vector3 curPosition = Camera.main.ScreenToWorldPoint(curScreenPoint);
            print("curScreenPoint: " + curScreenPoint);
            print("curPosition: " + curPosition);
            return curPosition;
        }
    
        /// <summary>
        /// 鼠标所在区域的中心点转换为LineRenderer的位置
        /// </summary>
        /// <returns></returns>
        public Vector3 centerPToLineRendererP(int Flag)
        {
            screenPoint = Camera.main.WorldToScreenPoint(scanPos);
            Vector3 curScreenPoint = new Vector3(CenterPointList[Flag].x,Screen.height-CenterPointList[Flag].y,screenPoint.z);
            Vector3 curPosition = Camera.main.ScreenToWorldPoint(curScreenPoint);
            print("curScreenPoint: " + curScreenPoint);
            print("curPosition: " + curPosition);
            return curPosition;
        }
    }

    把touch.CS绑定在Camera上,设置如下:

     运行后可以任意点间连线,如图:

  • 相关阅读:
    js---查找数组中的最大值(最小值),及相应的下标
    JS数组遍历的几种方法
    在 forEach 中使用 async/await 遇到的问题
    js 事件冒泡和事件捕获
    JS中dom0级事件和dom2级事件的区别介绍
    Vue集成Ueditor
    vue富文本编辑器 Vue-Quill-Editor
    Redis问题1---redis满了怎么办
    jQuery火箭图标返回顶部代码
    遇到的小问题
  • 原文地址:https://www.cnblogs.com/martianzone/p/3371789.html
Copyright © 2020-2023  润新知