计算敌人在屏幕中的位置

 1 using System.Collections;
 2 using System.Collections.Generic;
 3 using UnityEngine;
 4 using UnityEngine.UI;
 5 
 6 public class CArrowLockAt : MonoBehaviour
 7 {
 8     public Transform target;    //目标
 9     public Transform self;  //自己
10     public Image RoundScope;//指定为圆
11     public float direction; //箭头旋转的方向,或者说角度,只有正的值
12     public Vector3 u;   //叉乘结果,用于判断上述角度是正是负
13 
14     float devValue =100f;   //离屏边缘距离
15   
16 
17     Quaternion originRot;   //箭头原角度
18 
19     // 初始化
20     void Start()
21     {
22         originRot = transform.rotation;
23     }
24 
25     void Update()
26     {
27 
28 
29         // 计算向量和角度
30         Vector3 forVec = self.forward;  //计算本物体的前向量
31         Vector3 angVec = (target.position - self.position).normalized;  //本物体和目标物体之间的单位向量
32 
33         #region 求指向
34         Vector3 targetVec = Vector3.ProjectOnPlane(angVec - forVec, forVec).normalized; //这步很重要,将上述两个向量计算出一个代表方向的向量后投射到本身的xy平面
35         Vector3 originVec = self.up;
36 
37         direction = Vector3.Dot(originVec, targetVec);  //再跟y轴正方向做点积和叉积,就求出了箭头需要旋转的角度和角度的正负
38 
39         u = Vector3.Cross(originVec, targetVec);
40        
41         direction = Mathf.Acos(direction) * Mathf.Rad2Deg;  //转换为角度
42 
43         u = self.InverseTransformDirection(u);  //叉积结果转换为本物体坐标
44       
45         // 给与旋转值
46         transform.rotation = originRot * Quaternion.Euler(new Vector3(0f, 0f, direction * (u.z > 0 ? 1 : -1)));
47         #endregion
48 
49 
50         // 计算当前物体在屏幕上的位置
51         Vector2 screenPos = RectTransformUtility.WorldToScreenPoint(Camera.main,target.position);
52         #region 求在圆边位置
53         //圆半径
54         float range = (RoundScope.rectTransform.sizeDelta.y / 2) - 30;
55         //目标位置
56         Vector3 cc = RoundScope.transform.position + Vector3.ProjectOnPlane((target.position - self.position) - self.forward, self.forward) * range;
57         #endregion
58         // 不在屏幕内的情况
59         if (screenPos.x < devValue || screenPos.x > Screen.width - devValue || screenPos.y < devValue || screenPos.y > Screen.height - devValue || Vector3.Dot(forVec, angVec) < 0)
60         {
61             if (range < Vector3.Distance(cc, RoundScope.rectTransform.position))
62             {
63                 transform.position = (cc - RoundScope.transform.position).normalized * range + RoundScope.transform.position;
64             }
65             else
66             {
67                 transform.position = cc;
68             }
69         }
70         else    // 在屏幕内的情况
71         {
72             transform.Rotate(0, 90, -45);
73         }
74     }
75 }

 

posted @ 2022-07-12 17:49  枫亦  阅读(14)  评论(0)    收藏  举报