首页 > 其他分享 >Unity 导航路线生成,小地图同步映射, 经过以后地图与小地图删除点位(点击小地图控制导航以及点击场景导航都会有路径点和路径点图标)

Unity 导航路线生成,小地图同步映射, 经过以后地图与小地图删除点位(点击小地图控制导航以及点击场景导航都会有路径点和路径点图标)

时间:2024-07-01 21:00:08浏览次数:21  
标签:void 地图 rectTransform 点击 mesh new using 导航 public

效果:(如下图所示)

操作方法:

搭建小地图UI

截取图片

创建地面

挂载如下代码:

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

[RequireComponent(typeof(MeshFilter), typeof(MeshCollider), typeof(MeshRenderer))]
public class Map : MonoBehaviour
{
    //宽高
    [SerializeField] private int w, h;
    //颜色1和颜色2,用于设置渐变
    [SerializeField] private Color color1, color2;
    //存储水面上面的顶点的集合
    public List<Vector3> verticesPositions;
    //纹理
    private Texture2D _texture;
    //顶点辅助器
    private VertexHelper vh;
    //mesh网格
    private Mesh _mesh;

    // Start is called before the first frame update
    void Start()
    {
        verticesPositions= new List<Vector3>();
        _texture = new(w + 1, h + 1);
        vh = new();
        _mesh = new();
        //循环宽高
        for (int i = 0; i <= w; i++)
        {
            for (int j = 0; j <= h; j++)
            {
                //柏林噪声获取高度
                float y = Mathf.PerlinNoise(i * 0.2f, j * 0.2f);
                //uv坐标
                float uvx = (float)i / w;
                float uvy = (float)j / h;
                //添加顶点
                vh.AddVert(new(i, y * 5, j), Color.white, new(uvx, uvy));

                //设置纹理颜色
                _texture.SetPixel(i, j, Color.Lerp(color1, color2, y));
                //绘制三角
                if (i < w && j < h && y * 5 > 1.3f)
                {
                    vh.AddTriangle(j + i * (h + 1), j + 1 + i * (h + 1), j + 1 + 1 + h + i * (h + 1));
                    vh.AddTriangle(j + i * (h + 1), j + 1 + 1 + h + i * (h + 1), j + 1 + h + i * (h + 1));
                }
            }
        }
        //顶点辅助器给mesh网格赋值
        vh.FillMesh(_mesh);
        //mesh赋值给网格过滤器
        GetComponent<MeshFilter>().mesh = _mesh;
        //新建材质球
        Material material = new(Shader.Find("Standard"))
        {
            mainTexture = _texture
        };
        //网格渲染器赋值材质球
        GetComponent<MeshRenderer>().material = material;
        //网格碰撞器赋值mesh网格
        GetComponent<MeshCollider>().sharedMesh = _mesh;
        //加载水面
        Instantiate(Resources.Load<GameObject>("Water"));
        //设置纹理打包模式
        _texture.wrapMode = TextureWrapMode.Clamp;
        //应用纹理更改
        _texture.Apply();
    }
    // Update is called once per frame
    void Update()
    {
    }
}

小地图挂载

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

//Image有Mask,两个Image子类,一个挂脚本,一个作为中心点
public class SmallMap : MonoBehaviour, IPointerClickHandler
{
    //创建地图脚本的引用,用来获取其中的装饰物集合
    public NavMeshManager navMesh;
    //玩家
    public Transform player;
    //地图的rectTransform
    public RectTransform _rectTransform, Startpoint;
    //玩家的对象
    public NavMeshAgent nav;
    //控制缩放的Slider
    public Slider Slider;
    //存储路径点的图片的集合
    public List<GameObject> imageList = new List<GameObject>();

