下面这个方法返回一个在当前鼠标指向的物品的EntityId。在使用这个方法之前,确保你的代码中的鼠标是显示的。
EntityId GetMouseEntityID()
{
static ray_hit hit;
float x, y, xMouse, yMouse, zMouse = 0.0f;
if(!gEnv->pHardwareMouse || !gEnv->pRenderer || !gEnv->p3DEngine || !gEnv->pSystem
|| !gEnv->pEntitySystem || !g_pGame->GetIGameFramework())
return 0;
//得到当前的玩家句柄
IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor();
if (!pClientActor)
return 0;
//得到当前的鼠标位置(相对于客户区坐标)
gEnv->pHardwareMouse->GetHardwareMouseClientPosition(&x,&y);
y = gEnv->pRenderer->GetHeight() - y;
//反式投影 由(x, y, 0) 得到 (xMouse, yMouse, zMouse),也就是鼠标位置在3D世界中的位置
gEnv->pRenderer->UnProjectFromScreen(x, y, 0.0f,&xMouse,&yMouse,&zMouse);
static const unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any;
//再得到照相机在3D世界中的位置,和视线的深度
//这样由鼠标位置和照相机的位置组成方向,在视线深度上进行射线测试
//注意下面的第三行的代码,表示的是相机位置到鼠标位置的方向
float fRange = gEnv->p3DEngine->GetMaxViewDistance();
Vec3 vCamPos = gEnv->pSystem->GetViewCamera().GetPosition();
Vec3 vDir = (Vec3(xMouse,yMouse,zMouse) - vCamPos).GetNormalizedSafe();
IPhysicalEntity *pPhysicalEnt = pClientActor->GetEntity() ?
pClientActor->GetEntity()->GetPhysics() : NULL;
if(!pPhysicalEnt)
return 0;
if (gEnv->pPhysicalWorld &&
gEnv->pPhysicalWorld->RayWorldIntersection(vCamPos, vDir * fRange, ent_all,
flags, &hit, 1, pPhysicalEnt))
{
if (gEnv->p3DEngine->RefineRayHit(&hit, vDir * fRange))
{
if (IEntity *pEntity = gEnv->pEntitySystem->GetEntityFromPhysics(hit.pCollider))
{
return pEntity->GetId();
}
}
}
return 0;
}