最近开发功能需要一个寻路并且脚下会出现到目标的指引路标功能,所以找到了一个实现的功能,主要还是通过Nav实现地形内的寻找,如果不在Nav的地形内 ,将会中断搜索
好了 废话不多说 附上代码 挂在玩家身上即可
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.UI;
public class ArrowFindPath : MonoBehaviour
{
private NavMeshAgent _navPlayer;
private NavMeshPath _navPath;
public float tileSpacing = 0.5f;
public LineRenderer lineGameObject;
public GameObject directionPrefab;
public Transform tagetposition;
private List<GameObject> arrowList = new List<GameObject>();
public GameObject player;
public GameObject hp_bar;
bool timebool = false;
// Use this for initialization
void Start()
{
_navPlayer = transform.GetComponent<NavMeshAgent>();
_navPath = new NavMeshPath();
}
// Update is called once per frame
void Update()
{
float dis = (transform.position - player.transform.position).sqrMagnitude;
if (timebool==true)
{
hp_bar.GetComponentInChildren<Text>().text = dis.ToString("#0");
}
if (Input.GetKeyDown(KeyCode.A))
{
hp_bar = (GameObject)Resources.Load("end");
hp_bar.transform.position = player.transform.position;
hp_bar = Instantiate(hp_bar);
timebool = true;
}
print(dis);
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);
}
}
}
/// <summary>
/// Draws the path.
/// </summary>
/// <param name="navPath">Nav path.</param>
void DrawPath(NavMeshPath navPath)
{
List<GameObject> arrows = arrowList;
StartCoroutine(ClearArrows(arrows));
arrowList.Clear();
//If the path has 1 or no corners, there is no need to draw the line
if (navPath.corners.Length < 2)
{
print("navPath.corners.Length < 2");
return;
}
// Set the array of positions to the amount of corners...
lineGameObject.positionCount = navPath.corners.Length;
Quaternion planerot = Quaternion.identity;
for (int i = 0; i < navPath.corners.Length; i++)
{
// Go through each corner and set that to the line renderer's position...
lineGameObject.SetPosition(i, navPath.corners[i]);
float distance = 0;
Vector3 offsetVector = Vector3.zero;
if (i < navPath.corners.Length - 1)
{
//plane rotation calculation
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);
//plane position calculation
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);
}
}
}
/// <summary>
/// Clears the arrows.
/// </summary>
/// <returns>The arrows.</returns>
/// <param name="arrows">Arrows.</param>
private IEnumerator ClearArrows(List<GameObject> arrows)
{
if (arrowList.Count == 0)
yield break;
foreach (var arrow in arrows)
Destroy(arrow);
}
}