unity寻找物体脚下出现路标到制定地点

最近开发功能需要一个寻路并且脚下会出现到目标的指引路标功能,所以找到了一个实现的功能,主要还是通过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);

}

}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用Unity的协程(Coroutine)实现这个功能。具体步骤如下: 1. 在物体到达指定位置后,使用协程等待一段时间,让它停留在当前位置。 2. 在协程中,使用物体的Transform组件使其上升到指定高度。 下面是一个简单的示例代码: ```csharp public class ObjectController : MonoBehaviour { public float moveSpeed = 5f; // 物体移动速度 public float waitTime = 2f; // 停留时间 public float riseHeight = 2f; // 上升高度 private Vector3 targetPosition; // 目标位置 private bool isMoving = false; // 是否正在移动 void Start() { // 初始化目标位置 targetPosition = new Vector3(5f, 0f, 0f); } void Update() { // 检测是否需要移动 if (!isMoving && transform.position != targetPosition) { // 开始移动 StartCoroutine(MoveAndRise()); } } IEnumerator MoveAndRise() { isMoving = true; // 计算移动方向和距离 Vector3 direction = (targetPosition - transform.position).normalized; float distance = Vector3.Distance(transform.position, targetPosition); // 移动到目标位置 while (distance > 0.1f) { transform.position += direction * moveSpeed * Time.deltaTime; distance = Vector3.Distance(transform.position, targetPosition); yield return null; } // 等待一段时间 yield return new WaitForSeconds(waitTime); // 上升到指定高度 float currentHeight = 0f; while (currentHeight < riseHeight) { transform.position += Vector3.up * moveSpeed * Time.deltaTime; currentHeight += moveSpeed * Time.deltaTime; yield return null; } isMoving = false; } } ``` 在这个示例中,我们定义了三个公共变量,分别是物体移动速度、停留时间和上升高度。在Start()函数中初始化目标位置,然后在Update()函数中检测是否需要移动。如果物体没有正在移动且没有到达目标位置,就启动协程MoveAndRise()来移动物体。 在MoveAndRise()协程中,我们先计算移动方向和距离,并使用while循环来移动物体到目标位置。然后使用yield return new WaitForSeconds()来等待一段时间。最后使用while循环来上升物体到指定高度。注意,我们在while循环中使用了moveSpeed变量来控制移动速度和上升速度。 希望这个示例对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值