先说下原理:RVO的障碍识别是通过链接的坐标点数组围成的区域,收尾相接形成的。
namespace RVO
{
/**
* <summary>Defines static obstacles in the simulation.</summary>
* 障碍区的点坐标数据结构,是个双向链表结构
*通过Simulator.addObstacle进行添加
*/
internal class Obstacle
{
internal Obstacle next_;
internal Obstacle previous_;
internal Vector2 direction_;
internal Vector2 point_;
internal int id_;
internal bool convex_;
}
}
//在 ObstacleCollect.cs 的初始化函数中增加圆形区域的识别
using System.Collections;
using System.Collections.Generic;
using RVO;
using UnityEngine;
using Vector2 = RVO.Vector2;
//这个脚本要绑在它的障碍物分组上面,方便进行循环读取,并初始化;
public class ObstacleCollect : MonoBehaviour
{
void Awake()
{
BoxCollider[] boxColliders = GetComponentsInChildren<BoxCollider>();
for (int i = 0; i < boxColliders.Length; i++)
{
float minX = boxColliders[i].transform.position.x - boxColliders[i].size.x*boxColliders[i].transform.lossyScale.x*0.5f;
float minZ = boxColliders[i].transform.position.z - boxColliders[i].size.z*boxColliders[i].transform.lossyScale.z*0.5f;
float maxX = boxColliders[i].transform.position.x + boxColliders[i].size.x*boxColliders[i].transform.lossyScale.x*0.5f;
float maxZ = boxColliders[i].transform.position.z + boxColliders[i].size.z*boxColliders[i].transform.lossyScale.z*0.5f;
IList<Vector2> obstacle = new List<Vector2>();
obstacle.Add(new Vector2(maxX, maxZ));
obstacle.Add(new Vector2(minX, maxZ));
obstacle.Add(new Vector2(minX, minZ));
obstacle.Add(new Vector2(maxX, minZ));
Simulator.Instance.addObstacle(obstacle);
}
//添加圆形 障碍区域的坐标List
CapsuleCollider[] capsuleCollider = GetComponentsInChildren<CapsuleCollider>();
for (int i = 0; i < capsuleCollider.Length; i++)
{
//x = x0 + r * cos(angle * PI / 180)
//y = y0 + r * sin(angle * PI / 180)
IList<Vector2> obstacle = new List<Vector2>();
float angle = 30;//采样角度为30度,顺时针,这个根据项目情况自行决定;可以加入三角形的障碍物。
for (int j = 0; j < 360/ angle; j++) {
float x1 = capsuleCollider[i].transform.position.x + capsuleCollider[i].radius * capsuleCollider[i].transform.lossyScale.z * Mathf.Cos(angle * j * Mathf.PI / 180);
float z1 = capsuleCollider[i].transform.position.z + capsuleCollider[i].radius * capsuleCollider[i].transform.lossyScale.z * Mathf.Sin(angle * j * Mathf.PI / 180);
obstacle.Add(new Vector2(x1, z1));
}
Simulator.Instance.addObstacle(obstacle);
}
}
// Update is called once per frame
void Update()
{
}
}
增加圆形障碍物体:通过GameObject->3D Object ->Cylinder 创建圆柱体。
运行效果:
原RVO的github地址在:https://github.com/warmtrue/RVO2-Unity