using System.Collections; using System.Collections.Generic; using UnityEngine; namespace FiradzoAssets { /// /// This script automatically adds and removes weapon and shield, /// but works only while prefab opened for editing in prefab scene because of deleting prefab instance parts in scene is not allowed /// public class WeaponAttachmentHelper : MonoBehaviour { private const string ArmatureObjectName = "Armature"; private const string RightHandWeaponBoneName = "weapon_end"; private const string LeftHandShieldBone = "shield_end"; [SerializeField] private Transform armatureRoot; [Space(10f)] [SerializeField] private Transform rightHandWeaponBone; [SerializeField] private Transform leftHandShieldBone; [Space(10f)] [SerializeField] private GameObject rightHandWeaponPrefab; [SerializeField] private GameObject shieldPrefab; private void OnValidate() { var isDirty = false; if (armatureRoot == null) { armatureRoot = transform.Find(ArmatureObjectName); if (armatureRoot != null) { isDirty = true; } } if (armatureRoot != null) { if (rightHandWeaponBone == null) { rightHandWeaponBone = FindTransfomInChildRecursive(armatureRoot, RightHandWeaponBoneName); if (rightHandWeaponBone != null) { isDirty = true; } } if (leftHandShieldBone == null) { leftHandShieldBone = FindTransfomInChildRecursive(armatureRoot, LeftHandShieldBone); if (leftHandShieldBone != null) { isDirty = true; } } } #if UNITY_EDITOR if (isDirty) { UnityEditor.EditorUtility.SetDirty(this); } #endif } #if UNITY_EDITOR public void SetWeaponAndRebind(GameObject rightHandWeaponPrefab, GameObject shieldPrefab) { this.rightHandWeaponPrefab = rightHandWeaponPrefab; this.shieldPrefab = shieldPrefab; TryRefreshBindedItems(); } private bool isPerformingItemsRefreshing; public void TryRefreshBindedItems() { if (isPerformingItemsRefreshing) { return; } isPerformingItemsRefreshing = true; if (gameObject.scene.isLoaded && !UnityEditor.PrefabUtility.IsPartOfPrefabInstance(gameObject)) { TryRefreshBindedItem(rightHandWeaponBone, rightHandWeaponPrefab); TryRefreshBindedItem(leftHandShieldBone, shieldPrefab); } isPerformingItemsRefreshing = false; } private void TryRefreshBindedItem(Transform parent, GameObject itemPrefab) { if (parent != null) { if (itemPrefab == null) { if (parent.childCount > 0) { var childObject = parent.GetChild(0).gameObject; DestroyObject(childObject); } } else { if (parent.childCount > 0) { var childObject = parent.GetChild(0).gameObject; if (childObject.name != itemPrefab.name) { if (DestroyObject(childObject)) { InstantiateItem(parent, itemPrefab); } } } else { InstantiateItem(parent, itemPrefab); } } } } private bool DestroyObject(GameObject @object) { if (UnityEditor.PrefabUtility.IsPartOfPrefabInstance(@object.transform.parent)) { //Debug.LogFormat("Can't destroy item {0} in scene because it is part of prefab instance, open prefab for editing to do so", @object); return false; } GameObject.DestroyImmediate(@object); return true; } private void InstantiateItem(Transform parent, GameObject itemPrefab) { var itemInstance = GameObject.Instantiate(itemPrefab, parent); itemInstance.name = itemPrefab.name; itemInstance.transform.localPosition = Vector3.zero; itemInstance.transform.localRotation = Quaternion.identity; } #endif private Transform FindTransfomInChildRecursive(Transform transform, string transformName) { if (transform.name == transformName) { return transform; } var childCount = transform.childCount; if (transform.childCount > 0) { Transform result; for (int i = 0; i < childCount; i++) { result = FindTransfomInChildRecursive(transform.GetChild(i), transformName); if (result != null) { return result; } } } return null; } } }