UI显示任务目的地标记的方法

首先我们都知道用Camera.main.WorldToScreenPoint(),这是目的地在屏幕内的情况。

  1. 如果在屏幕外但还在玩家前方,对坐标的xy使用Mathf.Clamp()限制到屏幕里就行。
  2. 如果目的地在玩家后方,我选择根据是偏左还是偏右粗暴的放到屏幕最左或最右;

注意WorldToScreenPoint()的结果受屏幕分辨率影响,分辨率1920*1080和16:9 Aspect的效果不一样。所以加上pos.x * canvasRT.width / Screen.width消除影响。

简单粗暴的方法

注意z<0也就是在玩家身后时,x>Screen.width / 2反而意味着偏左。

cs 复制代码
void GetMarkerPos()
{
    Vector3 pos=Camera.main.WorldToScreenPoint(chasingMission.transform.position);
    if (pos.z > 0)
    {
        pos.x = Mathf.Clamp(pos.x,0, Screen.width);
        pos.y = Mathf.Clamp(pos.y,0, Screen.height);
    }
    else {
        pos.x = pos.x < Screen.width / 2 ? Screen.width : 0;
        pos.y=Screen.height / 2;
    }
    pos = new Vector2(pos.x * canvasRT.width / Screen.width,
        pos.y * canvasRT.height/Screen.height);
    string distanceHint = ((int)Vector3.Distance(player.transform.position,
    chasingMission.transform.position)).ToString() + "m";
    onUpdateMarker?.Invoke(pos, distanceHint);
}

一个之前的方法,很麻烦

cs 复制代码
Rect scale;
void Start(){
    Rect screen = (GameSceneManager.Instance.canvas.transform as RectTransform).rect;
    //画布的rect宽高固定为1920*1080,即使分辨率只是自由16:9
    scale.width = screen.width / Screen.width;
    scale.height = screen.height / Screen.height;
}
void CalculateMissionMarkerPosition(){
            targetDir=targetMission.transform.position-player.transform.position;
            if(Vector3.Angle(player.transform.forward,targetDir)<Camera.main.fieldOfView){
                Vector2 pos=Camera.main.WorldToScreenPoint(targetMission.transform.position);
                pos = new Vector2(pos.x / Screen.width * 1920, pos.y / Screen.height * 1080);
                missionMarker.anchoredPosition=pos;
            }
            else{
                if(cinemachineBrain.ActiveVirtualCamera==null){
                    return;//在第一帧可能ActiveVirtualCamera是空
                }
                Vector3 destInPlayer=cinemachineBrain.ActiveVirtualCamera.VirtualCameraGameObject.
                transform.InverseTransformPoint(targetMission.transform.position);
                Vector2 pos;
                if(Mathf.Abs(destInPlayer.y/destInPlayer.x)>(float)Screen.height/Screen.width){
                    pos.x=Mathf.Abs(destInPlayer.x/destInPlayer.y*Screen.height/2);
                    if(destInPlayer.x<0){
                        pos.x=-pos.x;
                    }
                    if(destInPlayer.y>0){
                        pos.y=Screen.height/2;
                    }
                    else{
                        pos.y=-Screen.height/2;
                    }
                }
                else{
                    pos.y=Mathf.Abs(destInPlayer.y/destInPlayer.x*Screen.width/2);
                    if(destInPlayer.y<0){
                        pos.y=-pos.y;
                    }
                    if(destInPlayer.x>0){
                        pos.x=Screen.width/2;
                    }
                    else{
                        pos.x=-Screen.width/2;
                    }
                }
                missionMarker.anchoredPosition=pos+new Vector2(Screen.width,Screen.height)/2;
            }
            textDistance.text = ((int)Vector3.Distance(MyInput.Instance.player.transform.position,
            targetMission.transform.position)).ToString()+"m";
    }
相关推荐
汀、人工智能7 分钟前
[特殊字符] 第2课:字母异位词分组
数据结构·算法·链表·数据库架构··字母异位词分组
小O的算法实验室39 分钟前
2026年SEVC,面向主动成像卫星任务规划问题的群体智能与动态规划混合框架,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
网安INF1 小时前
数据结构第一章复习:基本概念与算法复杂度分析
数据结构·算法
幻风_huanfeng1 小时前
人工智能之数学基础:什么是凸优化问题?
人工智能·算法·机器学习·凸优化
三雷科技1 小时前
使用 `dlopen` 动态加载 `.so` 文件
开发语言·c++·算法
Yzzz-F2 小时前
Problem - 2146D1 - Codeforces &&Problem - D2 - Codeforces
算法
Kk.08022 小时前
力扣 LCR 084.全排列||
算法·leetcode·职场和发展
环黄金线HHJX.2 小时前
龙虾钳足启发的AI集群语言交互新范式
开发语言·人工智能·算法·编辑器·交互
Omics Pro2 小时前
虚拟细胞:开启HIV/AIDS治疗新纪元的关键?
大数据·数据库·人工智能·深度学习·算法·机器学习·计算机视觉
旖-旎2 小时前
分治(快速选择算法)(3)
c++·算法·leetcode·排序算法·快速选择