• 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;
        }
  • 相关阅读:
    leetcode-237-删除链表中的节点
    leetcode-125-验证回文串
    leetcode-217-存在重复元素
    leetcode-189-旋转数组
    leetcode-121-买卖股票的最佳时机
    leetcde-27-移除元素
    redis相关
    leetcode-26-删除排序数组中的重复项
    leetcode-16-最接近的三数之和
    基础-递归
  • 原文地址:https://www.cnblogs.com/xiaoahui/p/12854231.html
Copyright © 2020-2023  润新知