Есть рабочий вариант, требующий допилки:
|
Код
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
if (!m_pPlayer->IsClient()) // marcio: fixes the eye direction for remote players
vNewEyeDirection = (m_lookTarget - vNewEyePosition).GetNormalizedSafe(state.eyeDirection);
else
{
if (m_pPlayer->IsThirdPerson())
{
Vec3 head_position = Vec3(ZERO);
head_position = m_pPlayer->GetBonePosition("Bip01 Head");
if(head_position.IsZero())
vNewEyeDirection = m_pPlayer->GetViewQuatFinal().GetColumn1();
else
{
const float max_dist = 200.0f;
const float min_dist = 5.0f;
head_position.z = vNewEyePosition.z;
CCamera& cam = GetISystem()->GetViewCamera();
ray_hit hit; hit.dist = min_dist; hit.pt = Vec3(ZERO);
IPhysicalEntity *pEnt_to_ignore = m_pPlayer->GetEntity()->GetPhysics();
if (gEnv->pPhysicalWorld)
{
gEnv->pPhysicalWorld->RayWorldIntersection(cam.GetPosition(), cam.GetViewdir()*max_dist, ent_all,
rwi_colltype_any | rwi_stop_at_pierceable | rwi_ignore_back_faces, &hit, 1, &pEnt_to_ignore, 1);
}
if (hit.dist < min_dist)
hit.dist = min_dist;
else if (hit.dist > max_dist)
hit.dist = max_dist;
Vec3 cd_ps = cam.GetPosition() + cam.GetViewdir()*hit.dist;
Vec3 rlviev_dir = cd_ps - head_position;
if (!hit.pt.IsZero())
rlviev_dir = hit.pt - head_position;
vNewEyeDirection = rlviev_dir.normalized();
}
}
else
vNewEyeDirection = m_pPlayer->GetViewQuatFinal().GetColumn1();
}
|
в функции "CPlayerMovementController::UpdateMovementState" заменить этот код:
|
Код
|
1
2
3
4
|
if (!m_pPlayer->IsClient()) // marcio: fixes the eye direction for remote players
vNewEyeDirection = (m_lookTarget - vNewEyePosition).GetNormalizedSafe(state.eyeDirection);
else
vNewEyeDirection = m_pPlayer->GetViewQuatFinal().GetColumn1();
|
. Минус в том, что я давно отказался от системы "аимпоз" и использую собственное решение для реализации прицеливания персонажей, которое не требует анимации "аимпозы" для каждого чиха персонажа, а потому не могу утверждать со 100% уверенность что такой подход будет работать для стандартной системой "аимпоз", но по идее должно, у меня просто нет сейчас времени протестировать. Если у тебя в коде нет функции от класса CPlayer - m_pPlayer->GetBonePosition её можно заменить на m_pPlayer->GetEntity()->GetPos(); Эти строки убери - "if (!hit.pt.IsZero())
rlviev_dir = hit.pt - head_position;" - иначе параметр min_dist не будет работать, так же параметр min_dist нужно будет скорректировать.
Работает такой вариант? Если нет, то что можно попробовать: 1) умножать cam.GetViewdir() на отрицательное значение дистанции до поверхности (-hit.dist)( в случае если при умножении на положительное значение персонаж "пытается" посмотреть назад); 2) в значение вектора head_position записать на старте положение кости Bip01 Spine3(координаты кости обязательно должны быть глобальными)(если такая кость есть на скелете, если нет то это будет корневая кость к которой крепятся руки и голова/шея). В общем, даже если не работает нужно посмотреть на скрин с результатом чтобы сделать выводы, что следует править для стандартной системы аимпоз. И оказывается ли на них вообще какой либо эффект. Но оружие само по себе теперь должно стрелять в режиме от 3го лица в не зависимости от положения камеры точно по перекрестию(это проверено).