导航中的路径指示(图片文字不被物体遮挡)

在场景中,新建一个 GameObject,命名为 LineRenderer,并在上面添加一个LineRenderer组件

导入一个箭头的 图片,并修改成精灵图,拖到场景中,调整好合适的精灵图比例,在拖到工程中,作为预制体

选中场景中的 Capsule,添加脚本 ArrowFindPath,赋值 LineRenderer 和 箭头预制体

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class ArrowFindPath : MonoBehaviour {

    private NavMeshAgent _navPlayer;
    private NavMeshPath _navPath;
    public float tileSpacing = 0.5f;
    public LineRenderer LineGameObject;

    public GameObject directionPrefab;
    private List<GameObject> arrowList = new List<GameObject>();

	void Start () {
        _navPlayer = transform.GetComponent<NavMeshAgent>();
        _navPath = new NavMeshPath();
	}
	
	void Update () {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray,out hit,Mathf.Infinity))
            {
                //print("hit:" + hit.point);
                _navPlayer.SetDestination(hit.point);
                NavMesh.CalculatePath(transform.position, hit.point, NavMesh.AllAreas, _navPath);

                DrawPath(_navPath);
            }
        }
	}

    private void DrawPath(NavMeshPath navPath)
    {
        List<GameObject> arrows = arrowList;
        StartCoroutine(ClearArrows(arrows));
        arrowList.Clear();

        Debug.Log(navPath.corners.Length);
        if (navPath.corners.Length<2)
        {
            print("navPath.corner,Lenth<2");
            return;
        }

        LineGameObject.positionCount = navPath.corners.Length;
        Quaternion planerot = Quaternion.identity;
        for (int i = 0; i < navPath.corners.Length; i++)
        {
            LineGameObject.SetPosition(i, navPath.corners[i]);
            float distance = 0;
            Vector3 offsetVector = Vector3.zero;
            if (i<navPath.corners.Length-1)
            {
                offsetVector = navPath.corners[i + 1] - navPath.corners[i];
                planerot = Quaternion.LookRotation(offsetVector);
                distance = Vector3.Distance(navPath.corners[i + 1], navPath.corners[i]);
                if (distance<tileSpacing)
                {
                    continue;
                }
                planerot = Quaternion.Euler(90, planerot.eulerAngles.y, planerot.eulerAngles.z);

                float newSpacing = 0;
                for (int j = 0; j < distance/tileSpacing; j++)
                {
                    newSpacing += tileSpacing;
                    var normalizedVector = offsetVector.normalized;
                    var position = navPath.corners[i] + newSpacing * normalizedVector;
                    GameObject go = Instantiate(directionPrefab, position + Vector3.up, planerot);
                    arrowList.Add(go);
                }
            }
            else
            {
                GameObject go = Instantiate(directionPrefab, navPath.corners[i] + Vector3.up, planerot);
                arrowList.Add(go);
            }
        }
    }

    private IEnumerator ClearArrows(List<GameObject> arrows)
    {
        if (arrowList.Count==0)
        {
            yield break;
        }
        foreach (var arrow in arrows)
        {
            Destroy(arrow);
        }
    }
}

文字不被遮挡图片不被遮挡

链接: https://pan.baidu.com/s/1Dk0BdvzFa8FyMu02op-OQw 提取码: k8m3 复制这段内容后打开百度网盘手机App,操作更方便哦

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class MapLine : MonoBehaviour
{
    private Vector3 startPos = Vector3.one;
    private Vector3 endPos = Vector3.one;
    private Vector3 rotation = Vector3.zero;
    private Material material;
    private bool isMove;
    private Vector2 moveDir;
    private Vector2 resetOffset;

    

    void Awake()
    {
        isMove = false;
        moveDir = new Vector2(0, 0.01f);
        resetOffset = new Vector2(0, 100);
        material = GetComponent<Renderer>().material;

        
    }
    /// <summary>  
    /// 设置材质的Offset的属性,让箭头移动起来  
    /// </summary>  
    private void Update()
    {
        if (isMove)
        {
            if (material.mainTextureOffset == resetOffset)
                material.mainTextureOffset = moveDir;
            material.mainTextureOffset += -moveDir;
        }
        
    }
    public void SetLine(Vector3 startPos, Vector3 endPos)
    {
        this.startPos = startPos;
        this.endPos = endPos;
        transform.localScale = Vector3.one * 0.05f;
        transform.position = startPos;
        transform.eulerAngles = Vector3.zero;
        var scale = transform.localScale;
        var lineLong = CalLineLong() * 2;
        scale.z = scale.z * lineLong;
        transform.localScale = scale;
        rotation.y = CalLineAngle();
        transform.eulerAngles = rotation;
        material.mainTextureScale = new Vector2(1, lineLong);
        transform.Translate(0, 0, lineLong / 4, Space.Self);

        //因为贴图箭头的方向不对,这里角度纠正,刚刚好 Y + 180
        transform.eulerAngles += new Vector3(0, 180, 0);
        isMove = true;
    }
    /// <summary>  
    /// 计算行军路线长度  
    /// </summary>  
    private float CalLineLong()
    {
        return Mathf.Sqrt(Mathf.Pow(startPos.x - endPos.x, 2) + Mathf.Pow(startPos.z - endPos.z, 2));
    }
    /// <summary>  
    /// 计算行军路线角度  
    /// </summary>  
    private float CalLineAngle()
    {
        //斜边长度  
        float length = Mathf.Sqrt(Mathf.Pow((startPos.x - endPos.x), 2) + Mathf.Pow((startPos.z - endPos.z), 2));
        //对边比斜边 sin  
        float hudu = Mathf.Asin(Mathf.Abs(startPos.z - endPos.z) / length);
        float ag = hudu * 180 / Mathf.PI;
        //第一象限  
        if ((endPos.x - startPos.x) >= 0 && (endPos.z - startPos.z >= 0))
            ag = -ag + 90;
        //第二象限  
        else if ((endPos.x - startPos.x) <= 0 && (endPos.z - startPos.z >= 0))
            ag = ag - 90;
        //第三象限  
        else if ((endPos.x - startPos.x) <= 0 && (endPos.z - startPos.z) <= 0)
            ag = -ag + 270;
        //第四象限  
        else if ((endPos.x - startPos.x) >= 0 && (endPos.z - startPos.z) <= 0)
            ag = ag + 90;
        return ag;
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class PlayerArrow : MonoBehaviour {

    private NavMeshAgent _navPlayer;
    public MapLine Arrow;

    void Start () {
        _navPlayer = transform.GetComponent<NavMeshAgent>();
    }
	
	void Update () {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit, Mathf.Infinity))
            {
                _navPlayer.SetDestination(hit.point);

                Arrow.SetLine(transform.position, hit.point);
            }
        }
    }
}

Shader"Custom/TransparentOverlay"
{
	Properties
	{
		_MainTex("MainTex(RGBA)",2D) = "white" {}
	}
		SubShader
	{
		LOD 100
		Cull Off Lighting Off ZWrite Off ZTest Always
		Blend SrcAlpha OneMinusSrcAlpha
		Tags
		{
			"Queue" = "Overlay"
			"IgnoreProjector" = "True"
			"RenderType" = "Transparent"
		}
		Pass
		{
			SetTexture[_MainTex]
		}
	}
}

猜你喜欢

转载自blog.csdn.net/qq_41579634/article/details/88813628