ByNameHumanoidAvatarMapper.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. using System.Collections.Generic;
  2. using TriLibCore.General;
  3. using TriLibCore.Extensions;
  4. using UnityEngine;
  5. using HumanLimit = TriLibCore.General.HumanLimit;
  6. namespace TriLibCore.Mappers
  7. {
  8. /// <summary>Represents a Mapper that finds humanoid Avatar bones by name-matching.</summary>
  9. [CreateAssetMenu(menuName = "TriLib/Mappers/Humanoid/By Name Humanoid Avatar Mapper", fileName = "ByNameHumanoidAvatarMapper")]
  10. public class ByNameHumanoidAvatarMapper : HumanoidAvatarMapper
  11. {
  12. /// <summary>
  13. /// String comparison mode to use on the mapping.
  14. /// </summary>
  15. [Header("Left = Loaded GameObjects Names, Right = Names in BonesMapping.BoneNames")]
  16. public StringComparisonMode stringComparisonMode;
  17. /// <summary>
  18. /// Is the string comparison case insensitive?
  19. /// </summary>
  20. public bool CaseInsensitive = true;
  21. /// <summary>
  22. /// The human bone to Unity bone relationship list.
  23. /// </summary>
  24. public List<BoneMapping> BonesMapping;
  25. /// <inheritdoc />
  26. public override Dictionary<BoneMapping, Transform> Map(AssetLoaderContext assetLoaderContext)
  27. {
  28. var mapping = new Dictionary<BoneMapping, Transform>();
  29. for (var i = 0; i < BonesMapping.Count; i++)
  30. {
  31. var boneMapping = BonesMapping[i];
  32. if (boneMapping.BoneNames != null)
  33. {
  34. var found = false;
  35. for (var j = 0; j < boneMapping.BoneNames.Length; j++)
  36. {
  37. var boneName = boneMapping.BoneNames[j];
  38. var transform = assetLoaderContext.RootGameObject.transform.FindDeepChild(boneName, stringComparisonMode, CaseInsensitive);
  39. if (transform == null)
  40. {
  41. continue;
  42. }
  43. var model = assetLoaderContext.Models[transform.gameObject];
  44. if (!model.IsBone)
  45. {
  46. continue;
  47. }
  48. mapping.Add(boneMapping, transform);
  49. found = true;
  50. break;
  51. }
  52. if (!found && !IsBoneOptional(boneMapping.HumanBone))
  53. {
  54. if (assetLoaderContext.Options.ShowLoadingWarnings)
  55. {
  56. Debug.LogWarning($"Could not find bone '{boneMapping.HumanBone}'");
  57. }
  58. mapping.Clear();
  59. return mapping;
  60. }
  61. }
  62. }
  63. return mapping;
  64. }
  65. private static bool IsBoneOptional(HumanBodyBones humanBodyBones)
  66. {
  67. return !HumanTrait.RequiredBone((int)humanBodyBones);
  68. }
  69. /// <summary>Adds a new mapping item, containing the humanoid bone type, the limits, and the list of names to look for to the query.</summary>
  70. /// <param name="humanBodyBones">The Human Body Bones (Humanoid Bone type).</param>
  71. /// <param name="humanLimit">The bone Human Limit.</param>
  72. /// <param name="boneNames">The bones Transform names.</param>
  73. public void AddMapping(HumanBodyBones humanBodyBones, HumanLimit humanLimit, params string[] boneNames)
  74. {
  75. if (BonesMapping == null)
  76. {
  77. BonesMapping = new List<BoneMapping>();
  78. }
  79. BonesMapping.Add(new BoneMapping(humanBodyBones, humanLimit, boneNames));
  80. }
  81. }
  82. }