diff --git a/HarmonySrc/Possession.cs b/HarmonySrc/Possession.cs
index ad8f26f..8a87b55 100644
--- a/HarmonySrc/Possession.cs
+++ b/HarmonySrc/Possession.cs
@@ -144,13 +144,14 @@ namespace NecromancerTome
/// Камера - позади и выше головы зомби.
public const float CamBack = 2.6f;
/// Вид от первого лица (указание 13.10): клавиша ~/ё - как переключение вида у персонажа в игре
- /// (QuickMenu, по умолчанию Backquote; и CameraChange геймпада), каждое вселение начинается от третьего лица. Камера - в голове, голова сжата
- /// (HideHead), положение глаз сглажено (FpSmooth) - голова зомби на ходу мотается.
+ /// (QuickMenu, по умолчанию Backquote; и CameraChange геймпада), каждое вселение начинается от третьего лица. Камера - в голове, тело - только тень
+ /// (HideBody), положение глаз сглажено (FpSmooth) - голова зомби на ходу мотается.
public static bool FirstPerson;
public const float FpForward = 0.12f, FpSmooth = 12f;
static Vector3 _fpEye;
- static Transform _hiddenHead;
- static Vector3 _hiddenHeadScale;
+ static readonly List _hiddenRenderers = new List();
+ static readonly List _hiddenModes = new List();
+ static EntityAlive _hiddenBody;
public const float CamUp = 0.6f;
/// Как далеко зомби замечают одержимого: зрение зомби - 30 м (entityclasses.xml SightRange).
public const float TauntRange = 30f;
@@ -354,7 +355,7 @@ namespace NecromancerTome
}
Active = false;
FirstPerson = false;
- HideHead(null);
+ HideBody(null);
RatLoot.CloseIfViewing();
WolfBag.CloseWindow();
RatPhase.Stop(GameManager.Instance?.World, Zombie, "выход из одержимости");
@@ -579,7 +580,7 @@ namespace NecromancerTome
_fpEye = Vector3.zero;
if (!FirstPerson)
{
- HideHead(null);
+ HideBody(null);
}
Debug.Log("[NecromancerTome] Possession: вид от " + (FirstPerson ? "первого" : "третьего") + " лица");
}
@@ -2024,26 +2025,39 @@ namespace NecromancerTome
_flyZoomHeld = false;
}
- /// Голова одержимого сжата почти в точку, пока вид от первого лица, - иначе камера внутри черепа
- /// (у зомби модель цельная, отдельных рук, как у персонажа, нет). Ставится каждый кадр после аниматора;
- /// null - вернуть прежний масштаб.
- static void HideHead(Transform _head)
+ /// Тело одержимого в виде от первого лица - только тень (тест 13.10: изнутри видно тело, у паука на
+ /// бегу лапы и череп в кадре; сжатие одной головы не спасало). Видимость - дело своего экрана: другие игроки
+ /// рисуют этого зомби сами и видят его как обычно; так же игра прячет тело персонажа от первого лица.
+ /// Рендеры собираются один раз на вход в вид; null - вернуть каждому прежний режим тени.
+ ///
+ /// ПАМЯТЬ. Ссылки на рендеры держим только пока вид от первого лица (null чистит список).
+ static void HideBody(EntityAlive _z)
{
- if (_hiddenHead != null && _hiddenHead != _head)
- {
- _hiddenHead.localScale = _hiddenHeadScale;
- _hiddenHead = null;
- }
- if (_head == null)
+ if (_hiddenBody == _z)
{
return;
}
- if (_hiddenHead == null)
+ for (int i = 0; i < _hiddenRenderers.Count; i++)
{
- _hiddenHead = _head;
- _hiddenHeadScale = _head.localScale;
+ if (_hiddenRenderers[i] != null)
+ {
+ _hiddenRenderers[i].shadowCastingMode = _hiddenModes[i];
+ }
}
- _head.localScale = Vector3.one * 0.001f;
+ _hiddenRenderers.Clear();
+ _hiddenModes.Clear();
+ _hiddenBody = _z;
+ if (_z == null || _z.emodel == null)
+ {
+ return;
+ }
+ _z.emodel.GetComponentsInChildren(true, _hiddenRenderers);
+ for (int i = 0; i < _hiddenRenderers.Count; i++)
+ {
+ _hiddenModes.Add(_hiddenRenderers[i].shadowCastingMode);
+ _hiddenRenderers[i].shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.ShadowsOnly;
+ }
+ Debug.Log("[NecromancerTome] Possession: тело " + _z.EntityName + " - только тень, рендеров " + _hiddenRenderers.Count);
}
/// Из постфикса vp_FPCamera.LateUpdate: камера позади и выше головы зомби, не сквозь стены.
@@ -2065,13 +2079,12 @@ namespace NecromancerTome
Quaternion rot = Quaternion.Euler(-_pitch, _yaw, 0f);
if (FirstPerson)
{
- // Положение головы - уже после аниматора (мы в LateUpdate камеры), до сжатия: сжатие масштаба
- // самой кости её положения не меняет.
+ // Положение головы - уже после аниматора (мы в LateUpdate камеры).
Vector3 want = anchor + rot * Vector3.forward * FpForward;
_fpEye = _fpEye == Vector3.zero || (want - _fpEye).sqrMagnitude > 4f
? want
: Vector3.Lerp(_fpEye, want, 1f - Mathf.Exp(-FpSmooth * Time.deltaTime));
- HideHead(head);
+ HideBody(z);
_camera.SetPositionAndRotation(_fpEye, rot);
return;
}