Unity学习笔记--实现UI元素跟随3D物体

前言

首先要分摄像机的渲染模式

  1. Camera的渲染模式为ScreenSpaceOverlay
  2. Camera的渲染模式为ScreenSpaceCamera

一、Camera的渲染模式为ScreenSpaceOverlay

思路

首先理解ScreenSpaceOverlay渲染模式

ScreenSpaceOverlay—这个模式不再需要UI摄像机,UI将出现在游戏场景的前面。但是这样会出现问题,如果要在UI前面放置一个游戏对象,那么这个对象将不可见。

那么我们就把目标的世界坐标转换为屏幕坐标,之后再赋值给UI物体的RectTransform的position就可以了。

二、Camera的渲染模式为ScreenSpaceCamera

思路

首先理解ScreenSpaceCamera渲染模式

ScreenSpaceCamera—这种模式需要提供一个UICamera 。这样就和NGUI的原理很像了,如果我想在UI前面加特效我可以在创建一个摄像机深度大于这个UICamera就行了。

这里我们需要用到Unity自带的工具类RectTransformUtility里面的

public static bool ScreenPointToLocalPointInRectangle
	(
		RectTransform rect, 
		Vector2 screenPoint,
		Camera cam, 
		out Vector2 localPoint
	);

不知道作用的我贴一下官方文档:官方文档

那么我们只需要得到需要跟踪物体的屏幕坐标就行了。
那么我们首先得到它。

Vector2 pos = m_camera.WorldToScreenPoint(m_target.transform.position);

之后我们可以获得RectTransformUtility.ScreenPointToLocalPointInRectangle函数out出来的值。把它赋值给UI物体的坐标就行了。

两种情况合并代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UIFollowWorldObject : MonoBehaviour
{
    
    
    private Camera m_camera;
    private Transform m_target;
    private Canvas m_canvas;

    private bool hasFollowed = false;
    public bool alwaysFollow = true;
    public void Init(Camera camera, Transform target, Canvas canvas)
    {
    
    
        m_camera = camera;
        m_target = target;
        m_canvas = canvas;
        FollowObject();
    }

    public void Update()
    {
    
    
        FollowObject();
    }

    private void FollowObject()
    {
    
    
        if (!alwaysFollow && hasFollowed)
        {
    
    
        	return;
        }

        if (m_camera != null && m_target != null)
        {
    
    
            Vector2 pos = m_camera.WorldToScreenPoint(m_target.transform.position);
            switch (m_canvas.renderMode)
            {
    
    
                case RenderMode.ScreenSpaceOverlay:
                    (transform as RectTransform).position = pos;
                    hasFollowed = true;
                    break;
                case RenderMode.ScreenSpaceCamera:
                    if (RectTransformUtility.ScreenPointToLocalPointInRectangle(transform.parent as RectTransform, pos, m_camera, out Vector2 point))
                    {
    
    
                        transform.localPosition = new Vector3(point.x, point.y, 0);
                        hasFollowed = true;
                    }
                    break;
            }
        }
    }
}

使用方法

我们需要首先把该脚本挂载到UI物体上。之后需要调用的时候就调用该UI脚本的Init函数就可以了。

例如:

GameObject.FindObjectOfType<UIFollowWorldObject>().
	Init(
			Camera.main, transform, 
			GameObject.FindObjectOfType<Canvas>()
		);

猜你喜欢

转载自blog.csdn.net/qq_52855744/article/details/121608886