Unity3d C# 实现UGUI面板跟随标注3D模型功能(含源码)

前言

如题的需求,让UI的窗体跟随场景中模型进行移动,现在很多游戏的血条就是按这个进行;如果我们直接使用世界中的Canvas,每个窗体都需要一个Canvas,消耗很大,我们一般还是在屏幕内同步显示UI的方式。

效果

在这里插入图片描述

在这里插入图片描述

如上就是同步的效果。

实现

UI搭建

按如图搭建UI

在这里插入图片描述

重点是pivot是UI的同步点,如果调整不准可以用偏移值修正。

定义变量

[Header("跟随的物体")]
public Transform FollowTran;

[Header("偏移值")]
public Vector2 Offset;

RectTransform ParentTran, Rtran;

同步位置

 if (FollowTran != null)
 {
    
    
Vector2 mScreenPos = Camera.main.WorldToScreenPoint(FollowTran.transform.position);
      Vector2 mRectPos;
      RectTransformUtility.ScreenPointToLocalPointInRectangle(ParentTran, mScreenPos, null, out mRectPos);
      Rtran.localPosition = mRectPos + Offset;
}

思路就是世界坐标转屏幕点;通过屏幕点再转为UI位置即可。

源码工程

https://download.csdn.net/download/qq_33789001/33465355

\---------------------------------------------华丽分割线---------------------------------------------\

以下2022.3.9更新

问题

感谢kindred_joe网友的反馈,在摄像头背面会出现标签问题:
在这里插入图片描述

该问题的原因是在世界位置映射屏幕位置(WorldToScreenPoint)时,在摄像机背面的世界位置也会映射到屏幕内位置造成了该问题。

我这边的解决思路是判断物体是否在在摄像机前面,在前面时进行标注,否则不标注。

同步位置

if (FollowTran != null)
        {
    
    
            if (isInFront())
            {
    
    
                Vector2 mScreenPos = Camera.main.WorldToScreenPoint(FollowTran.transform.position);
                Vector2 mRectPos;
                RectTransformUtility.ScreenPointToLocalPointInRectangle(ParentTran, mScreenPos, null, out mRectPos);
                Rtran.localPosition = mRectPos + Offset;
                Rtran.localScale = Vector3.one;
            }
            else
                Rtran.localScale = Vector3.zero;
}

位置判断

//判定在摄像头前面
    public bool isInFront() {
    
    
        Vector2 viewPos = Camera.main.WorldToViewportPoint(FollowTran.position);
        Vector3 dir = (FollowTran.position - Camera.main.transform.position).normalized;
        float dot = Vector3.Dot(Camera.main.transform.forward, dir);
        if (dot > 0)
            return true;
        else
            return false;
    }

猜你喜欢

转载自blog.csdn.net/qq_33789001/article/details/120864639
今日推荐