【Unity】實現箭頭追蹤效果,將2D箭頭沿着屏幕邊緣指向3D模型

只需要一個腳本,就可以例圖的效果


在這裏插入圖片描述
廢話不多說,直接上腳本(此腳本只支持單個箭頭追蹤,如果需要實現多箭頭追蹤的效果,請自己酌情修改腳本,或者多調用幾次這個方法)

using System.Collections;
using UnityEngine;

public class UIGuidManager : MonoBehaviour
{
    public Transform arrows; //2d的箭頭拖在這裏
    Transform target;
    Vector3 prePos = Vector3.zero;
    //這個是檢測間隔,和性能掛鉤,默認爲0.2,自己可以隨更改
    public float checkTime = 0.2f;

//被指向的3D對象傳入這裏,在全局的任何地方,調用一次這個方法即可
    public void SetGuid(Transform _target)
    {
        target = _target;
    }
    void Start()
    {
        arrows.gameObject.SetActive(false);
        StartCoroutine(TrakerGuider());
    }

    private IEnumerator TrakerGuider()
    {
        while (true)
        {
            yield return new WaitForSeconds(checkTime);
            SetGuid();
        }
    }

    private void SetGuid()
    {
        if (target)
        {
            var pos = Camera.main.WorldToScreenPoint(target.transform.position);
            Debug.Log("pos:" + pos);
            var distance = Vector3.Distance(prePos, pos);
            if (distance < 1) { Debug.Log("沒動"); return; };
            prePos = pos;
            if (0 < pos.x && pos.x < Screen.width && pos.y > 0 && pos.y < Screen.height && pos.z > 0)
            {
                arrows.gameObject.SetActive(false);
                return;
            }
            else
                arrows.gameObject.SetActive(true);
            if (pos.z < 0)
                pos = pos * -1;
            var startpos = new Vector3(Screen.width / 2f, Screen.height / 2f, 0);
            var dir = pos - startpos;

            //通過反餘弦函數獲取 向量 a、b 夾角(默認爲 弧度)
            float radians = Mathf.Atan2(dir.y, dir.x);

            //將弧度轉換爲 角度
            float angle = radians * Mathf.Rad2Deg;
            Debug.Log("angle:" + angle);
            arrows.localEulerAngles = new Vector3(0, 0, angle);
            // arrows.transform.LookAt(new Vector3(pos.x, pos.y, 0));
            float sereenangle = (float)Screen.height / (float)Screen.width;
            var va = System.Math.Abs(dir.y / dir.x);
            if (va <= sereenangle)
            {
                var length = arrows.GetComponent<RectTransform>().sizeDelta.x;
                if (pos.x < 0)
                    arrows.transform.position = GetNode(pos, startpos, length * 0.5f);
                else
                    arrows.transform.position = GetNode(pos, startpos, Screen.width - length * 0.5f);
            }
            else
            {
                var length = arrows.GetComponent<RectTransform>().sizeDelta.x;

                if (pos.y < 0)
                    arrows.transform.position = GetNode2(pos, startpos, length * 0.5f);
                else
                    arrows.transform.position = GetNode2(pos, startpos, Screen.height - length * 0.5f);
            }
        }
    }

    private Vector3 GetNode2(Vector3 pos, Vector3 startpos, float v)
    {
        pos = new Vector3(pos.x, pos.y, 0);
        Vector3 ab = pos - startpos;
        Vector3 am = ab * (Mathf.Abs(startpos.y - v) / Mathf.Abs(pos.y - startpos.y));
        Vector3 om = startpos + am;
        return om;
    }

    private Vector3 GetNode(Vector3 pos, Vector3 startpos, float v)
    {
        //float high = ((startpos.x - length) * (pos.y - startpos.y) / (startpos.x - pos.x)) + startpos.y;
        //return new Vector3(length, high, 0);
        pos = new Vector3(pos.x, pos.y, 0);
        Vector3 ab = pos - startpos;
        Vector3 am = ab * (Mathf.Abs(startpos.x - v) / Mathf.Abs(pos.x - startpos.x));
        Vector3 om = startpos + am;
        return om;
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章