Духи урн: смирно по умолчанию, поза покойника (cross) на подборе, сомкнутые пальцы, временно непрозрачные
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
0dad901b64
commit
a5f166c161
+101
-14
@@ -51,14 +51,16 @@ namespace NecromancerTome
|
|||||||
}
|
}
|
||||||
/// <summary>Руки (16.10: «Т-поза бесит»): плечо от вертикали вбок и вперёд, локоть согнут вперёд, градусы.
|
/// <summary>Руки (16.10: «Т-поза бесит»): плечо от вертикали вбок и вперёд, локоть согнут вперёд, градусы.
|
||||||
/// Модель в позе покоя, аниматора нет - кости ставятся один раз при появлении.</summary>
|
/// Модель в позе покоя, аниматора нет - кости ставятся один раз при появлении.</summary>
|
||||||
public static float ArmOut = 12f;
|
public static float ArmOut = 3f; // 17.10 в игре: «По стойке смирно» - руки прямо вдоль тела (necrogenie arms 3 0 0)
|
||||||
public static float ArmFwd = 15f;
|
public static float ArmFwd = 0f;
|
||||||
public static float Elbow = 35f;
|
public static float Elbow = 0f;
|
||||||
/// <summary>Покой (17.10: «в покое руки нужно скрестить на груди»): плечо вниз-вперёд на CrossFwd, предплечье поперёк
|
/// <summary>Покой - поза покойника (17.10): плечо вниз-вперёд на CrossFwd, предплечье вверх наискось, кисть к плечу другой
|
||||||
/// груди к другому боку, одно на CrossLift выше другого, чтобы не проходили друг сквозь друга. Жест - из этой позы и назад.</summary>
|
/// стороны, вынесенному вперёд на CrossDepth ширины плеч; левая рука поверх правой - ещё на CrossLift. Жест - из этой позы
|
||||||
public static bool Cross = true;
|
/// и назад.</summary>
|
||||||
|
public static bool Cross = false; // 17.10: пока поза покойника подбирается в Blender - резервная «смирно» (Arm*)
|
||||||
public static float CrossFwd = 25f;
|
public static float CrossFwd = 25f;
|
||||||
public static float CrossLift = 0.12f;
|
public static float CrossLift = 0.15f;
|
||||||
|
public static float CrossDepth = 0.3f;
|
||||||
|
|
||||||
static GameObject _prefab;
|
static GameObject _prefab;
|
||||||
static bool _tried;
|
static bool _tried;
|
||||||
@@ -154,8 +156,7 @@ namespace NecromancerTome
|
|||||||
m.EnableKeyword("_EMISSION");
|
m.EnableKeyword("_EMISSION");
|
||||||
m.globalIlluminationFlags = MaterialGlobalIlluminationFlags.None;
|
m.globalIlluminationFlags = MaterialGlobalIlluminationFlags.None;
|
||||||
}
|
}
|
||||||
m.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
|
SetLook(m); // смешивание, глубина и очередь - тоже там (Solid)
|
||||||
SetLook(m);
|
|
||||||
_ghostMats[_src] = m;
|
_ghostMats[_src] = m;
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
@@ -165,12 +166,33 @@ namespace NecromancerTome
|
|||||||
/// <summary>Своё свечение тела, доля от Tint.</summary>
|
/// <summary>Своё свечение тела, доля от Tint.</summary>
|
||||||
public static float Glow = 0.35f;
|
public static float Glow = 0.35f;
|
||||||
|
|
||||||
|
/// <summary>ВРЕМЕННО (17.10: «Временно убери им прозрачность. А то плохо видно» - пока подбирается поза рук): дух
|
||||||
|
/// непрозрачный, обычная заливка с записью глубины. Перед релизом вернуть false (BACKLOG). Консоль: necrogenie solid 0|1.</summary>
|
||||||
|
public static bool Solid = true;
|
||||||
|
|
||||||
static void SetLook(Material _m)
|
static void SetLook(Material _m)
|
||||||
{
|
{
|
||||||
if (_m == null)
|
if (_m == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
_m.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
|
||||||
|
_m.SetInt("_DstBlend", (int)(Solid ? UnityEngine.Rendering.BlendMode.Zero : UnityEngine.Rendering.BlendMode.One));
|
||||||
|
_m.SetInt("_ZWrite", Solid ? 1 : 0);
|
||||||
|
_m.SetOverrideTag("RenderType", Solid ? "Opaque" : "Transparent");
|
||||||
|
_m.renderQueue = (int)(Solid ? UnityEngine.Rendering.RenderQueue.Geometry : UnityEngine.Rendering.RenderQueue.Transparent);
|
||||||
|
if (Solid)
|
||||||
|
{
|
||||||
|
if (_m.HasProperty("_Color"))
|
||||||
|
{
|
||||||
|
_m.color = new Color(Tint.r, Tint.g, Tint.b, 1f);
|
||||||
|
}
|
||||||
|
if (_m.HasProperty("_EmissionColor"))
|
||||||
|
{
|
||||||
|
_m.SetColor("_EmissionColor", new Color(Tint.r * Glow * 0.5f, Tint.g * Glow * 0.5f, Tint.b * Glow * 0.5f, 1f));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (_m.HasProperty("_Color"))
|
if (_m.HasProperty("_Color"))
|
||||||
{
|
{
|
||||||
_m.color = new Color(Tint.r * Alpha, Tint.g * Alpha, Tint.b * Alpha, 1f);
|
_m.color = new Color(Tint.r * Alpha, Tint.g * Alpha, Tint.b * Alpha, 1f);
|
||||||
@@ -309,6 +331,7 @@ namespace NecromancerTome
|
|||||||
}
|
}
|
||||||
Debug.Log("[NecromancerTome] CinerariumGenie: кости рук " + sb);
|
Debug.Log("[NecromancerTome] CinerariumGenie: кости рук " + sb);
|
||||||
}
|
}
|
||||||
|
CloseFingers();
|
||||||
}
|
}
|
||||||
for (int i = 0; i < _arm.Length; i++)
|
for (int i = 0; i < _arm.Length; i++)
|
||||||
{
|
{
|
||||||
@@ -331,16 +354,71 @@ namespace NecromancerTome
|
|||||||
if (_cross > 0f)
|
if (_cross > 0f)
|
||||||
{
|
{
|
||||||
float cf = CinerariumGenie.CrossFwd * Mathf.Deg2Rad;
|
float cf = CinerariumGenie.CrossFwd * Mathf.Deg2Rad;
|
||||||
Vector3 crossUp = new Vector3(sign * 0.12f, -Mathf.Cos(cf), Mathf.Sin(cf)).normalized;
|
upDir = Vector3.Slerp(upDir, new Vector3(0f, -Mathf.Cos(cf), Mathf.Sin(cf)), _cross).normalized;
|
||||||
Vector3 crossFore = new Vector3(-sign * 0.85f, side == 0 ? CinerariumGenie.CrossLift : -CinerariumGenie.CrossLift, 0.45f).normalized;
|
|
||||||
upDir = Vector3.Slerp(upDir, crossUp, _cross);
|
|
||||||
foreDir = Vector3.Slerp(foreDir, crossFore, _cross);
|
|
||||||
}
|
}
|
||||||
up.rotation = Quaternion.FromToRotation(fore.position - up.position, transform.TransformDirection(upDir)) * up.rotation;
|
up.rotation = Quaternion.FromToRotation(fore.position - up.position, transform.TransformDirection(upDir)) * up.rotation;
|
||||||
|
Transform otherUp = _arm[(1 - side) * 3];
|
||||||
|
if (_cross > 0f && otherUp != null)
|
||||||
|
{
|
||||||
|
// Кисть - к плечу другой стороны (17.10: «Ладонь правой руки прижимается к левому плечу. Левая рука идёт
|
||||||
|
// поверх правой и прижимает ладонь к правому плечу»): цель - сустав другого плеча, вынесенный вперёд на
|
||||||
|
// толщину груди; левая (side 0) - ещё на CrossLift вперёд, поверх правой. Доли - от ширины плеч.
|
||||||
|
float width = Vector3.Distance(up.position, otherUp.position);
|
||||||
|
Vector3 target = otherUp.position + transform.forward * width * (CinerariumGenie.CrossDepth + (side == 0 ? CinerariumGenie.CrossLift : 0f));
|
||||||
|
Vector3 want = transform.InverseTransformDirection(target - fore.position).normalized;
|
||||||
|
foreDir = Vector3.Slerp(foreDir, want, _cross).normalized;
|
||||||
|
}
|
||||||
fore.rotation = Quaternion.FromToRotation(hand.position - fore.position, transform.TransformDirection(foreDir)) * fore.rotation;
|
fore.rotation = Quaternion.FromToRotation(hand.position - fore.position, transform.TransformDirection(foreDir)) * fore.rotation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Пальцы (17.10: «Пальцы можешь не растопыривать?»): в модели они веером. Указательный, безымянный и мизинец
|
||||||
|
/// поворачиваются к направлению среднего на долю FingersTogether, большой - на треть её. Пальцы - дети кисти, позы рук их
|
||||||
|
/// не трогают, поэтому ставятся один раз.</summary>
|
||||||
|
public static float FingersTogether = 0.85f;
|
||||||
|
|
||||||
|
void CloseFingers()
|
||||||
|
{
|
||||||
|
Transform[] all = GetComponentsInChildren<Transform>(true);
|
||||||
|
Dictionary<string, Transform> bones = new Dictionary<string, Transform>();
|
||||||
|
foreach (string side in new[] { "Left", "Right" })
|
||||||
|
{
|
||||||
|
foreach (string finger in new[] { "Index", "Middle", "Ring", "Pinky", "Thumb" })
|
||||||
|
{
|
||||||
|
for (int j = 1; j <= 2; j++)
|
||||||
|
{
|
||||||
|
string key = side + "Hand" + finger + j;
|
||||||
|
foreach (Transform t in all)
|
||||||
|
{
|
||||||
|
if (t.name.EndsWith(key))
|
||||||
|
{
|
||||||
|
bones[key] = t;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (string side in new[] { "Left", "Right" })
|
||||||
|
{
|
||||||
|
if (!bones.TryGetValue(side + "HandMiddle1", out Transform m1) || !bones.TryGetValue(side + "HandMiddle2", out Transform m2))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Vector3 mid = m2.position - m1.position;
|
||||||
|
foreach (string finger in new[] { "Index", "Ring", "Pinky", "Thumb" })
|
||||||
|
{
|
||||||
|
if (!bones.TryGetValue(side + "Hand" + finger + "1", out Transform f1) || !bones.TryGetValue(side + "Hand" + finger + "2", out Transform f2))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Vector3 cur = f2.position - f1.position;
|
||||||
|
float k = finger == "Thumb" ? FingersTogether / 3f : FingersTogether;
|
||||||
|
f1.rotation = Quaternion.FromToRotation(cur, Vector3.Slerp(cur, mid, k)) * f1.rotation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Светящиеся материалы рендереров - вернуть после почернения.</summary>
|
/// <summary>Светящиеся материалы рендереров - вернуть после почернения.</summary>
|
||||||
readonly Dictionary<Renderer, Material[]> _glowing = new Dictionary<Renderer, Material[]>();
|
readonly Dictionary<Renderer, Material[]> _glowing = new Dictionary<Renderer, Material[]>();
|
||||||
|
|
||||||
@@ -560,7 +638,8 @@ namespace NecromancerTome
|
|||||||
"necrogenie glow <0-1> - body's own glow (visible at night)\n" +
|
"necrogenie glow <0-1> - body's own glow (visible at night)\n" +
|
||||||
"necrogenie tint <r> <g> <b> - body colour\n" +
|
"necrogenie tint <r> <g> <b> - body colour\n" +
|
||||||
"necrogenie arms <out> <fwd> <elbow> - arm pose, degrees: upper arm from vertical sideways and forward, elbow bend\n" +
|
"necrogenie arms <out> <fwd> <elbow> - arm pose, degrees: upper arm from vertical sideways and forward, elbow bend\n" +
|
||||||
"necrogenie cross <0|1> [fwd] [lift] - arms crossed on the chest at rest (1) or hanging (0); upper arm forward, degrees; forearm height offset\n" +
|
"necrogenie cross <0|1> [fwd] [lift] [depth] - rest pose: hands on the opposite shoulders, left over right (1) or hanging (0); upper arm forward, degrees; left forearm over the right and chest depth, shares of shoulder width\n" +
|
||||||
|
"necrogenie solid <0|1> - TEMPORARY: opaque body (1) to see the pose, or the ghostly glow (0)\n" +
|
||||||
"necrogenie sleep <m> - spirits and threads freeze when the player is farther (work goes on)\n" +
|
"necrogenie sleep <m> - spirits and threads freeze when the player is farther (work goes on)\n" +
|
||||||
"necrogenie hide|show - hide all spirits (weak PCs, video), work goes on";
|
"necrogenie hide|show - hide all spirits (weak PCs, video), work goes on";
|
||||||
}
|
}
|
||||||
@@ -618,6 +697,10 @@ namespace NecromancerTome
|
|||||||
m.Pose();
|
m.Pose();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "solid":
|
||||||
|
CinerariumGenie.Solid = v != 0f;
|
||||||
|
CinerariumGenie.ApplyAlpha();
|
||||||
|
break;
|
||||||
case "cross":
|
case "cross":
|
||||||
CinerariumGenie.Cross = v != 0f;
|
CinerariumGenie.Cross = v != 0f;
|
||||||
if (_params.Count >= 3 && float.TryParse(_params[2], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out float cf))
|
if (_params.Count >= 3 && float.TryParse(_params[2], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out float cf))
|
||||||
@@ -628,6 +711,10 @@ namespace NecromancerTome
|
|||||||
{
|
{
|
||||||
CinerariumGenie.CrossLift = cl;
|
CinerariumGenie.CrossLift = cl;
|
||||||
}
|
}
|
||||||
|
if (_params.Count >= 5 && float.TryParse(_params[4], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out float cd))
|
||||||
|
{
|
||||||
|
CinerariumGenie.CrossDepth = cd;
|
||||||
|
}
|
||||||
foreach (CinerariumGenieMotion m in CinerariumGenie.Live)
|
foreach (CinerariumGenieMotion m in CinerariumGenie.Live)
|
||||||
{
|
{
|
||||||
m.Pose();
|
m.Pose();
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user