    private void Awake()
    {
        Slider.value = 1;
        _rectTransform = GetComponent<RectTransform>();
    }
    private void Update()
    {
        //实时获取大地图的比例(100是柏林噪声地图的宽高)
        float x = nav.transform.position.x / 100;
        float y = nav.transform.position.z / 100;
        //中心点跟随移动
        _rectTransform.pivot = new Vector2(x, y);
        //滑动条控制缩放
        //_rectTransform.localScale = Vector3.one * Slider.value;
        //滚轮控制缩放
        if (Input.GetAxis("Mouse ScrollWheel") != 0)
        {
            _rectTransform.localScale += Vector3.one * Input.GetAxis("Mouse ScrollWheel")*2;
            //设置最小缩放限制
            if (_rectTransform.localScale.x <= 0.75f)
            {
                _rectTransform.localScale = new Vector3(0.75f, 0.75f, 0.75f);
            }
        }
    }
    //创建路径点Image
    public void CreateImage()
    {
        //生成地图装饰物
        for (int i = 0; i < navMesh.spawnedCubes.Count; i++)
        {
            GameObject bodyimg = GameObject.Instantiate(Resources.Load<GameObject>("bodyimg"), transform);
            if (navMesh.spawnedCubes[i].tag == "Cube")
            {
                bodyimg.GetComponent<Image>().color = Color.yellow;
            }
            //都加起始位置,就是小地图 的左下角的位置(因为小地图一直在移动,所以用这个空对象作为起点)
            float a = navMesh.spawnedCubes[i].transform.position.x / 100 * _rectTransform.sizeDelta.x + Startpoint.localPosition.x;
            float b = navMesh.spawnedCubes[i].transform.position.z / 100 * _rectTransform.sizeDelta.y + Startpoint.localPosition.y;
            bodyimg.transform.localPosition = new Vector2(a, b);
            imageList.Add(bodyimg);
        }
    }
    //删除路径点Image
    public void DeletImage()
    {
        for (int i = 0; i < imageList.Count; i++)
        {
            Destroy(imageList[i].gameObject);
        }
        imageList.Clear();  
    }
    public void OnPointerClick(PointerEventData eventData)
    {
        //mapImage 的标签
        if (eventData.pointerPressRaycast.gameObject.tag == "Map")
        {
            var isClick =
            RectTransformUtility.ScreenPointToLocalPointInRectangle(_rectTransform, eventData.position, null,
                out var point);
            float x = point.x / _rectTransform.sizeDelta.x * 100;
            float y = point.y / _rectTransform.sizeDelta.y * 100;
            var endpos = player.position + new Vector3(x, 0, y);
            nav.SetDestination(endpos);
            //点击小地图控制人物移动
            navMesh.isGeneratingCubes = true;
        }
    }
}

角色挂载

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

public class NavMeshManager : MonoBehaviour
{
    public SmallMap map;
    public NavMeshAgent agent; // 角色的 NavMeshAgent
    public GameObject cubePrefab; // 用于生成的 Cube 预制件
    public float cubeSpacing = 2f; // Cube 之间的距离

    public List<GameObject> spawnedCubes = new List<GameObject>();
    public bool isGeneratingCubes = false;
    void Update()
    {
        //有这个可以点击地图移动,让小地图动
        //if (Input.GetMouseButtonDown(0))
        //{
        //    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        //    if (Physics.Raycast(ray, out RaycastHit hit))
        //    {
        //        // 设置导航目标点
        //        agent.SetDestination(hit.point);
        //        isGeneratingCubes = true;
        //    }
        //}

        if (isGeneratingCubes && agent.hasPath && agent.remainingDistance > agent.stoppingDistance)
        {
            // 清除之前生成的所有 Cube
            ClearCubes();
            // 生成路径上的 Cube
            GenerateCubesAlongPath(agent.path);
            
            isGeneratingCubes = false;
        }
    }

    private void GenerateCubesAlongPath(NavMeshPath path)
    {
        if (path.corners.Length < 2)
        {
            return;
        }

        Vector3 previousCorner = path.corners[0];
        float distanceSinceLastCube = 0f;

        for (int i = 1; i < path.corners.Length; i++)
        {
            Vector3 corner = path.corners[i];
            float segmentLength = Vector3.Distance(previousCorner, corner);

            while (distanceSinceLastCube < segmentLength)
            {
                Vector3 direction = (corner - previousCorner).normalized;
                Vector3 cubePosition = previousCorner + direction * distanceSinceLastCube;

                GameObject cube = Instantiate(cubePrefab, cubePosition, Quaternion.identity);
                spawnedCubes.Add(cube);

                distanceSinceLastCube += cubeSpacing;
            }
            
            distanceSinceLastCube -= segmentLength;
            previousCorner = corner;
        }
    }
    //清除生成的代表路径点的Cube
    private void ClearCubes()
    {
        foreach (var cube in spawnedCubes)
        {
            Destroy(cube);
        }
        spawnedCubes.Clear();
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.CompareTag("Cube"))
        {
            //碰撞就刷新
            map.DeletImage();
            Destroy(other.gameObject);
            spawnedCubes.Remove(other.gameObject);
            map.CreateImage();
        }
    }
}

