이 페이지에서는 게임에서 CylinderObstacles를 생성, 업데이트 및 삭제하는 방법을 설명합니다.
장애물 관리 시스템에서 CylinderObstacles 클래스의 역할에 대한 설명은 동적 장애물 및 TagVolume 사용을(를) 참조하십시오.
NavTag 시스템에 대한 배경 정보는 사용자 정의 데이터로 태그 지정을(를) 참조하십시오.
게임에서 CylinderObstacle 초기화 및 파괴를 관리하는 클래스를 만들 수 있습니다. CylinderObstacle이 Gameware Navigation World 내에서 나타내는 오브젝트의 수명을 관리하는 클래스가 게임에 이미 있을 수도 있습니다. 이 경우 해당 클래스를 사용할 수 있습니다. 또한 각 프레임에서 오브젝트의 위치 및 속도를 가져올 수 있는 유사 오브젝트가 물리 시스템에 있을 수도 있습니다.
예: [Tutorial_ObstacleIntegration.cpp의 코드]
class MyGameCylinderObstacle
{
public:
MyGameCylinderObstacle() : m_navCylinderObstacle(KY_NULL) {}
void Initialize(Kaim::World* world, KyFloat32 radius, KyFloat32 height, const Kaim::Vec3f& position, const Kaim::Vec3f& linearVelocity);
void Destroy();
void Update(KyFloat32 simulationStepsInSeconds);
RigidBodyPhysics m_rigidBodyPhysics;
Kaim::Ptr<Kaim::CylinderObstacle> m_navCylinderObstacle;
};CylinderObstacle를 초기화하려면 CylinderObstacle에 필요한 데이터를 사용하여 설정하는 CylinderObstacleInitConfig 구성 클래스의 인스턴스를 제공해야 합니다. 적어도 다음을 설정해야 합니다.
예: [Tutorial_ObstacleIntegration.cpp의 코드]
void MyGameCylinderObstacle::Initialize(Kaim::World* world, KyFloat32 radius, KyFloat32 height, const Kaim::Vec3f& position, const Kaim::Vec3f& linearVelocity)
{
// Initialize the object that represents this obstacle in the physics system.
m_rigidBodyPhysics.Initialize(position, linearVelocity);
// Set up the CylinderObstacleInitConfig
Kaim::CylinderObstacleInitConfig cylinderObstacleInitConfig;
cylinderObstacleInitConfig.m_world = world;
cylinderObstacleInitConfig.m_radius = radius;
cylinderObstacleInitConfig.m_height = height;
cylinderObstacleInitConfig.m_startPosition = m_rigidBodyPhysics.GetPosition();
// This sets the NavTag as non-walkable: it will "cut a hole" in the NavMesh.
cylinderObstacleInitConfig.m_navTag.SetAsExclusive();
// Create and initialize the CylinderObstacle, and add it to its World.
m_navCylinderObstacle = *KY_NEW Kaim::CylinderObstacle;
m_navCylinderObstacle->Init(cylinderObstacleInitConfig);
// We want to draw a maximum amount of information
m_navCylinderObstacle->SetCurrentVisualDebugLOD(Kaim::VisualDebugLOD_Maximal);
}CylinderObstacle이 나타내는 오브젝트가 게임에서 해당 위치 또는 속도를 변경할 때마다 CylinderObstacle을 업데이트하여 새 상태를 반영해야 합니다. CylinderObstacle의 함수를 사용하면 새 상태를 반영할 수 있습니다.
이 경우 CylinderObstacle가 즉시 수정되는 것은 아닙니다. 다음에 World가 업데이트될 때까지 업데이트가 지연됩니다.
예: [Tutorial_ObstacleIntegration.cpp의 코드]
void MyGameCylinderObstacle::Update(KyFloat32 simulationStepsInSeconds)
{
...
// Update the object in the physics system.
m_rigidBodyPhysics.Update(simulationStepsInSeconds);
// Update the CylinderObstacle.
m_navCylinderObstacle->SetPosition(m_rigidBodyPhysics.GetPosition());
m_navCylinderObstacle->SetVelocity(m_rigidBodyPhysics.GetLinearVelocity());
}장애물의 이동이 중지되고 안정된 경우 게임의 Bot이 경로 따르기의 동적 회피 단계 중에 장애물의 존재에 반응하는 대신 지형을 통과하는 경로를 계획할 때 장애물의 존재를 고려할 수 있도록 NavMesh에 장애물을 통합할 수 있습니다.
장애물이 정지되면 해당 CylinderObstacle::DoesTriggerTagVolume() 메서드를 호출하고 true를 전달합니다. World의 다음 업데이트 중에 동일한 위치 및 치수와 CylinderObstacle을 초기화할 때 설정한 NavTag가 지정된 TagVolume이 장애물에 투명하게 생성됩니다. 그런 다음 이 TagVolume을 NavMesh에 통합하여 사용자 정의 데이터로 영역의 태그를 지정하거나 "배타적"으로 태그를 지정하고 NavMesh에서 제거할 수 있습니다. 통합이 완료되고 NavMesh가 업데이트되면 장애물의 존재가 NavMesh를 통해 관리되므로 장애물의 볼륨이 모든 동적 회피 계산에서 제거됩니다.
장애물이 다시 움직이기 시작하면 프로세스가 역순으로 진행되도록 CylinderObstacle::DoesTriggerTagVolume()을 호출하고 false를 전달합니다.
예: [Tutorial_ObstacleIntegration.cpp의 코드]
void MyGameCylinderObstacle::Update(KyFloat32 simulationStepsInSeconds)
{
const bool isStopped = m_rigidBodyPhysics.IsSleeping();
m_navCylinderObstacle->SetDoesTriggerTagVolume(isStopped);
if (isStopped)
return;
...
}CylinderObstacle을 파괴하려면
예: [Tutorial_ObstacleIntegration.cpp의 코드]
void MyGameCylinderObstacle::Destroy()
{
m_navCylinderObstacle->RemoveFromWorld();
m_navCylinderObstacle = KY_NULL;
}