zoukankan      html  css  js  c++  java
  • Unity获取Agent导航网格上的随机点

    核心原理是,获取导航网格上的一个网格三角形,然后获取这个网格三角形 上的随机点(对逐个两个顶点之间获取插值)

        /// <summary>
        /// 获取随机位置
        /// </summary>
        /// <returns></returns>
        public Vector3 GetRandomPoint()
        {
            NavMeshTriangulation navMeshData = NavMesh.CalculateTriangulation();
    
            int t = Random.Range(0, navMeshData.indices.Length - 3);
    
            Vector3 point = Vector3.Lerp(navMeshData.vertices[navMeshData.indices[t]], navMeshData.vertices[navMeshData.indices[t + 1]], Random.value);
            point = Vector3.Lerp(point, navMeshData.vertices[navMeshData.indices[t + 2]], Random.value);
    
            return point;
        }
    
        /// <summary>
        /// 获取一个高精度的范围外随机点
        /// </summary>
        /// <param name="targetPoint"></param>
        /// <param name="distance"></param>
        /// <param name="success"></param>
        /// <returns></returns>
        public Vector3 GetRandomRangePointWithHighPrecision(Vector3 targetPoint, float distance, out bool success)
        {
            NavMeshTriangulation navMeshData = NavMesh.CalculateTriangulation();
            List<int> list = new List<int>();
            //获取所有三角的第一个顶点的索引值
            for (int i = 0; i < navMeshData.indices.Length-3; i++)
                list.Add(i);
            int count = list.Count; Debug.Log("顶点数量:" + navMeshData.indices.Length);
            List<Vector3> triangle = new List<Vector3>();
            
            for (int i = 0; i < count; i++)
            {
                //判断当前的顶点是否在列表中,并且该顶点的另外两个顶点是否在列表中(如果不在,表示已经被判断过,并且不符合条件)
                int index = Random.Range(0, list.Count);
                if (Vector3.Distance(targetPoint, navMeshData.vertices[navMeshData.indices[list[index]]]) > distance) triangle.Add(navMeshData.vertices[navMeshData.indices[list[index]]]);
                if (list.Contains(list[index] + 1)&&Vector3.Distance(targetPoint, navMeshData.vertices[navMeshData.indices[list[index] + 1]]) > distance) triangle.Add(navMeshData.vertices[navMeshData.indices[list[index] + 1]]);
                if (list.Contains(list[index] + 2)&&Vector3.Distance(targetPoint, navMeshData.vertices[navMeshData.indices[list[index] + 2]]) > distance) triangle.Add(navMeshData.vertices[navMeshData.indices[list[index] + 2]]);
                if (triangle.Count > 0) break;
                list.RemoveAt(index);
            }
    
            Vector3 point = Vector3.zero;
            success = false;
            if (triangle.Count > 0)
            {
                point = GerLerpPoint(triangle);
                success = true;
            }
            return point;
        }
    
        /// <summary>
        /// 获取远离tartgetPoint的点
        /// </summary>
        /// <param name="tartpoint"></param>
        /// <returns></returns>
        public Vector3 GetRandomEscapPoint(Vector3 targetPoint,float distance,out bool success)
        {
            NavMeshTriangulation navMeshData = NavMesh.CalculateTriangulation();
            List<int> list = new List<int>();
            //获取所有三角的第一个顶点的索引值
            for(int i = 0; i < navMeshData.indices.Length; i+=3)
                list.Add(i);
            int count = list.Count;Debug.Log("顶点数量:"+navMeshData.indices.Length);
            List<Vector3> triangle=new List<Vector3>();
            for(int i = 0; i < count; i++)
            {
                int index = Random.Range(0, list.Count);
                if (Vector3.Distance(targetPoint, navMeshData.vertices[navMeshData.indices[list[index]]]) > distance) triangle.Add(navMeshData.vertices[navMeshData.indices[list[index]]]);
                if (Vector3.Distance(targetPoint, navMeshData.vertices[navMeshData.indices[list[index] + 1]]) > distance) triangle.Add(navMeshData.vertices[navMeshData.indices[list[index] + 1]]);
                if (Vector3.Distance(targetPoint, navMeshData.vertices[navMeshData.indices[list[index] + 2]]) > distance) triangle.Add(navMeshData.vertices[navMeshData.indices[list[index] + 2]]);
                if (triangle.Count > 0) break;
                list.RemoveAt(index);
            }
    
            Vector3 point = Vector3.zero;
            success = false;
            if (triangle.Count > 0)
            {
                point = GerLerpPoint(triangle);
                success = true;
            }
            return point;
        }
        //获取多个顶点之间的一个随机点
        Vector3 GerLerpPoint(List<Vector3> list)
        {
            Vector3 point = list[0];
            foreach(Vector3 v in list)
            {
                point = Vector3.Lerp(point, v, Random.value);
            }
            return point;
        }
  • 相关阅读:
    requirejs 初探
    jquery版本
    querystring
    git 使用记录
    nodejs mocha 单元测试
    Jquery之promise
    nodejs express命令问题
    Sublime Text 资料整理
    SQL SERVER 2008 R2 自动备份并删除过期备份数据
    无法编辑的word解密
  • 原文地址:https://www.cnblogs.com/xiaoahui/p/12854231.html
Copyright © 2011-2022 走看看