Unity 抬头显示 屏幕外跟踪标记

简介

游戏中经常会需要实现屏幕外标记指示的功能,这样能方便玩家快速定位目标方位,尤其在多人网络游戏中出现(守望先锋,彩虹六号,Apex英雄等等):

屏外显示实例

具体实现

现在使用Unity实现,其实要复杂可以很复杂,这里肯定用简单直接点的,核心功能是Unity的Unity - Scripting API: Camera.WorldToScreenPoint (unity3d.com)https://docs.unity3d.com/ScriptReference/Camera.WorldToScreenPoint.html

这个API可以直接将特定物体在屏幕上的相对坐标输出出来,真是非常Nice!

在Unity Canvas中加入一个Image便可,箭头的话放入子集,可能需要一个空物体做parent来当作旋转轴心,然后在Canvas组件中加入如下脚本,然后在Unity中指定每个变量。部分解析在代码注释中,不保证是最佳解决方法,但是确实能用。

using UnityEngine;
/* 
* Copyright (c) [2023] [Lizhneghe.Chen https://github.com/Lizhenghe-Chen]
*/
//https://blog.csdn.net/DUYIJIU/article/details/98366918
//https://indienova.com/indie-game-development/unity-off-screen-objective-marker/
public class TargetToScreen : MonoBehaviour
{
    [Header("Assign below variables in the inspector:")]
    [SerializeField] Transform TargetTransform;
    [SerializeField] Vector3 TargetPositionOffset = new Vector3(0, 1, 0);
    [SerializeField] float screenBoundOffset = 0.1f;
    [SerializeField] RectTransform TargetImage, TargetImageArrow;
    [SerializeField] TMPro.TextMeshProUGUI TargetText;
    [Header("Below is for Debug use:")]
    [SerializeField] Vector3 screenPosition, screenBound;
    [SerializeField] Vector2 Arrowdirection;
    private void LateUpdate()
    {
        TargetToScreenPosition();
    }
    /// <summary>
    /// This function is to convert the world position of the target to the screen position, and then update the position of the target image and the arrow image.
    /// </summary>
    public void TargetToScreenPosition()
    {
        screenPosition = Camera.main.WorldToScreenPoint(TargetTransform.position + TargetPositionOffset);// simple way to get the screen position of the target
        (screenBound.x, screenBound.y) = (Screen.width, Screen.height);//get the screen size

        if (screenPosition.z < 0)//if the target is behind the camera, flip the screen position
        {
            screenPosition = -screenPosition;
            if (screenPosition.y > screenBound.y / 2)//this is to avoid small probablity that the target is behind the camera and the screen position is flipped, but the y position is still in the screen
            {
                screenPosition.y = screenBound.y;
            }
            else screenPosition.y = 0;
        }
        //clamp the screen position to the screen bound
        TargetImage.transform.position = new Vector2(
                    Mathf.Clamp(screenPosition.x, screenBound.y * screenBoundOffset, screenBound.x - screenBound.y * screenBoundOffset),
                    Mathf.Clamp(screenPosition.y, screenBound.y * screenBoundOffset, screenBound.y - screenBound.y * screenBoundOffset)
                                );

        //optional, rotate the arrow to point to the target:
        Arrowdirection = TargetImageArrow.transform.position - screenPosition;//get the direction of the arrow by subtracting the screen position of the target from the screen position of the arrow
        // Debug.Log(Arrowdirection.magnitude);
        if (Mathf.Abs(Arrowdirection.x + Arrowdirection.y) < 0.1)
        {
            //disable the arrow when the target is too close to the center of the screen
            TargetImageArrow.gameObject.SetActive(false);
            //TargetImageArrow.transform.up = Vector2.zero;
        }
        else
        {
            TargetImageArrow.gameObject.SetActive(true);
            TargetImageArrow.transform.up = Arrowdirection;
        }
        //optional, update the distance text
        TargetText.text = Vector3.Distance(TargetTransform.position, Camera.main.transform.position).ToString("F1") + "m";
    }
}

实际效果展示,略糊,蓝绿色图标

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bunny Chen

来啊来让我发家致富,一毛钱可!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值