Урна: дух встаёт у края станции в свободной клетке со стороны урны и смотрит на неё, а не влетает в центр
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
d7c80341d2
commit
fad57a3756
@@ -198,10 +198,47 @@ namespace NecromancerTome
|
||||
{
|
||||
_pending = true;
|
||||
_actAt = Time.time + (motion != null ? CinerariumGenieMotion.ActDelay : 0f);
|
||||
motion?.Visit(World.blockToTransformPos(at.Value) - Origin.position);
|
||||
if (motion != null)
|
||||
{
|
||||
Vector3 look = World.blockToTransformPos(at.Value) - Origin.position;
|
||||
motion.Visit(Stand(_world, at.Value, out bool beside) - Origin.position, look, beside);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Где духу встать у места работы (16.10: «влетает в станцию в самый центр... логичнее к краю станции с
|
||||
/// доступной стороны»): из четырёх соседних клеток - свободная (воздух или растение), ближайшая к урне; дух встаёт у
|
||||
/// её края со стороны места. Свободной нет - над местом. Возвращает низ точки в координатах мира (blockToTransformPos).</summary>
|
||||
Vector3 Stand(World _world, Vector3i _at, out bool _beside)
|
||||
{
|
||||
Vector3i urn = ToWorldPos();
|
||||
Vector3i best = _at;
|
||||
int bestD = int.MaxValue;
|
||||
foreach (Vector3i dir in new[] { Vector3i.forward, Vector3i.back, Vector3i.left, Vector3i.right })
|
||||
{
|
||||
Vector3i n = _at + dir;
|
||||
BlockValue bv = _world.GetBlock(n);
|
||||
if (!bv.isair && !(bv.Block is BlockPlant))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int d = (n.x - urn.x) * (n.x - urn.x) + (n.z - urn.z) * (n.z - urn.z);
|
||||
if (d < bestD)
|
||||
{
|
||||
bestD = d;
|
||||
best = n;
|
||||
}
|
||||
}
|
||||
_beside = best != _at;
|
||||
Vector3 at = World.blockToTransformPos(_at);
|
||||
if (!_beside)
|
||||
{
|
||||
return at;
|
||||
}
|
||||
Vector3 n0 = World.blockToTransformPos(best);
|
||||
return Vector3.Lerp(n0, at, 0.2f); // чуть ближе к месту - у самого края
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Череп.
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
@@ -309,14 +309,20 @@ namespace NecromancerTome
|
||||
/// <summary>Светящиеся материалы рендереров - вернуть после почернения.</summary>
|
||||
readonly Dictionary<Renderer, Material[]> _glowing = new Dictionary<Renderer, Material[]>();
|
||||
|
||||
/// <summary>_worldUnity - точка в координатах сцены (без Origin): низ блока, где дух работал.</summary>
|
||||
public void Visit(Vector3 _worldUnity)
|
||||
/// <summary>Куда смотреть за работой (в координатах модели урны); _beside - дух стоит сбоку от места, а не над ним.</summary>
|
||||
Vector3 _look;
|
||||
bool _beside;
|
||||
|
||||
/// <summary>Точки - в координатах сцены (без Origin): _stand - где встать (низ клетки), _look - низ клетки места работы.</summary>
|
||||
public void Visit(Vector3 _stand, Vector3 _lookAt, bool _besideIt)
|
||||
{
|
||||
if (transform.parent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_visit = transform.parent.InverseTransformPoint(_worldUnity);
|
||||
_visit = transform.parent.InverseTransformPoint(_stand);
|
||||
_look = transform.parent.InverseTransformPoint(_lookAt);
|
||||
_beside = _besideIt;
|
||||
_t = 0f;
|
||||
}
|
||||
|
||||
@@ -379,10 +385,13 @@ namespace NecromancerTome
|
||||
_t += Time.deltaTime;
|
||||
if (_t < OutSeconds + WorkSeconds + BackSeconds)
|
||||
{
|
||||
Vector3 over = _visit + new Vector3(0f, CinerariumGenie.OffsetY + 0.6f, 0f) + Quaternion.Euler(0f, _yaw, 0f) * new Vector3(0f, 0f, CinerariumGenie.Forward);
|
||||
// Сбоку - на уровне места (тело вровень со станцией), над местом - выше него.
|
||||
Vector3 over = _visit + new Vector3(0f, CinerariumGenie.OffsetY + (_beside ? 0.15f : 0.8f), 0f) + Quaternion.Euler(0f, _yaw, 0f) * new Vector3(0f, 0f, CinerariumGenie.Forward);
|
||||
Vector3 d = _visit - new Vector3(0f, CinerariumGenie.OffsetY, 0f);
|
||||
bool far = d.x * d.x + d.z * d.z > 0.01f;
|
||||
float toPlace = far ? Mathf.Atan2(d.x, d.z) * Mathf.Rad2Deg : _yaw;
|
||||
Vector3 dl = _look - _visit;
|
||||
float toLook = dl.x * dl.x + dl.z * dl.z > 0.01f ? Mathf.Atan2(dl.x, dl.z) * Mathf.Rad2Deg : toPlace;
|
||||
float k, face, w = 0f;
|
||||
if (_t < OutSeconds)
|
||||
{
|
||||
@@ -392,7 +401,7 @@ namespace NecromancerTome
|
||||
else if (_t < OutSeconds + WorkSeconds)
|
||||
{
|
||||
k = 1f;
|
||||
face = toPlace;
|
||||
face = toLook; // за работой - лицом к станции
|
||||
w = Mathf.Sin((_t - OutSeconds) / WorkSeconds * Mathf.PI);
|
||||
}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user