Руки одержимого: аниматор включается; necroarms anim|mat|set|trigger|tint для подбора в игре
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
cfcd9d33a5
commit
0c42714416
+161
-3
@@ -33,7 +33,9 @@ namespace NecromancerTome
|
||||
"zombieUtilityWorker", "zombieYo",
|
||||
};
|
||||
|
||||
public static readonly Color Tint = new Color(0.55f, 0.56f, 0.55f, 1f);
|
||||
public static Color Tint = new Color(0.55f, 0.56f, 0.55f, 1f);
|
||||
/// <summary>Параметры аниматора рук, выставленные necroarms set (подбор «пустых рук»), - ставятся и при пересборке.</summary>
|
||||
static readonly Dictionary<string, float> _animParams = new Dictionary<string, float>();
|
||||
/// <summary>Сдвиг рук от камеры (подбор necroarms pos). У персонажа игра опускает руки на 1.7 м: начало их
|
||||
/// скелета - у ног (vp_FPWeapon PositionOffset 0,-1.7,0.02 для SDCS).</summary>
|
||||
public static Vector3 Offset = new Vector3(0f, -1.7f, 0.02f);
|
||||
@@ -127,7 +129,19 @@ namespace NecromancerTome
|
||||
}
|
||||
// Префаб рук выключен: у персонажа его включает BodyAnimator (State = Visible) - тест 13.10: «активны False».
|
||||
_rig.SetActive(true);
|
||||
Debug.Log("[NecromancerTome] FpArms: снято скриптов " + stripped);
|
||||
// Аниматор у персонажа включает тот же BodyAnimator (тест 13.10: «рука одна и без анимации»).
|
||||
Animator anim = _rig.GetComponent<Animator>();
|
||||
if (anim != null)
|
||||
{
|
||||
anim.enabled = true;
|
||||
anim.cullingMode = AnimatorCullingMode.AlwaysAnimate;
|
||||
anim.Rebind();
|
||||
foreach (KeyValuePair<string, float> kv in _animParams)
|
||||
{
|
||||
SetParam(anim, kv.Key, kv.Value);
|
||||
}
|
||||
}
|
||||
Debug.Log("[NecromancerTome] FpArms: снято скриптов " + stripped + ", аниматор " + (anim != null ? anim.runtimeAnimatorController?.name : "нет"));
|
||||
_rig.name = "necroZombieArmsFP";
|
||||
int layer = LayerMask.NameToLayer("HoldingItem");
|
||||
int tinted = 0;
|
||||
@@ -188,6 +202,122 @@ namespace NecromancerTome
|
||||
return s;
|
||||
}
|
||||
|
||||
static Animator Anim => _rig != null ? _rig.GetComponent<Animator>() : null;
|
||||
|
||||
static bool SetParam(Animator _a, string _name, float _v)
|
||||
{
|
||||
foreach (AnimatorControllerParameter p in _a.parameters)
|
||||
{
|
||||
if (p.name != _name)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
switch (p.type)
|
||||
{
|
||||
case AnimatorControllerParameterType.Float: _a.SetFloat(_name, _v); break;
|
||||
case AnimatorControllerParameterType.Int: _a.SetInteger(_name, (int)_v); break;
|
||||
case AnimatorControllerParameterType.Bool: _a.SetBool(_name, _v != 0f); break;
|
||||
default: _a.SetTrigger(_name); break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>necroarms set: параметр аниматора (запоминается для пересборки; у триггера - только срабатывание).</summary>
|
||||
public static string Set(string _name, float _v)
|
||||
{
|
||||
Animator a = Anim;
|
||||
if (a == null)
|
||||
{
|
||||
return "рук нет";
|
||||
}
|
||||
if (!SetParam(a, _name, _v))
|
||||
{
|
||||
return "нет параметра " + _name;
|
||||
}
|
||||
_animParams[_name] = _v;
|
||||
return _name + " = " + _v.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public static string Trigger(string _name)
|
||||
{
|
||||
Animator a = Anim;
|
||||
if (a == null)
|
||||
{
|
||||
return "рук нет";
|
||||
}
|
||||
a.SetTrigger(_name);
|
||||
return "триггер " + _name;
|
||||
}
|
||||
|
||||
/// <summary>Аниматор рук: вкл, контроллер, текущие клипы по слоям и все параметры со значениями.</summary>
|
||||
public static string DumpAnim()
|
||||
{
|
||||
Animator a = Anim;
|
||||
if (a == null)
|
||||
{
|
||||
return "рук нет";
|
||||
}
|
||||
string s = "аниматор вкл " + a.enabled + ", контроллер " + a.runtimeAnimatorController?.name + ", слоёв " + a.layerCount;
|
||||
for (int l = 0; l < a.layerCount; l++)
|
||||
{
|
||||
string clips = "";
|
||||
foreach (AnimatorClipInfo ci in a.GetCurrentAnimatorClipInfo(l))
|
||||
{
|
||||
clips += " " + ci.clip?.name + "(" + ci.weight.ToString("F2") + ")";
|
||||
}
|
||||
s += "\n слой " + l + " " + a.GetLayerName(l) + " вес " + a.GetLayerWeight(l).ToString("F2") + ":" + clips;
|
||||
}
|
||||
foreach (AnimatorControllerParameter p in a.parameters)
|
||||
{
|
||||
string v = p.type == AnimatorControllerParameterType.Float ? a.GetFloat(p.name).ToString("F2", CultureInfo.InvariantCulture)
|
||||
: p.type == AnimatorControllerParameterType.Int ? a.GetInteger(p.name).ToString()
|
||||
: p.type == AnimatorControllerParameterType.Bool ? a.GetBool(p.name).ToString() : "trigger";
|
||||
s += "\n " + p.name + " = " + v;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/// <summary>Материалы рук: шейдер и его цветовые/текстурные свойства (подбор серого).</summary>
|
||||
public static string DumpMat()
|
||||
{
|
||||
if (_rig == null)
|
||||
{
|
||||
return "рук нет";
|
||||
}
|
||||
string s = "";
|
||||
foreach (SkinnedMeshRenderer smr in _rig.GetComponentsInChildren<SkinnedMeshRenderer>(true))
|
||||
{
|
||||
foreach (Material m in smr.sharedMaterials)
|
||||
{
|
||||
if (m == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
s += "\n " + smr.name + " / " + m.name + " / " + m.shader.name + ":";
|
||||
for (int i = 0; i < m.shader.GetPropertyCount(); i++)
|
||||
{
|
||||
UnityEngine.Rendering.ShaderPropertyType t = m.shader.GetPropertyType(i);
|
||||
string n = m.shader.GetPropertyName(i);
|
||||
if (t == UnityEngine.Rendering.ShaderPropertyType.Color)
|
||||
{
|
||||
s += " " + n + "=" + m.GetColor(n);
|
||||
}
|
||||
else if (t == UnityEngine.Rendering.ShaderPropertyType.Texture)
|
||||
{
|
||||
s += " " + n + "[" + (m.GetTexture(n) != null ? m.GetTexture(n).name : "-") + "]";
|
||||
}
|
||||
else
|
||||
{
|
||||
s += " " + n + "=" + m.GetFloat(n).ToString("F2", CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/// <summary>Пересобрать руки на месте (после necroarms pos/parent).</summary>
|
||||
public static void Rebuild()
|
||||
{
|
||||
@@ -226,7 +356,7 @@ namespace NecromancerTome
|
||||
public class ConsoleCmdNecroArms : ConsoleCmdAbstract
|
||||
{
|
||||
public override string[] getCommands() => new[] { "necroarms" };
|
||||
public override string getDescription() => "NecromancerTome: руки одержимого от первого лица - [pos x y z | parent cam|ufps]";
|
||||
public override string getDescription() => "NecromancerTome: руки одержимого от первого лица - [pos x y z | parent cam|ufps | anim | mat | set <param> <value> | trigger <name> | tint r g b]";
|
||||
|
||||
void Out(string _s)
|
||||
{
|
||||
@@ -250,6 +380,34 @@ namespace NecromancerTome
|
||||
FpArms.ParentCamera = _params[1] != "ufps";
|
||||
FpArms.Rebuild();
|
||||
}
|
||||
else if (cmd == "anim")
|
||||
{
|
||||
Out(FpArms.DumpAnim());
|
||||
return;
|
||||
}
|
||||
else if (cmd == "mat")
|
||||
{
|
||||
Out(FpArms.DumpMat());
|
||||
return;
|
||||
}
|
||||
else if (cmd == "set" && _params.Count >= 3 && float.TryParse(_params[2].Replace(',', '.'), NumberStyles.Float, CultureInfo.InvariantCulture, out float v))
|
||||
{
|
||||
Out(FpArms.Set(_params[1], v));
|
||||
return;
|
||||
}
|
||||
else if (cmd == "trigger" && _params.Count >= 2)
|
||||
{
|
||||
Out(FpArms.Trigger(_params[1]));
|
||||
return;
|
||||
}
|
||||
else if (cmd == "tint" && _params.Count >= 4 &&
|
||||
float.TryParse(_params[1].Replace(',', '.'), NumberStyles.Float, CultureInfo.InvariantCulture, out float r) &&
|
||||
float.TryParse(_params[2].Replace(',', '.'), NumberStyles.Float, CultureInfo.InvariantCulture, out float g) &&
|
||||
float.TryParse(_params[3].Replace(',', '.'), NumberStyles.Float, CultureInfo.InvariantCulture, out float b))
|
||||
{
|
||||
FpArms.Tint = new Color(r, g, b, 1f);
|
||||
FpArms.Rebuild();
|
||||
}
|
||||
Out(FpArms.Dump());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user