在Havok Vision中编写 NavMesh 寻路

这篇教程的前提是已经掌握了如何在PA中创建NavMesh,如果你还不会,请参考官方的教程
http://www.anarchy.cn/portal.php?mod=view&aid=15

首先创建我们的Hero, 寻路的主角
我选择在代码中创建的方式,而创建坐标是在PA中创建一个 名为 Spawn的模型,给它一个 key 比如 9527 . 然后我们在 Vision中通过key 找到它

[cc language=”c++”]
VisBaseEntity_cl * pPlayerSpawn = Vision::Game.SearchEntity(“9527”);
if(NULL != pPlayerSpawn){
Vision::Message.Add(1, “Try To CreatePlayer”);
hkvVec3 pos = pPlayerSpawn->GetPosition();
hkvVec3 rot = pPlayerSpawn->GetOrientation();
m_playerEntity = SpawnPlayer(“Models/Eddy Export/Eddy.MODEL”,pos, rot);
//把出生点隐藏掉
pPlayerSpawn->SetVisibleBitmask(0);
}
[/cc]

SpawnPlayer 函数的内如
[cc language=”c++”]
VisBaseEntity_cl * tmp = Vision::Game.CreateEntity(“VisBaseEntity_cl”, position, prefabName);
if(NULL != tmp){
tmp->SetOrientation(orientation);
m_vPos = tmp->GetPosition();
m_vRot = tmp->GetOrientation();
}
return tmp;
[/cc]

有了Hero后,就可以开始创建寻路AI了。
这里有见基础的组件来做

[cc language=”c++”]
m_aiSteering = new vHavokAiSteering();
m_aiSteering->SetRadius(40);
m_aiSteering->SetDesiredSpeed(400);
m_aiSteering->SetEntityPivotHeight(0);
m_aiSteering->SetSensorSize(500);
m_aiSteering->SetTurnRadius(40);
m_aiSteering->SetKinematicConstraint(vHavokAiSteering::CONSTRAINT_LINEAR_AND_ANGULAR);
m_aiSteering->SetMaximalAngularVelocity(4);
m_aiSteering->SetMaximalAcceleration(2000);
m_aiSteering->SetMaximalDeceleration(3000);

m_playerEntity->AddComponent(m_aiSteering);
[/cc]

接下来要做的事情显而易见,就是点击屏幕,然后算出投影到NavMesh上的坐标,然后寻路过去呗
对于lua 来说有个 Sceene:PickPoint. cpp 也有可惜没有 export dll 没事,我们抄写出来就行

like this
[cc language=”cpp”]
hkvVec3 * MyGameManager::PickPoint( float x, float y, float fMaxDist )
{
hkvVec3 *result = NULL;

hkvVec3 traceStart = Vision::Camera.GetCurrentCameraPosition();
hkvVec3 traceDir;
Vision::Contexts.GetCurrentContext()->GetTraceDirFromScreenPos(x, y, traceDir, fMaxDist);
hkvVec3 traceEnd = traceStart + traceDir;

hkVector4 s;
vHavokConversionUtils::VisVecToPhysVecWorld(traceStart, s);
hkVector4 e;
vHavokConversionUtils::VisVecToPhysVecWorld(traceEnd, e);

hkaiNavMeshQueryMediator::RaycastInput rcInput;
rcInput.m_from = s;
rcInput.m_to = e;

hkaiNavMeshQueryMediator::HitDetails hitInfo;

const hkaiNavMeshQueryMediator* mediator = vHavokAiModule::GetInstance()->GetAiWorld()->getDynamicQueryMediator();
hkBool didHit = mediator->castRay( rcInput, hitInfo );

if (didHit)
{
hkVector4 hitPoint;
hitPoint.setInterpolate4( s, e, hitInfo.m_hitFraction);

result = new hkvVec3(0);
vHavokConversionUtils::PhysVecToVisVecWorld(hitPoint, *result);
}

return result;
}
[/cc]

最后的最后,在Run函数中检测鼠标是否按下,然后做这样的事情
[cc language=”cpp”]
if(bOnMouseClick){
hkvVec3 * goal = PickPoint(posX, posY);
if(goal){
m_aiSteering->RequestPathTo(*goal);
}else{
m_aiSteering->CancelPath();
}
}
[/cc]

这个时候如果你想说,我看不到鼠标咋办? 很好办,自己画一个
[cc language=”cpp”]
void MyGameManager::DrawCursor(float posX, float posY)
{
Vision::Game.DrawSingleLine2D(posX,posY,posX + 10, posY + 5, V_RGBA_GREEN);
Vision::Game.DrawSingleLine2D(posX,posY,posX + 5, posY + 10, V_RGBA_GREEN);
Vision::Game.DrawSingleLine2D(posX + 10,posY + 5,posX + 5, posY + 10, V_RGBA_GREEN);

Vision::Message.Print(1,200,500,”Mouse Pos X %f Y %f”, posX, posY);
}
[/cc]

最后如果你又问,我的Hero在寻路的时候不会转向怎么办,也好办,写个Hkt 或者,用代码来动态算
在 Run 函数中加入如下
[cc language=”cpp”]
if(m_aiSteering->HasPath()){
hkvVec3 lastPos = m_vPos;
hkvVec3 nowPos = m_playerEntity->GetPosition();
float dx = lastPos.x – nowPos.x;
float dy = lastPos.y – nowPos.y;
float degree = hkvMath::atan2Deg(dy,dx) – 90;
m_vRot = hkvVec3(degree,0,0);
m_eState = ROLE_RUN;
}
m_playerEntity->SetOrientation(m_vRot);
[/cc]

如果你问我Hkt 怎么做转向? 改日再说吧,我要睡觉啦。

发表评论

电子邮件地址不会被公开。 必填项已用*标注