【Unity3D】世界坐标转屏幕坐标的坑

本菜鸟是今年2019年毕业,正式走向游戏开发岗位三个月的大萌新。每天忙着和策划各种撕逼,实现各种脑残设计,其中就遇到不少值得罗缕纪存的坑,现在就开始写下了供后来的学习者跳坑。
策划之前提了一个玩家目标指示器需求,箭头始终指向玩家点击的目标在屏幕上的位置。接到需求第一个想法是直接将目标单位的世界坐标转换成ugui的屏幕坐标,使用unity自带的坐标转换函数转换就行了。
ugui以左下角为坐标原点(0,0),向上为y轴正半轴,向右为x轴正半轴。所以先计算目标的屏幕坐标和玩家摄像机屏幕中心坐标的两点之间的角度angle,通过判断目标屏幕坐标相对于摄像机屏幕中心位于哪个象限,处理之前计算的angle差值(ugui图片的角度是逆时针从0到360)。

//将目标世界坐标转换成ugui屏幕坐标
Vector3 target_ScreenPoint = Camera.main.WorldToScreenPoint(m_target.position);
//计算target_ScreenPoint和屏幕中心点的绝对值角度float angle = Mathf.Atan(Mathf.Abs(target_ScreenPoint.y - Screen.height / 2)/ Mathf.Abs(target_ScreenPoint.x - Screen.width / 2)) * 180 / Mathf.PI;//通过判断target_ScreenPoint相对屏幕中心点所在象限处理angle的差值
if (target_ScreenPoint.x <= Screen.width / 2)angle = target_ScreenPoint.y >= Screen.height / 2 ? 90 - angle : 90 + angle;
elseangle = target_ScreenPoint.y >= Screen.height / 2 ? 270 + angle : 270 - angle;Vector3 euler = m_arrow.eulerAngles;
euler.z = angle;
//设置箭头的角度
m_arrow.eulerAngles = euler;

下面是效果图


箭头指示器始终指向目标在屏幕显示的位置,是不是很完美无缺。但狗策划测试发现个问题,当目标不在屏幕内,玩家转动到某些角度时候,箭头指示器会指向相反方向。如下图所示


此时目标不在屏幕范围内,在人物左边,转换成的屏幕坐标x值为负也正常,但当人物继续向右转动后出现下图问题了。

指向箭头刚才还指向左边,现在指向右边相反方向了,目标转换成的屏幕左边x值也变成正的了,所以这时候需要把箭头角度改成对角相反的方向。至于什么时候改了,需要通过判断当目标在摄像头左边但指示箭头角度大于180度和当目标在摄像头右边但指示箭头角度小于180时候转换即可,最后达到了真正完美的效果图如下。


这回即使旋转一周箭头位置都没任何问题,最后上完整代码

using UnityEngine;public class GuideUICtl : MonoBehaviour
{public Transform m_target;                  //指向目标public RectTransform m_arrow;               //UI箭头Vector3 m_Screen_Center;private void Start(){m_Screen_Center = new Vector3(Screen.width / 2, Screen.height / 2, 0);}void Update() {//将目标的世界坐标转换成屏幕坐标Vector3 target_ScreenPoint = Camera.main.WorldToScreenPoint(m_target.position);//计算target_ScreenPoint和屏幕中心点的绝对值角度float angle = Mathf.Atan(Mathf.Abs(target_ScreenPoint.y - Screen.height / 2)/ Mathf.Abs(target_ScreenPoint.x - Screen.width / 2)) * 180 / Mathf.PI;//通过判断target_ScreenPoint相对屏幕中心点所在象限处理angle的差值if (target_ScreenPoint.x <= Screen.width / 2)angle = target_ScreenPoint.y >= Screen.height / 2 ? 90 - angle : 90 + angle;elseangle = target_ScreenPoint.y >= Screen.height / 2 ? 270 + angle : 270 - angle;#region  计算摄像机和目标的叉乘//以屏幕中心所在的单位向量为起始向量from,并将from的y值设成和目标y值保持一致Vector3 from = Camera.main.transform.forward;from.y = m_target.forward.y;//将屏幕中心坐标转换成世界坐标Vector3 cameraPos = Camera.main.ScreenToWorldPoint(m_Screen_Center);cameraPos.y = m_target.position.y;//求出目标点与摄像机之间的向量Vector3 to = m_target.position - cameraPos;//求出两向量之间的叉乘Vector3 cross = Vector3.Cross(from, to);#endregion//根据叉乘求出带符号的角度//cross.y > 0:目标向量位于起始向量右侧//cross.y < 0:目标向量位于起始向量左侧if (cross.y > 0 && angle < 180)angle += 180;else if (cross.y < 0 && angle > 180)angle -= 180;Vector3 euler = m_arrow.eulerAngles;euler.z = angle;//设置箭头的角度m_arrow.eulerAngles = euler;}
}

