- 最后登录
- 2021-7-6
- 注册时间
- 2012-12-27
- 阅读权限
- 90
- 积分
- 76145
 
- 纳金币
- 53488
- 精华
- 316
|
网上找了很多关于NPC头顶姓名的代码。有OnGUI的,有用NGUI的
但是,都有一个共同的特点,就是只能进行2D视角的显示或者伪3D视角,在3D视角里存在着Z轴的影响,且相机的2D坐标里涉及相机的背对着NPC的情况。
因此,在绘制NPC姓名时出现了一个BUG,那就是即使背对着NPC方向,屏幕上也会出现NPC的姓名,导致玩家不能准确的找到NPC的位置。
话不多说,下面上代码- using UnityEngine;
- using System.Collections;
-
- public class NpcShowName : MonoBehaviour
- {
- //主角对象
- private GameObject player;
- //主摄像机对象
- private Camera camera;
- //NPC名称
- private string name = "哥布林";
- //NPC模型高度
- private float npcHeight =1;
- //是否进行NPC名称的绘制
- private bool canlook=false;
- //看见名称的距离
- public int watchRange =20;
- void Start ()
- {
- //根据Tag得到主角对象
-
- player = GameObject.FindGameObjectWithTag("MainCamera");
- camera = Camera.main;
- }
- void Update ()
- {
-
-
- float nowDistance = Vector3.Distance(transform.position, player.transform.position);
- Debug.Log(canlook);
- Debug.Log(nowDistance);
-
- Rect screenRect = new Rect(0, 0, Screen.width, Screen.height);
- Vector3 screenPos = camera.WorldToScreenPoint(transform.position);
- if (!screenRect.Contains(screenPos) || nowDistance > watchRange) //不在屏幕上或者超出可视范围,则不显示名称
- {
- canlook = false;
- }
- else
- {
- canlook = true;
- }
-
- }
- void OnGUI()
- {
- if (canlook)
- {
- //得到NPC头顶在3D世界中的坐标
- //默认NPC坐标点在脚底下,所以这里加上npcHeight它模型的高度即可
- Vector3 worldPosition = new Vector3(transform.position.x, transform.position.y + npcHeight, transform.position.z);
- //根据NPC头顶的3D坐标换算成它在2D屏幕中的坐标
- Vector3 position = camera.WorldToScreenPoint(worldPosition);
- //得到真实NPC头顶的2D坐标
- position = new Vector3(position.x, Screen.height - position.y,position.z);
- //计算NPC名称的宽高
- Vector2 nameSize = GUI.skin.label.CalcSize(new GUIContent(name));
- //设置显示颜色为黄色
- GUI.color = Color.red;
- //绘制NPC名称
-
- GUI.Label(new Rect(position.x - (nameSize.x / 2), position.y - nameSize.y, nameSize.x, nameSize.y), name);
- }
-
- }
- void OnBecameVisible() //在相机范围内则进行渲染(即显示)
- {
- enabled = true;
- canlook = true;
- }
- void OnBecameInvisible() //在相机范围外,则不进行渲染(即不显示)
- {
- enabled = false;
- canlook = false;
- }
- }
复制代码 这里使用了两个重要的函数。 OnBecameVisible()和 OnBecameInvisible() 这是[color=rgb(85, 85, 85) !important]U3D自带的函数 (用于相机的渲染,是否是相机视野范围内)
然后提供了一个办法
Rect screenRect = new Rect(0, 0, Screen.width, Screen.height); Vector3 screenPos = camera.WorldToScreenPoint(transform.position); if (!screenRect.Contains(screenPos) || nowDistance > watchRange) //不在屏幕上或者超出可视范围,则不显示名称
这段代码是用来 把看到的物体的坐标转换为屏幕的2D坐标,再进行与屏幕的宽和高进行对比,判断是否在屏幕范围内(不是相机视野)。
好了,讲解就到这里。希望会对大家有帮助。有什么错误的地方请指正。相互学习。
|
|