107 lines
4.7 KiB
C#
107 lines
4.7 KiB
C#
using System.Collections.Generic;
|
|
using System.Text;
|
|
using UnityEngine;
|
|
using UnityEngine.Scripting;
|
|
|
|
namespace NecromancerTome
|
|
{
|
|
/// <summary>
|
|
/// necrobones - разведка к жестам (BACKLOG «Заклинания с руки и жесты», 1.6.0). Свой хват -
|
|
/// это неподвижная поза рук от первого лица, как у браслета (кулак к противнику, без движения
|
|
/// при действии): кости рига ставятся в нужную комбинацию после аниматора. Сначала надо знать
|
|
/// кости: команда пишет в лог дерево рига рук от первого лица (EModelSDCS.baseRigFP, его создаёт
|
|
/// SDCSUtils.CreateVizFP под Camera/UFPSRoot) с локальными поворотами и позициями, и параметры
|
|
/// аниматора FPPlayerController (WeaponHoldType и прочие) с текущими значениями.
|
|
/// </summary>
|
|
[Preserve]
|
|
public class ConsoleCmdNecroBones : ConsoleCmdAbstract
|
|
{
|
|
const string Tag = "[NecromancerTome] necrobones: ";
|
|
|
|
public override string[] getCommands() => new[] { "necrobones" };
|
|
public override string getDescription() => "NecromancerTome: дерево костей рук от первого лица и параметры аниматора - в лог";
|
|
|
|
public override void Execute(List<string> _params, CommandSenderInfo _senderInfo)
|
|
{
|
|
EntityPlayerLocal player = GameManager.Instance.World?.GetPrimaryPlayer();
|
|
if (player == null)
|
|
{
|
|
return;
|
|
}
|
|
if (!(player.emodel is EModelSDCS sdcs) || sdcs.baseRigFP == null)
|
|
{
|
|
SdtdConsole.Instance.Output("риг рук от первого лица не найден (EModelSDCS.baseRigFP)");
|
|
return;
|
|
}
|
|
Transform root = sdcs.baseRigFP.transform;
|
|
ItemClass held = player.inventory?.holdingItem;
|
|
Debug.Log(Tag + "в руке " + (held != null ? held.GetItemName() + ", HoldType " + held.HoldType.Value : "ничего") + ", вид от первого лица " + sdcs.IsFPV);
|
|
Debug.Log(Tag + "путь рига: " + PathOf(root));
|
|
int count = 0;
|
|
var sb = new StringBuilder();
|
|
Dump(root, 0, sb, ref count);
|
|
foreach (string line in sb.ToString().Split('\n'))
|
|
{
|
|
if (line.Length > 0)
|
|
{
|
|
Debug.Log(Tag + line);
|
|
}
|
|
}
|
|
Animator anim = root.GetComponentInChildren<Animator>(true) ?? root.GetComponentInParent<Animator>();
|
|
if (anim != null)
|
|
{
|
|
Debug.Log(Tag + "аниматор на " + anim.name + ", контроллер " + (anim.runtimeAnimatorController != null ? anim.runtimeAnimatorController.name : "нет"));
|
|
foreach (AnimatorControllerParameter p in anim.parameters)
|
|
{
|
|
string v = p.type == AnimatorControllerParameterType.Float ? anim.GetFloat(p.nameHash).ToString("0.###")
|
|
: p.type == AnimatorControllerParameterType.Int ? anim.GetInteger(p.nameHash).ToString()
|
|
: p.type == AnimatorControllerParameterType.Bool ? anim.GetBool(p.nameHash).ToString()
|
|
: "trigger";
|
|
Debug.Log(Tag + " параметр " + p.name + " (" + p.type + ") = " + v);
|
|
}
|
|
for (int l = 0; l < anim.layerCount; l++)
|
|
{
|
|
AnimatorClipInfo[] clips = anim.GetCurrentAnimatorClipInfo(l);
|
|
string names = "";
|
|
foreach (AnimatorClipInfo c in clips)
|
|
{
|
|
names += (names.Length > 0 ? ", " : "") + (c.clip != null ? c.clip.name : "?") + " x" + c.weight.ToString("0.##");
|
|
}
|
|
Debug.Log(Tag + " слой " + l + " " + anim.GetLayerName(l) + " вес " + anim.GetLayerWeight(l).ToString("0.##") + ": " + names);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Debug.Log(Tag + "аниматор не найден");
|
|
}
|
|
SdtdConsole.Instance.Output("костей рук: " + count + " - дерево и параметры аниматора в логе (строки necrobones)");
|
|
}
|
|
|
|
static void Dump(Transform _t, int _depth, StringBuilder _sb, ref int _count)
|
|
{
|
|
_count++;
|
|
Vector3 e = _t.localEulerAngles;
|
|
Vector3 p = _t.localPosition;
|
|
_sb.Append(new string(' ', _depth * 2)).Append(_t.name)
|
|
.Append(_t.gameObject.activeSelf ? "" : " [выкл]")
|
|
.Append(" пов. ").Append(e.x.ToString("0.#")).Append(' ').Append(e.y.ToString("0.#")).Append(' ').Append(e.z.ToString("0.#"))
|
|
.Append(" поз. ").Append(p.x.ToString("0.###")).Append(' ').Append(p.y.ToString("0.###")).Append(' ').Append(p.z.ToString("0.###"))
|
|
.Append('\n');
|
|
for (int i = 0; i < _t.childCount; i++)
|
|
{
|
|
Dump(_t.GetChild(i), _depth + 1, _sb, ref _count);
|
|
}
|
|
}
|
|
|
|
static string PathOf(Transform _t)
|
|
{
|
|
string s = _t.name;
|
|
for (Transform p = _t.parent; p != null; p = p.parent)
|
|
{
|
|
s = p.name + "/" + s;
|
|
}
|
|
return s;
|
|
}
|
|
}
|
|
}
|