【Unity学习笔记|Unity学习笔记--实现UI元素跟随3D物体】
目录
- 前言
-
- 一、Camera的渲染模式为ScreenSpaceOverlay
-
- 思路
- 二、Camera的渲染模式为ScreenSpaceCamera
-
- 思路
- 两种情况合并代码
- 使用方法
前言 首先要分摄像机的渲染模式
- Camera的渲染模式为ScreenSpaceOverlay
- Camera的渲染模式为ScreenSpaceCamera
首先理解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().
Init(
Camera.main, transform,
GameObject.FindObjectOfType
推荐阅读
- Unity 计算所有物体包围盒的中心点
- 笔记|Unity 2021.3.6f1 Crack
- 你所需要了解的几种纹理压缩格式原理
- 实用工具|10种舒服的颜色及配色推荐
- Unity|【Unity】Unity学习笔记目录整理
- unity|unity笔记
- 数据库|艾伟(一次挂死(hang)的处理过程及经验)
- 操作系统|查看w3wp进程占用的内存及.NET内存泄露,死锁分析
- 操作系统|查看w3wp进程占用的内存及.NET内存泄露,死锁分析--转载