预制体预览

路径点Image

路径点预制体

角色预制体

标签:void,地图,rectTransform,点击,mesh,new,using,导航,public
From: https://blog.csdn.net/djrjnfjdjejb/article/details/140038103

相关文章

  • WordPress 5.5+ 如何自定义XML 站点地图功能
    关键要点在WordPress5.5中,WordPress将导出一个站点地图索引文件/wp-sitemap.xml。这是主要的XML文件,其中包含WordPress网站公开的所有站点地图页面的列表。该站点地图索引最多可容纳50000个站点地图,单个站点地图最多可容纳2000个条目(可过滤)。默认情况下,将为所有公开和可公开查......
  • Vue Ant Design中a-tree组件支持点击父节点名称(title\label)所有子节点选中
    核心代码<a-treeref="treeRef"class="draggable-tree"v-if="treeData.length":tree-data="treeData"......
  • flutter3空页面加导航
    import'package:flutter/material.dart';voidmain(){runApp(constGoWaterMyApp());}classGoWaterMyAppextendsStatelessWidget{constGoWaterMyApp({super.key});@overrideWidgetbuild(BuildContextcontext){returnMaterialApp(......
  • UE4 C++ 随机生成迷宫地图
    参考参考原理就是利用一个房间的三个方向(排除进入口)出口(可以减少,即设置墙壁),从而获得下一次房间生成的位置,其中涉及到对于多个房间重叠,生成结束后如何对缺口进行修补等功能实现RoomBaseActor该Actor类是后续创建房间的基类,如果想要固定所有房间形状即只改变出口个数,那么在该类......
  • 创新实训(十)——代码美化部分:导航栏的active
    代码美化部分————导航栏的active对于导航栏来说,当选定在某个功能部分时,当前模块会有高亮显示。查看main-nav.php中有管导航栏的代码<divclass="collapsenavbar-collapse"id="navbarSupportedContent"> <ulclass="navnav-pillsmain-navmr-auto"> <liclass="......
  • python pyautogui实现图片识别点击失败后重试
    安装库 pipinstallPillowpipinstallopencv-pythonconfidence作用confidence参数是用于指定图像匹配的信度(或置信度)的,它表示图像匹配的准确程度。这个参数的值在0到1之间,数值越高表示匹配的要求越严格。具体来说,confidence参数用于调整在屏幕上搜索目标图像时......
  • 地图瓦片服务器搭建
    文章目录一、OpenStreetMap-Tile-Server二、OpenStreetMap地图资源下载三、加载地图资源①移动本地osm.pbf文件到docker容器中②解析osm.pbf文件③创建Postgre账号:renderer,表结构创建,地图数据导入数据库④下载地图公共资源,这里有点坑,这里详细说一下四、启动瓦片服务器五......
  • three.js+vue实现酷炫三维地图web3d大屏可视化GIS地图
    三维地图效果如下,gif压缩导致画质变差了,哈哈three.js+vue代码如下:<template><divid="chinaMap"><divid="threejs"></div><!--右侧按钮--><divclass="rightButton"><divv-for="(item,i......
  • excel电子表格双表多列修改,点击式。
        excel的xlookup确实非常简单,有部分功能也非常快。但是有的人不会公式,或者不喜欢用公式,或者没有excel2021以上的版本。而且xlookup确实也有些还不是很完美的地方,比如对多列关联查询很慢。所以我们还是有必要增加类似的办法,hpctb提供了“双表多列修改”,我们来看一看。......
  • 高精地图的黄昏与车端感知的黎明
    高精地图的黄昏与车端感知的黎明在过去几年的时间里,自动驾驶行业的技术路线经历了依赖高精地图向“重感知、轻地图”的转变。在营销口径上,有人宣传轻图,有人声称无图,还有人喊出了真无图或全面无图的口号,林林总总,令人眼花缭乱,请问元芳你怎么看?附赠自动驾驶最全的学习资料......