Firstborn/Assets/InfinityPBR/Editor/SFB_CharacterEquip.cs

122 lines
7.4 KiB
C#
Raw Normal View History

using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using UnityEngine;
using UnityEditorInternal;
using UnityEditor;
public class SFB_CharacterEquip : MonoBehaviour {
static GameObject target; // The target to match
private static string rootBoneName = "BoneRoot"; // Name of the root bone structure [IMPORTANT AND MAY BE DIFFERENT FOR YOUR MODEL!]
private static SkinnedMeshRenderer targetRenderer; // Renderer we are targetting
private static string subRootBoneName; // Bone name
private static GameObject thisBoneRoot; // Current bone root
[MenuItem("Window/Infinity PBR/Character Equip %#c")] // Provides a menu item & shortcut
static void EquipCharacter()
{
if (Selection.activeGameObject) // If there is an activeObject selected
{
Debug.Log("Starting Character Equip Workflow.");
Dictionary<string, Transform> boneMap; // Holds all the bones
boneMap = new Dictionary<string, Transform>(); // Create the new dictionary
target = Selection.activeGameObject; // Set the target to the selected object
// Make sure there is a proper root bone structure
bool isValidObject = false; // Assume false
foreach (Transform childCheck in target.transform) // For each child transform
{
if (childCheck.name == rootBoneName) // if this child name is the rootBoneName
{
isValidObject = true; // Make this a valid object
}
if (childCheck.GetComponent<SkinnedMeshRenderer>()) // If this has a skinnedMeshRenderer
{
targetRenderer = childCheck.GetComponent<SkinnedMeshRenderer>(); // Set targetRenderer
Debug.Log("Set Target Renderer: " + targetRenderer.name);
foreach (Transform bone in targetRenderer.bones) // For each bone...
{
boneMap[bone.name] = bone; // Add the bone to the dictionary
}
}
}
if (isValidObject) // If the object is proper, we will find and equip the valid attached equipment.
{
foreach (Transform child in target.transform) // For each child of the target
{
bool isEquipmentObject = false; // Assume it is not equipment
SkinnedMeshRenderer subChildRenderer = null; // Renderer of the subChild
foreach (Transform subChild in child.transform) // For each child of the child
{
if (subChild.name == rootBoneName) // If the subChild name is the rootBoneName
{
thisBoneRoot = subChild.gameObject; // This is the root
isEquipmentObject = true; // This is valid equipment
}
if (subChild.GetComponent<SkinnedMeshRenderer>()) // If the subChild has a skinnedMeshRenderer
{
// If the subChild has a SkinnedMeshRenderer, assign the renderer, bone name, and target;
Debug.Log("Name: " + subChild.gameObject.name);
subChildRenderer = subChild.gameObject.GetComponent<SkinnedMeshRenderer>();
Debug.Log("2: " + subChildRenderer.name);
subRootBoneName = subChildRenderer.rootBone.name;
Debug.Log("3: " + subRootBoneName);
targetRenderer = subChildRenderer;
}
}
if (isEquipmentObject && subChildRenderer) // If this is valid equipment and we have a subChildRenderer...
{
Debug.Log(child.name + " is valid equipment!");
Transform[] boneArray = subChildRenderer.bones; // Set the boneArray to be all the bones from the subChildRenderer
for (int i = 0; i < boneArray.Length; i++) // For each bone...
{
string boneName = boneArray[i].name; // Get the bone name
if (boneMap.ContainsKey(boneName)) // if the dictionary for the target bones contains this bone name...
{
boneArray[i] = boneMap[boneName]; // Set the array to match the bone from the Dictionary
}
}
subChildRenderer.bones = boneArray; // Assing the boneArray to the bones
foreach (Transform bone in targetRenderer.bones) // For each bone...
{
if (bone.name == subRootBoneName) // Is the bone name the same as subRootBoneName?
{
subChildRenderer.rootBone = bone; // Assign the root bone to this
}
}
PrefabUtility.UnpackPrefabInstance(child.gameObject,PrefabUnpackMode.Completely,InteractionMode.AutomatedAction);
DestroyImmediate(thisBoneRoot, true); // Destroy the bones of the subChildRenderer
}
}
/* NOTE: In a previous version I had a prefab created automatically. I'm removing this as (1) it's not really
* hard at all to create a prefab by draggin, (2) I think there's little point to making lots of prefabs with
* different versions, and (3) one less thing to support...coding isn't my strong suit! :D
*/
// Finally, we will remove "Dummy001" from the objects.
Transform[] allChildren = target.GetComponentsInChildren<Transform>(); // Get all children of the target
foreach (Transform child in allChildren) // And for each one...
{
if (child.gameObject.name == "Dummy001") // If the name is Dummy001
{
PrefabUtility.UnpackPrefabInstance(child.gameObject,PrefabUnpackMode.Completely,InteractionMode.AutomatedAction);
DestroyImmediate(child.gameObject); // Destroy it
}
}
}
Debug.Log("Character Equip Complete!!");
}
else
{
Debug.Log("No Object Selected!");
}
}
}