当前位置: 首页 > news >正文

【小松教你手游开发】【系统模块开发】根据上一个GameObject坐标生成的tips界面...

开发游戏,特别是mmo手游的时候经常需要开发的一个需求是,点击某个装备,在它附近的位置生成一个tips界面,介绍装备功能和各种信息。
【小松教你手游开发】【系统模块开发】根据上一个GameObject坐标生成的tips界面
像上面红色框框里的这个。

这个主要的问题是 根据点击的GameObject对应生成这个详情界面时,详情界面位置需要合理摆放(不能显示不到,不能遮挡等)

基本的思路是,

首先找到GameObject的position,

把手机屏幕大概分成四个象限,知道这个GameObject大概在这个屏幕的哪个象限(左上,左下,右上,右下)

根据象限来判断详情界面应该在GameObject的哪一边生成

(比如如果GameObject在右下,则详情界面应该在GameObject的左上方生成)

根据上面的position加上GameObject的宽的一半,加上自己界面的宽的一半,再加几个像素进行偏移,

这样就可以摆放好详情界面的位置。

不过这里有个比较重要的问题是,通常情况下,GameObject和自己的详情界面一般不会在同一个camera下。

所以这里首先解决的是要这两边的坐标撸通。

这里简单说一下,

在unity里基本上有4种坐标

世界坐标,相对坐标,屏幕坐标,相对屏幕0,0点坐标

由于我们要在Camera之前切换坐标,为了简化,我们不要去算世界坐标和相对坐标,通过屏幕坐标进行转化

意思就是,

找到GameObject的世界坐标,通过接口算出它自己Camera的屏幕坐标,把屏幕坐标传给详情界面,

详情界面通过把GameObject的屏幕坐标通过自己Camera的转化接口转化成世界坐标,摆放位置。

这样就能计算出在不同camera的情况下,屏幕上同一个点坐标的转化。

下面贴上代码

public void ResetPosition(GameObject relativeObject,Camera cam)  
{  

    //获取触发这个dialog的gameObject相对于屏幕的position  
    Vector3 relativePosition = cam.WorldToScreenPoint(relativeObject.transform.position);//通过世界坐标去获取  
    Vector3 relativePositionPercent = cam.WorldToViewportPoint(relativeObject.transform.position);//获取GameObject相对于屏幕0,0点的位置(x,y范围在0,1之间)  
    Vector3 newPosition = CDialogManager.Instance.GetCamera(eUIIndex.Index_OrthographicThree).ScreenToWorldPoint(relativePosition);//转回世界坐标摆放  
    m_mainGameObject.transform.position = newPosition;//先摆放position,之后再把总偏移值加上  

    Bounds realativeObjectBounds = NGUIMath.CalculateRelativeWidgetBounds(relativeObject.transform);//算出GameObject边框大小  
    float realativeObjectWidth = realativeObjectBounds.extents.x;  
    float realativeObjectHeight = realativeObjectBounds.extents.y;  

    Bounds objectBounds = NGUIMath.CalculateRelativeWidgetBounds(m_mainGameObject.transform);//算出自己边框大小  
    float objectWidth = objectBounds.extents.x;  
    float objectHeight = objectBounds.extents.y;  

    float spacingX = 5;//5像素偏移  
    float spacingY = 5;  

    float offsetX = 0;//总偏移  
    float offsetY = 0;  

    if (relativePositionPercent.x >= 0.5 && relativePositionPercent.y >= 0.7)//为了效果更好,y轴上分为上中下三个象限  
    {  
        offsetX =  -realativeObjectWidth - objectWidth - spacingX;  
        offsetY =  -realativeObjectHeight - objectHeight - spacingY;  

    }  
    else if(relativePositionPercent.x >= 0.5 && relativePositionPercent.y <= 0.3)  
    {  
        offsetX = -realativeObjectWidth - objectWidth - spacingX;  
        offsetY = realativeObjectHeight +objectHeight + spacingY;  
    }  
    else if (relativePositionPercent.x >= 0.5 && relativePositionPercent.y > 0.3 && relativePositionPercent.y < 0.7)  
    {  
        offsetX = -realativeObjectWidth - objectWidth - spacingX;  
        offsetY = 0;  
    }  
    else if (relativePositionPercent.x <= 0.5 && relativePositionPercent.y >= 0.7)  
    {  
        offsetX = realativeObjectWidth + objectWidth + spacingX;  
        offsetY = -realativeObjectHeight - objectHeight - spacingY;  

    }  
    else if (relativePositionPercent.x <= 0.5 && relativePositionPercent.y <= 0.3)  
    {  
        offsetX = realativeObjectWidth + objectWidth + spacingX;  
        offsetY = realativeObjectHeight + objectHeight + spacingY;  
    }  
    else if (relativePositionPercent.x <= 0.5 && relativePositionPercent.y > 0.3 && relativePositionPercent.y < 0.7)  
    {  
        offsetX = realativeObjectWidth + objectWidth + spacingX;  
        offsetY = 0;  
    }  
span style="white-space:pre">    </span>//最后通过相对坐标进行偏移  
    m_mainGameObject.transform.localPosition = new Vector3(m_mainGameObject.transform.localPosition.x + offsetX, m_mainGameObject.transform.localPosition.y + offsetY, 0);  
}  

