Unity3D的几种坐标系,以及屏幕解锁类似功能

7 篇文章 0 订阅
 

World Space(世界坐标):我们在场景中添加物体(如:Cube),他们都是以世界坐标显示在场景中的。transform.position可以获得该位置坐标。

  Screen Space(屏幕坐标,鼠标坐标):以像素来定义的,以屏幕的左下角为(0,0)点,右上角为(Screen.width,Screen.height),Z的位置是以相机的世界单位来衡量的。注:鼠标位置坐标属于屏幕坐标,Input.mousePosition可以获得该位置坐标,手指触摸屏幕也为屏幕坐标,Input.GetTouch(0).position可以获得单个手指触摸屏幕坐标。

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

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

  LineRender坐标:以屏幕中心为原点,向上向右增加。

  世界坐标→屏幕坐标:camera.WorldToScreenPoint(transform.position);这样可以将世界坐标转换为屏幕坐标。其中camera为场景中的camera对象。

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

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

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

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

  using  unity Engine;

  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 Texture 2D  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 .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.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上,设置如下:

 


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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值