Unity3D 世界坐标转屏幕坐标的坑相关推荐

  1. 【Unity3D】世界坐标与屏幕坐标

    Unity3D由于是在三维世界中编程,而最终的结果是需要反馈到肉眼所示的2D屏幕之上的.这就产生了一种比较需要考虑的问题,尤其在一些涉及屏幕与Unity3D的3D世界交互的情况.网络上对于这方面的文字 ...

  2. 【Unity3D日常开发】Unity3D中实现屏幕坐标和3维空间坐标的转化

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有 ...

  3. Unity3D最佳实践:避坑技巧

    以下总结一部分来自经验之谈,一部分来自其他人的分享.总的来讲,Unity开发原型和效果.验证想法,确实是无比便利.可能一个月就把核心玩法做得差不多.强大的编辑器功能让我们也有很大的可扩展空间来协助我们 ...

  4. Cocos Creator 世界坐标转屏幕坐标

    Cocos creator某一坐标转屏幕坐标(screen position),以前都是屏幕坐标转世界坐标. 先上代码为敬(只是提供一种思路,有更好的实现和建议欢迎留言) //Scene的设计分辨率是 ...

  5. Android:AS与Unity3D之间打包的各种坑及解决方案

    作者:DrkCore (http://blog.csdn.net/DrkCore)  原文链接:(http://blog.csdn.net/drkcore/article/details/520793 ...

  6. Unity3D Content Size Fitter的坑

    Content Size Fitter 如果设置了水平或垂直的约束 那么rect组件在Awake Start阶段 width或高的值为0 如图:设置了垂直方向上的约束 在awake start 时 h ...

  7. unity3d序列帧动画无法显示坑

    序列帧动画不能放在canvas2d节点的子节点下,否则不能显示.就算改了sprite 的(pixel unit)属性改变大小等,也只是在编辑环境下看得见,且还有透明度,实际运行中完全看不见. 序列帧动 ...

  8. [Unity][UGUI][NGUI]地图指示UI屏幕边缘显示

    UGUI和NGUI 的屏幕坐标 指示UI 的localRotation.z NGUI NGUI_ui.transform.localPosition = new Vector3(x, y, 0); U ...

  9. ThreeJS 屏幕坐标与世界坐标互转

    文章目录 屏幕坐标系和标准设备坐标 屏幕坐标转世界坐标 世界坐标转屏幕坐标   要理解坐标系间的转换过程,需要提前了解: ThreeJS 中的几种坐标系 屏幕坐标系和标准设备坐标系   不想看链接中的 ...

  10. 【浅墨Unity3D Shader编程】之一 夏威夷篇:游戏场景的创建 第一个Shader的书写

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/40723789 作者:毛星云(浅墨) ...

最新文章

  1. Gartner预测:2025年,人工智能将创造200万个新增就业机会
  2. Xcode 6.x 上开发APP 兼容 iOS7
  3. 使用Mock.js进行独立于后端的前端开发
  4. C++二进制数字相加用字符串返回的算法实现(附完整源码)
  5. PHP增加$_ENV变量
  6. Android 百度地图之全局搜索周边搜索全国搜索城市路线规划(升级版附源码)
  7. mapbox 加载json数据 和数据中颜色 和高度 并根据数值加载颜色
  8. 以ontouch为例说明android事件发送机制
  9. BFS和DFS的java实现
  10. CentOS6和CentOS7进入单用户模式重置root密码
  11. java 上传文件接口_Java接口实现文件上传
  12. css实现剪切蒙版,CSS3“蒙版(剪切路径)”: clip-path
  13. 你知道视频怎么去水印吗?试试这三个方法学会怎么去视频水印
  14. tb6600 两相四线步进电机相关参数计算关系
  15. php利用堆栈 实现高级计算器
  16. 这个世界,总是被设计得刚刚好?人类或许只是被设定的一个程序
  17. 镭神16线激光雷达使用
  18. 火车头怎么采集图片-火车头采集图片并保存本地化
  19. 各品牌网络监控摄像头RTSP地址查询
  20. sql语句 如果为空值显示为0

热门文章

  1. Kindle3 升级
  2. 【OR】YALMIP 几何规划
  3. 大华出入口管理系统H710服务器配置,DH-DSS-H710S2 大华出入口综合管理系统 人员车辆管理车场收费...
  4. 维修电工技师、高级技师技能实训考核装置
  5. cnpm 安装文件找不到_技术员修复 win7系统word2013找不到标尺工具的处理办法 -win7系统使用教程...
  6. MDUI登陆注册案例
  7. 小写字母转大写代码HTML,CSS控制转换字母的大写和小写
  8. myeclipse编写的html页面乱码问题
  9. 【软件测试基础】文档测试
  10. css 入场动画_进入css3动画世界(一)