这里有个问题要注意!!

可能在计算widget宽度的时候GameObject不在原点上。所以优化一下应该是这样:

Bounds realativeObjectBounds = NGUIMath.CalculateRelativeWidgetBounds(relativeObject.transform);//算出GameObject边框大小  
    float realativeObjectWidth = realativeObjectBounds.extents.x - realativeObjectBounds.center.x;  
    float realativeObjectHeight = realativeObjectBounds.extents.y - realativeObjectBounds.center.y;  

    Bounds objectBounds = NGUIMath.CalculateRelativeWidgetBounds(m_mainGameObject.transform);//算出自己边框大小  
    float objectWidth = objectBounds.extents.x - objectBounds.center.x;  
    float objectHeight = objectBounds.extents.y - objectBounds.center.y;

转载于:https://blog.51cto.com/13638120/2084880

相关文章:

  • 观察者模式在One Order回调函数中的应用
  • grep sed awk 练习题
  • #define与typedef区别
  • Linux下命令设置别名--alias(同实用于mac)
  • Eclipse/MyEclipse导入导出注释模板
  • 正则介绍以及grep
  • AI的故事:半人马的诞生之路
  • 共享单车引发秩序问题增多,政府正在研究相关管理办法
  • web后台过程
  • 0314-布局遇到的问题(山东理工大)
  • java多线程处理导入数据拆分List集合 同步处理插入数据
  • 1011. A+B和C (15)
  • Pandora.js 视频介绍
  • display和position的值与用途
  • 吊销***用户
  • [ JavaScript ] 数据结构与算法 —— 链表
  • [Vue CLI 3] 配置解析之 css.extract
  • 【css3】浏览器内核及其兼容性
  • Android系统模拟器绘制实现概述
  • C++入门教程(10):for 语句
  • ECMAScript入门(七)--Module语法
  • Flex布局到底解决了什么问题
  • JS字符串转数字方法总结
  • Laravel 中的一个后期静态绑定
  • Spring框架之我见(三)——IOC、AOP
  • ⭐ Unity 开发bug —— 打包后shader失效或者bug (我这里用Shader做两张图片的合并发现了问题)
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 彻底搞懂浏览器Event-loop
  • 发布国内首个无服务器容器服务,运维效率从未如此高效
  • 机器学习中为什么要做归一化normalization
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 如何实现 font-size 的响应式
  • 如何使用Mybatis第三方插件--PageHelper实现分页操作
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 扩展资源服务器解决oauth2 性能瓶颈
  • #php的pecl工具#
  • #在线报价接单​再坚持一下 明天是真的周六.出现货 实单来谈
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (003)SlickEdit Unity的补全
  • (32位汇编 五)mov/add/sub/and/or/xor/not
  • (C语言)共用体union的用法举例
  • (Qt) 默认QtWidget应用包含什么?
  • (安全基本功)磁盘MBR,分区表,活动分区,引导扇区。。。详解与区别
  • (附源码)spring boot北京冬奥会志愿者报名系统 毕业设计 150947
  • (附源码)springboot青少年公共卫生教育平台 毕业设计 643214
  • (亲测成功)在centos7.5上安装kvm,通过VNC远程连接并创建多台ubuntu虚拟机(ubuntu server版本)...
  • (算法)前K大的和
  • (一)使用Mybatis实现在student数据库中插入一个学生信息
  • (原創) 物件導向與老子思想 (OO)
  • (转)Android学习笔记 --- android任务栈和启动模式
  • (转)jdk与jre的区别
  • (转)Mysql的优化设置
  • (轉貼) UML中文FAQ (OO) (UML)
  • **CI中自动类加载的用法总结
  • ... 是什么 ?... 有什么用处?