Урна: дух летит к делу лицом, над местом жестикулирует руками, дело - в середине жеста, назад лицом к урне
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
23587d78e0
commit
7e93e19c5f
@@ -226,10 +226,20 @@ namespace NecromancerTome
|
||||
{
|
||||
float _yaw;
|
||||
float _phase;
|
||||
/// <summary>Полёт к месту работы и обратно: точка в координатах модели урны и сколько осталось.</summary>
|
||||
/// <summary>Полёт к месту работы и обратно (16.10: «возвращается задом», «делал действие не сразу, а хоть руками
|
||||
/// пошевелив»): туда - лицом к месту, над местом - жест руками (дело делается в его середине, см. ActDelay),
|
||||
/// обратно - развернувшись лицом к урне. Точка - в координатах модели урны; _t - время с начала полёта, -1 - дома.</summary>
|
||||
Vector3 _visit;
|
||||
float _visitLeft;
|
||||
public const float VisitSeconds = 2.2f;
|
||||
float _t = -1f;
|
||||
public static float OutSeconds = 1.3f;
|
||||
public static float WorkSeconds = 1.6f;
|
||||
public static float BackSeconds = 1.3f;
|
||||
/// <summary>Через сколько после начала полёта дело выполняется - в середине жеста.</summary>
|
||||
public static float ActDelay => OutSeconds + WorkSeconds * 0.5f;
|
||||
/// <summary>Жест: плечи вперёд до GestureFwd градусов, локти ходят на ±GestureWave вразнобой.</summary>
|
||||
public static float GestureFwd = 55f;
|
||||
public static float GestureWave = 30f;
|
||||
bool _gesturing;
|
||||
/// <summary>Почернел и замер (готовое класть некуда, решение 06.10).</summary>
|
||||
bool _stuck;
|
||||
/// <summary>Кости рук (плечо, предплечье, кисть по сторонам) и их поворот в позе покоя.</summary>
|
||||
@@ -240,6 +250,11 @@ namespace NecromancerTome
|
||||
/// <summary>Опустить руки из позы покоя: направление плеча и предплечья задаётся в осях модели (вперёд - +Z),
|
||||
/// поворот - от текущего направления кости к нужному, так что оси самих костей значения не имеют.</summary>
|
||||
public void Pose()
|
||||
{
|
||||
Pose(CinerariumGenie.ArmFwd, CinerariumGenie.Elbow, CinerariumGenie.Elbow);
|
||||
}
|
||||
|
||||
void Pose(float _fwd, float _elbowL, float _elbowR)
|
||||
{
|
||||
if (_arm == null)
|
||||
{
|
||||
@@ -283,9 +298,9 @@ namespace NecromancerTome
|
||||
continue;
|
||||
}
|
||||
float sign = Mathf.Sign(transform.InverseTransformPoint(up.position).x);
|
||||
float o = CinerariumGenie.ArmOut * Mathf.Deg2Rad, f = CinerariumGenie.ArmFwd * Mathf.Deg2Rad;
|
||||
float o = CinerariumGenie.ArmOut * Mathf.Deg2Rad, f = _fwd * Mathf.Deg2Rad;
|
||||
Vector3 upDir = new Vector3(sign * Mathf.Sin(o), -Mathf.Cos(o) * Mathf.Cos(f), Mathf.Sin(f)).normalized;
|
||||
Vector3 foreDir = Vector3.RotateTowards(upDir, Vector3.forward, CinerariumGenie.Elbow * Mathf.Deg2Rad, 0f);
|
||||
Vector3 foreDir = Vector3.RotateTowards(upDir, Vector3.forward, (side == 0 ? _elbowL : _elbowR) * Mathf.Deg2Rad, 0f);
|
||||
up.rotation = Quaternion.FromToRotation(fore.position - up.position, transform.TransformDirection(upDir)) * up.rotation;
|
||||
fore.rotation = Quaternion.FromToRotation(hand.position - fore.position, transform.TransformDirection(foreDir)) * fore.rotation;
|
||||
}
|
||||
@@ -302,7 +317,7 @@ namespace NecromancerTome
|
||||
return;
|
||||
}
|
||||
_visit = transform.parent.InverseTransformPoint(_worldUnity);
|
||||
_visitLeft = VisitSeconds;
|
||||
_t = 0f;
|
||||
}
|
||||
|
||||
public void SetStuck(bool _on)
|
||||
@@ -359,21 +374,54 @@ namespace NecromancerTome
|
||||
}
|
||||
float yawTarget = _yaw + CinerariumGenie.TurnSpeed * Time.deltaTime;
|
||||
Vector3 home = new Vector3(0f, CinerariumGenie.OffsetY, 0f) + Quaternion.Euler(0f, _yaw, 0f) * new Vector3(0f, 0f, CinerariumGenie.Forward);
|
||||
if (_visitLeft > 0f)
|
||||
if (_t >= 0f)
|
||||
{
|
||||
// Туда и обратно по синусу: на полпути - над местом работы, лицом к нему.
|
||||
_visitLeft -= Time.deltaTime;
|
||||
float k = Mathf.Sin(Mathf.Clamp01(1f - _visitLeft / VisitSeconds) * Mathf.PI);
|
||||
Vector3 over = _visit + new Vector3(0f, CinerariumGenie.OffsetY + 0.6f, 0f) + Quaternion.Euler(0f, _yaw, 0f) * new Vector3(0f, 0f, CinerariumGenie.Forward);
|
||||
transform.localPosition = Vector3.Lerp(home, over, k);
|
||||
Vector3 d = _visit - home;
|
||||
if (d.x * d.x + d.z * d.z > 0.01f)
|
||||
_t += Time.deltaTime;
|
||||
if (_t < OutSeconds + WorkSeconds + BackSeconds)
|
||||
{
|
||||
yawTarget = Mathf.LerpAngle(_yaw, Mathf.Atan2(d.x, d.z) * Mathf.Rad2Deg, Time.deltaTime * 4f);
|
||||
Vector3 over = _visit + new Vector3(0f, CinerariumGenie.OffsetY + 0.6f, 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;
|
||||
float k, face, w = 0f;
|
||||
if (_t < OutSeconds)
|
||||
{
|
||||
k = Mathf.SmoothStep(0f, 1f, _t / OutSeconds);
|
||||
face = toPlace;
|
||||
}
|
||||
else if (_t < OutSeconds + WorkSeconds)
|
||||
{
|
||||
k = 1f;
|
||||
face = toPlace;
|
||||
w = Mathf.Sin((_t - OutSeconds) / WorkSeconds * Mathf.PI);
|
||||
}
|
||||
else
|
||||
{
|
||||
k = 1f - Mathf.SmoothStep(0f, 1f, (_t - OutSeconds - WorkSeconds) / BackSeconds);
|
||||
face = far ? toPlace + 180f : _yaw; // назад - лицом к урне
|
||||
}
|
||||
_yaw = Mathf.MoveTowardsAngle(_yaw, face, 300f * Time.deltaTime) % 360f;
|
||||
transform.localPosition = Vector3.Lerp(home, over, k);
|
||||
transform.localRotation = Quaternion.Euler(0f, _yaw, 0f);
|
||||
if (w > 0f)
|
||||
{
|
||||
float wave = Mathf.Sin(_t * Mathf.PI * 2f * 1.5f) * GestureWave * w;
|
||||
Pose(Mathf.Lerp(CinerariumGenie.ArmFwd, GestureFwd, w), CinerariumGenie.Elbow + 15f * w + wave, CinerariumGenie.Elbow + 15f * w - wave);
|
||||
_gesturing = true;
|
||||
}
|
||||
else if (_gesturing)
|
||||
{
|
||||
Pose();
|
||||
_gesturing = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
_t = -1f;
|
||||
if (_gesturing)
|
||||
{
|
||||
Pose();
|
||||
_gesturing = false;
|
||||
}
|
||||
_yaw = yawTarget % 360f;
|
||||
transform.localRotation = Quaternion.Euler(0f, _yaw, 0f);
|
||||
return;
|
||||
}
|
||||
_yaw = yawTarget % 360f;
|
||||
float bob = CinerariumGenie.BobPeriod > 0.01f
|
||||
|
||||
Reference in New Issue
Block a user