WeaponAttachmentHelper.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace FiradzoAssets
  5. {
  6. /// <summary>
  7. /// This script automatically adds and removes weapon and shield,
  8. /// but works only while prefab opened for editing in prefab scene because of deleting prefab instance parts in scene is not allowed
  9. /// </summary>
  10. public class WeaponAttachmentHelper : MonoBehaviour
  11. {
  12. private const string ArmatureObjectName = "Armature";
  13. private const string RightHandWeaponBoneName = "weapon_end";
  14. private const string LeftHandShieldBone = "shield_end";
  15. [SerializeField]
  16. private Transform armatureRoot;
  17. [Space(10f)]
  18. [SerializeField]
  19. private Transform rightHandWeaponBone;
  20. [SerializeField]
  21. private Transform leftHandShieldBone;
  22. [Space(10f)]
  23. [SerializeField]
  24. private GameObject rightHandWeaponPrefab;
  25. [SerializeField]
  26. private GameObject shieldPrefab;
  27. private void OnValidate()
  28. {
  29. var isDirty = false;
  30. if (armatureRoot == null)
  31. {
  32. armatureRoot = transform.Find(ArmatureObjectName);
  33. if (armatureRoot != null)
  34. {
  35. isDirty = true;
  36. }
  37. }
  38. if (armatureRoot != null)
  39. {
  40. if (rightHandWeaponBone == null)
  41. {
  42. rightHandWeaponBone = FindTransfomInChildRecursive(armatureRoot, RightHandWeaponBoneName);
  43. if (rightHandWeaponBone != null)
  44. {
  45. isDirty = true;
  46. }
  47. }
  48. if (leftHandShieldBone == null)
  49. {
  50. leftHandShieldBone = FindTransfomInChildRecursive(armatureRoot, LeftHandShieldBone);
  51. if (leftHandShieldBone != null)
  52. {
  53. isDirty = true;
  54. }
  55. }
  56. }
  57. #if UNITY_EDITOR
  58. if (isDirty)
  59. {
  60. UnityEditor.EditorUtility.SetDirty(this);
  61. }
  62. #endif
  63. }
  64. #if UNITY_EDITOR
  65. public void SetWeaponAndRebind(GameObject rightHandWeaponPrefab, GameObject shieldPrefab)
  66. {
  67. this.rightHandWeaponPrefab = rightHandWeaponPrefab;
  68. this.shieldPrefab = shieldPrefab;
  69. TryRefreshBindedItems();
  70. }
  71. private bool isPerformingItemsRefreshing;
  72. public void TryRefreshBindedItems()
  73. {
  74. if (isPerformingItemsRefreshing)
  75. {
  76. return;
  77. }
  78. isPerformingItemsRefreshing = true;
  79. if (gameObject.scene.isLoaded && !UnityEditor.PrefabUtility.IsPartOfPrefabInstance(gameObject))
  80. {
  81. TryRefreshBindedItem(rightHandWeaponBone, rightHandWeaponPrefab);
  82. TryRefreshBindedItem(leftHandShieldBone, shieldPrefab);
  83. }
  84. isPerformingItemsRefreshing = false;
  85. }
  86. private void TryRefreshBindedItem(Transform parent, GameObject itemPrefab)
  87. {
  88. if (parent != null)
  89. {
  90. if (itemPrefab == null)
  91. {
  92. if (parent.childCount > 0)
  93. {
  94. var childObject = parent.GetChild(0).gameObject;
  95. DestroyObject(childObject);
  96. }
  97. }
  98. else
  99. {
  100. if (parent.childCount > 0)
  101. {
  102. var childObject = parent.GetChild(0).gameObject;
  103. if (childObject.name != itemPrefab.name)
  104. {
  105. if (DestroyObject(childObject))
  106. {
  107. InstantiateItem(parent, itemPrefab);
  108. }
  109. }
  110. }
  111. else
  112. {
  113. InstantiateItem(parent, itemPrefab);
  114. }
  115. }
  116. }
  117. }
  118. private bool DestroyObject(GameObject @object)
  119. {
  120. if (UnityEditor.PrefabUtility.IsPartOfPrefabInstance(@object.transform.parent))
  121. {
  122. //Debug.LogFormat("Can't destroy item <b>{0}</b> in scene because it is part of prefab instance, open prefab for editing to do so", @object);
  123. return false;
  124. }
  125. GameObject.DestroyImmediate(@object);
  126. return true;
  127. }
  128. private void InstantiateItem(Transform parent, GameObject itemPrefab)
  129. {
  130. var itemInstance = GameObject.Instantiate(itemPrefab, parent);
  131. itemInstance.name = itemPrefab.name;
  132. itemInstance.transform.localPosition = Vector3.zero;
  133. itemInstance.transform.localRotation = Quaternion.identity;
  134. }
  135. #endif
  136. private Transform FindTransfomInChildRecursive(Transform transform, string transformName)
  137. {
  138. if (transform.name == transformName)
  139. {
  140. return transform;
  141. }
  142. var childCount = transform.childCount;
  143. if (transform.childCount > 0)
  144. {
  145. Transform result;
  146. for (int i = 0; i < childCount; i++)
  147. {
  148. result = FindTransfomInChildRecursive(transform.GetChild(i), transformName);
  149. if (result != null)
  150. {
  151. return result;
  152. }
  153. }
  154. }
  155. return null;
  156. }
  157. }
  158. }