3D物体在UGUI下的坐标映射

3D物体在UGUI下的坐标映射

这个标题着实不好取。举例,譬如怪物的血条总是跟随者怪物移动而移动,因而我们需要实时的更新这个血条的坐标。类似的,还有很多应用场景。归结起来就如标题所示–“3D物体在UGUI下的坐标映射”。其实并不 难,只是实际工作中发现经常用到,故总结为一个工具函数,方便以后工作使用。
下面看我在 UGUI的Canvas下是如何实现的。

关于坐标转换,肯定离不开相机,我们先来考虑相机。毫无疑问,我们将3D场景物体的坐标转换为UI 层级下的坐标,肯定需要两个相机,一个是SceneCamera,一个是UICamera。这里值得注意的是UICamera需要设置成正交相机.当然,你的UI相机也可以是透视相机,但是在做坐标转换的时候就会复杂一些,有需要的时候再考虑,暂时考虑通用性比较高的。当然,SceneCamera就必须是透视相机了。

ui相机设置

归纳

以下是具体代码,主要是思路还是把3D物体的世界坐标转换为视口坐标,然后在UI相机之下,把该视口坐标转换为Canvas下的世界坐标,赋给UI对象,并校正Z轴。提供UI对象位置偏移的重载。

using UnityEngine;
using System.Collections;

    public class Utility {
        /// <summary>
        /// Correct the position of the ui object to the specified 3D position in scene. 
        /// </summary>
        public static void ScenePositionToUIPosition( Camera sceneCamera, 
                                                      Camera uiCamera, 
                                                      Vector3 posInScene, 
                                                      Transform uiTarget){
            Vector3 viewportPos =   sceneCamera.WorldToViewportPoint( posInScene );//unify the position to viewport point.
            Vector3 worldPos = uiCamera.ViewportToWorldPoint( viewportPos );
            uiTarget.position = worldPos;//set world position.
            Vector3 localPos = uiTarget.localPosition;
            localPos.z = 0f;//ignore z axis offset.
            uiTarget.localPosition = localPos;//correct the local position of the ui target.
    }

        /// <summary>
        /// Correct the position of the ui object to the specified 3D position      in scene. 
        /// </summary>
        public static void ScenePositionToUIPosition( Camera sceneCamera, 
                                                      Camera uiCamera, 
                                                      Vector3 posInScene, 
                                                      Transform uiTarget, 
                                                      Vector2 offset){
            ScenePositionToUIPosition( sceneCamera, uiCamera, posInScene, uiTarget );
            uiTarget.localPosition += (Vector3)offset;
        }
    }

例子

我们希望UI 随着球体运动而运动,且在球体上方偏移一定长度。
场景

using UnityEngine;
using System.Collections;

    public class Test : MonoBehaviour {
        public Camera UICamera;
        public Camera SceneCamera;
        public Transform TargetSceneObj;
        public Transform TargetUIObj;

        // Update is called once per frame
        void Update () {    
            Utility.ScenePositionToUIPosition( SceneCamera,
                                               UICamera,
                                               TargetSceneObj.position, 
                                               TargetUIObj,
                                               new Vector2(0, 30f) );
        }
    }

实际运行效果
跟随效果

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值