Логист - латунное кадило: два вида, дух 1/3 из окон, мигание; команды разработки
- Блоки логиста на модели кадила: по центру на подставке (necroCinerariumLogist) и новый вид у стены на кронштейне (necroCinerariumLogistWall/+Skull); выбор вида - R с урной в руке. - Дух логиста втрое меньше, в покое сидит в кадиле, на перевозку вылетает через окно крышки (у стены - не в стену) и возвращается тем же окном. - Застрял (ящик «куда» полон) - урна мигает (CinerariumBlink) вместо почерневшего духа; прежняя зелёная подмена свечения старой модели убрана. - Команды разработки без мыши: necrospawn, necroexit [quit], necrolook, necroaim, necroplace, necrohold, necrobox, necrourn, necroclick. Проверено в игре (test8): перевозка обоими видами, вылет духа, вид у стены от стены. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
b5bd4e4b2c
commit
6693d96d5e
@@ -74,7 +74,17 @@ namespace NecromancerTome
|
||||
return _prefab != null;
|
||||
}
|
||||
|
||||
public static GameObject Spawn(Transform _urnModel, float _drop)
|
||||
/// <summary>Дух логиста (18.10: «Пусть дух вылетает когда нужно что-то нести. Но уменьшим его в три раза»): размер.</summary>
|
||||
public static float LogistScale = 1f / 3f;
|
||||
/// <summary>Дом духа логиста в осях модели урны - корень модели духа внутри кадила, середина тела на высоте окон крышки
|
||||
/// (по центру - окна на 0.63 м, у стены - 0.73 м, кадило в 0.22 м от стены, стена - -z).</summary>
|
||||
public static Vector3 LogistHome = new Vector3(0f, 0.25f, 0f);
|
||||
public static Vector3 LogistWallHome = new Vector3(0f, 0.35f, -0.22f);
|
||||
/// <summary>Окна крышки - на расстоянии LogistExit от оси кадила (радиус крышки 0.21 м), по осям модели.</summary>
|
||||
public static float LogistExit = 0.3f;
|
||||
|
||||
/// <summary>_logist: 0 - обычный дух над горлышком, 1 - дух логиста в кадиле по центру, 2 - в кадиле у стены.</summary>
|
||||
public static GameObject Spawn(Transform _urnModel, float _drop, int _logist = 0)
|
||||
{
|
||||
if (_urnModel == null || !Load())
|
||||
{
|
||||
@@ -107,6 +117,12 @@ namespace NecromancerTome
|
||||
}
|
||||
CinerariumGenieMotion m = g.AddComponent<CinerariumGenieMotion>();
|
||||
m.Drop = _drop;
|
||||
if (_logist > 0)
|
||||
{
|
||||
m.Small = true;
|
||||
m.Wall = _logist == 2;
|
||||
g.transform.localScale = Vector3.one * LogistScale;
|
||||
}
|
||||
m.Pose();
|
||||
return g;
|
||||
}
|
||||
@@ -273,8 +289,14 @@ namespace NecromancerTome
|
||||
{
|
||||
public Vector3 Hover, Look; // в осях модели урны
|
||||
public float Fly;
|
||||
public bool Pass; // точка пути (окно кадила) - без жеста
|
||||
}
|
||||
|
||||
/// <summary>Дух логиста (18.10): втрое меньше, дома (в кадиле) не виден, вылетает и влетает через окно крышки.</summary>
|
||||
public bool Small;
|
||||
/// <summary>Кадило у стены: дом сдвинут к кронштейну, окно в стену (-z) не используется.</summary>
|
||||
public bool Wall;
|
||||
|
||||
readonly List<Stop> _stops = new List<Stop>();
|
||||
float _backFly;
|
||||
float _t = -1f;
|
||||
@@ -374,11 +396,23 @@ namespace NecromancerTome
|
||||
Vector3 home = Home();
|
||||
Vector3 prev = home;
|
||||
float delay = 0f;
|
||||
Vector3 exit = home;
|
||||
if (Small)
|
||||
{
|
||||
// Сначала - к окну крышки в сторону первого места (у стены окно в стену не годится), оттуда - к месту.
|
||||
exit = Window(home, transform.parent.InverseTransformPoint(_list[0].stand) - home);
|
||||
_stops.Add(new Stop { Hover = exit, Look = exit + (exit - home), Fly = 0.35f, Pass = true });
|
||||
delay += 0.35f;
|
||||
prev = exit;
|
||||
}
|
||||
foreach ((Vector3 stand, Vector3 look, bool beside) in _list)
|
||||
{
|
||||
// Высота корня духа над низом клетки места: обычный дух - над станцией 0.8 (сбоку 0.15) с поправкой урны;
|
||||
// маленький - над верхом клетки (1.05) или у её середины сбоку (0.4).
|
||||
float up = Small ? (beside ? 0.4f : 1.05f) : CinerariumGenie.OffsetY + Drop + (beside ? 0.15f : 0.8f);
|
||||
Stop st = new Stop
|
||||
{
|
||||
Hover = transform.parent.InverseTransformPoint(stand) + new Vector3(0f, CinerariumGenie.OffsetY + Drop + (beside ? 0.15f : 0.8f), 0f),
|
||||
Hover = transform.parent.InverseTransformPoint(stand) + new Vector3(0f, up, 0f),
|
||||
Look = transform.parent.InverseTransformPoint(look)
|
||||
};
|
||||
st.Fly = Mathf.Max(OutSeconds, Vector3.Distance(prev, st.Hover) / FlySpeed);
|
||||
@@ -386,13 +420,44 @@ namespace NecromancerTome
|
||||
prev = st.Hover;
|
||||
_stops.Add(st);
|
||||
}
|
||||
_backFly = Mathf.Max(BackSeconds, Vector3.Distance(prev, home) / FlySpeed);
|
||||
if (Small)
|
||||
{
|
||||
// Назад - тем же окном.
|
||||
_stops.Add(new Stop { Hover = exit, Look = home, Fly = Mathf.Max(BackSeconds, Vector3.Distance(prev, exit) / FlySpeed), Pass = true });
|
||||
prev = exit;
|
||||
}
|
||||
_backFly = Small ? 0.35f : Mathf.Max(BackSeconds, Vector3.Distance(prev, home) / FlySpeed);
|
||||
_t = 0f;
|
||||
return delay - WorkSeconds * 0.5f;
|
||||
}
|
||||
|
||||
/// <summary>Окно крышки кадила по направлению _dir (оси модели): одно из четырёх по осям x/z, у стены - не в стену.</summary>
|
||||
Vector3 Window(Vector3 _home, Vector3 _dir)
|
||||
{
|
||||
Vector3 best = Vector3.forward;
|
||||
float bestDot = float.MinValue;
|
||||
foreach (Vector3 w in new[] { Vector3.forward, Vector3.back, Vector3.left, Vector3.right })
|
||||
{
|
||||
if (Wall && w == Vector3.back)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
float d = Vector3.Dot(w, new Vector3(_dir.x, 0f, _dir.z));
|
||||
if (d > bestDot)
|
||||
{
|
||||
bestDot = d;
|
||||
best = w;
|
||||
}
|
||||
}
|
||||
return _home + best * CinerariumGenie.LogistExit;
|
||||
}
|
||||
|
||||
Vector3 Home()
|
||||
{
|
||||
if (Small)
|
||||
{
|
||||
return Wall ? CinerariumGenie.LogistWallHome : CinerariumGenie.LogistHome;
|
||||
}
|
||||
return new Vector3(0f, CinerariumGenie.OffsetY + Drop, 0f) + Quaternion.Euler(0f, _yaw, 0f) * new Vector3(0f, 0f, CinerariumGenie.Forward);
|
||||
}
|
||||
|
||||
@@ -483,14 +548,16 @@ namespace NecromancerTome
|
||||
transform.localPosition = Home();
|
||||
}
|
||||
_asleep = asleep;
|
||||
if (_hiddenApplied != CinerariumGenie.Hidden)
|
||||
}
|
||||
// Виден ли: не скрыт командой; дух логиста - только в полёте (дома сидит в кадиле). Рендереры - только при смене
|
||||
// (16.10, проверка на утечки: раньше список рендереров собирался каждые 0.5 с - мусор для GC).
|
||||
bool show = !CinerariumGenie.Hidden && (!Small || _t >= 0f);
|
||||
if (_hiddenApplied != !show)
|
||||
{
|
||||
_hiddenApplied = !show;
|
||||
foreach (Renderer r in GetComponentsInChildren<Renderer>(true))
|
||||
{
|
||||
// Только при смене (16.10, проверка на утечки: раньше список рендереров собирался каждые 0.5 с - мусор для GC).
|
||||
_hiddenApplied = CinerariumGenie.Hidden;
|
||||
foreach (Renderer r in GetComponentsInChildren<Renderer>(true))
|
||||
{
|
||||
r.enabled = !_hiddenApplied;
|
||||
}
|
||||
r.enabled = show;
|
||||
}
|
||||
}
|
||||
if (_stuck || _asleep)
|
||||
@@ -515,7 +582,7 @@ namespace NecromancerTome
|
||||
return;
|
||||
}
|
||||
acc += st.Fly;
|
||||
if (_t < acc + WorkSeconds)
|
||||
if (!st.Pass && _t < acc + WorkSeconds)
|
||||
{
|
||||
transform.localPosition = st.Hover;
|
||||
Face(st.Look - st.Hover); // за работой - лицом к месту
|
||||
@@ -523,7 +590,10 @@ namespace NecromancerTome
|
||||
transform.localRotation = Quaternion.Euler(0f, _yaw, 0f);
|
||||
return;
|
||||
}
|
||||
acc += WorkSeconds;
|
||||
if (!st.Pass)
|
||||
{
|
||||
acc += WorkSeconds;
|
||||
}
|
||||
from = st.Hover;
|
||||
}
|
||||
if (_t < acc + _backFly)
|
||||
@@ -537,6 +607,11 @@ namespace NecromancerTome
|
||||
_t = -1f;
|
||||
Gesture(0f);
|
||||
}
|
||||
if (Small)
|
||||
{
|
||||
transform.localPosition = home; // в кадиле, не виден
|
||||
return;
|
||||
}
|
||||
_yaw = yawTarget % 360f;
|
||||
float bob = CinerariumGenie.BobPeriod > 0.01f
|
||||
? Mathf.Sin((Time.time + _phase) * Mathf.PI * 2f / CinerariumGenie.BobPeriod) * CinerariumGenie.BobHeight
|
||||
|
||||
Reference in New Issue
Block a user