diff --git a/CHANGELOG.md b/CHANGELOG.md index fd95aaf..45fdb26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.1.0 + +- remove all PhysBones action + # 1.0.0 - remove PhysBone action diff --git a/Editor/DataStructure.cs b/Editor/DataStructure.cs index 99ca7bd..0d8e444 100644 --- a/Editor/DataStructure.cs +++ b/Editor/DataStructure.cs @@ -53,4 +53,8 @@ class RemovePhysBoneAction : Action { public string pathToGameObject; public int physBoneIndex; } + + class RemoveAllPhysBonesAction : Action { + public string pathToGameObject; + } } \ No newline at end of file diff --git a/Editor/Exceptions.cs b/Editor/Exceptions.cs index 1e918de..7b7362c 100644 --- a/Editor/Exceptions.cs +++ b/Editor/Exceptions.cs @@ -21,4 +21,10 @@ public FailedToRemovePhysBoneException(string message) : base(message) { public string pathToGameObject; public int physBoneIndex; } + + public class FailedToRemoveAllPhysBonesException : System.Exception { + public FailedToRemoveAllPhysBonesException(string message) : base(message) { + } + public string pathToGameObject; + } } \ No newline at end of file diff --git a/Editor/VRC_Questifyer.cs b/Editor/VRC_Questifyer.cs index f0824e9..60b6515 100644 --- a/Editor/VRC_Questifyer.cs +++ b/Editor/VRC_Questifyer.cs @@ -32,7 +32,8 @@ public class VRC_Questifyer : EditorWindow enum Types { SwitchToMaterial, RemoveGameObject, - RemovePhysBone + RemovePhysBone, + RemoveAllPhysBones } VRCAvatarDescriptor sourceVrcAvatarDescriptor; @@ -253,6 +254,8 @@ void RenderErrors() { message = message + "Failed to remove game object: " + exception.Message + "\nGame object: " + (exception as FailedToRemoveGameObjectException).pathToGameObject; } else if (exception is FailedToRemovePhysBoneException) { message = message + "Failed to remove PhysBone: " + exception.Message + "\nPhysBone game object: " + (exception as FailedToRemovePhysBoneException).pathToGameObject + " (index " + (exception as FailedToRemovePhysBoneException).physBoneIndex + ")"; + } else if (exception is FailedToRemoveAllPhysBonesException) { + message = message + "Failed to remove all PhysBones: " + exception.Message + "\nGame object: " + (exception as FailedToRemovePhysBoneException).pathToGameObject; } GUILayout.Label(message, guiStyle); @@ -373,6 +376,20 @@ void RenderCreateActionForm() { RenderPerformAtEndToggle(); RenderAddButton(selectedType, createFormFieldValue1 != ""); break; + + case Types.RemoveAllPhysBones: + GUILayout.Label("Path to game object:"); + createFormFieldValue1 = EditorGUILayout.TextField(createFormFieldValue1); + + gameObjectToUse = (GameObject)EditorGUILayout.ObjectField("Search:", gameObjectToUse, typeof(GameObject)); + + if (gameObjectToUse != null) { + createFormFieldValue1 = Utils.GetRelativeGameObjectPath(gameObjectToUse, sourceVrcAvatarDescriptor.gameObject); + } + + RenderPerformAtEndToggle(); + RenderAddButton(selectedType, createFormFieldValue1 != ""); + break; default: throw new System.Exception("Unknown type for dropdown!"); @@ -413,6 +430,12 @@ void AddAction(Types type, string fieldValue1, string fieldValue2, int fieldValu }; break; + case Types.RemoveAllPhysBones: + action = new RemoveAllPhysBonesAction() { + pathToGameObject = fieldValue1 + }; + break; + default: throw new System.Exception("Unknown type to add!"); break; @@ -480,6 +503,8 @@ void RenderTypeForAction(Action action) { label = "Remove Object"; } else if (action is RemovePhysBoneAction) { label = "Remove PhysBone"; + } else if (action is RemoveAllPhysBonesAction) { + label = "Remove All PhysBones"; } else { throw new System.Exception("Unknown action!"); } @@ -510,6 +535,9 @@ void RenderDataForAction(Action action) { string pathToGameObject = (action as RemovePhysBoneAction).pathToGameObject; string physBoneIndexStr = (action as RemovePhysBoneAction).physBoneIndex.ToString(); GUILayout.Label(pathToGameObject + " (" + physBoneIndexStr + ")", guiStyle); + } else if (action is RemoveAllPhysBonesAction) { + string pathToGameObject = (action as RemoveAllPhysBonesAction).pathToGameObject; + GUILayout.Label(pathToGameObject, guiStyle); } else { throw new System.Exception("Unknown action!"); } @@ -608,6 +636,13 @@ void PerformAction(Action action, GameObject avatar) { } catch (FailedToRemovePhysBoneException exception) { errors.Add(exception); } + } else if (action is RemoveAllPhysBonesAction) { + try { + string pathToGameObject = (action as RemoveAllPhysBonesAction).pathToGameObject; + RemoveAllPhysBonesOnGameObjectForAvatar(avatar, pathToGameObject); + } catch (FailedToRemovePhysBoneException exception) { + errors.Add(exception); + } } else { throw new System.Exception("Cannot perform action - unknown action type: " + nameof(action)); } @@ -653,6 +688,30 @@ void RemovePhysBoneForAvatar(GameObject avatar, string pathToGameObject, int phy DestroyImmediate(physBoneToRemove); } + void RemoveAllPhysBonesOnGameObjectForAvatar(GameObject avatar, string pathToGameObject) { + Debug.Log("Removing all physbones at " + pathToGameObject + "..."); + + Transform gameObjectTransform = Utils.FindChild(avatar.transform, pathToGameObject); + + if (gameObjectTransform == null) { + throw new FailedToRemoveAllPhysBonesException("Game object not found") { + pathToGameObject = pathToGameObject + }; + } + + VRCPhysBone[] physBones = gameObjectTransform.gameObject.GetComponents(); + + if (physBones.Length == 0) { + throw new FailedToRemoveAllPhysBonesException("No PhysBones found on the game object") { + pathToGameObject = pathToGameObject + }; + } + + foreach (VRCPhysBone physBone in physBones) { + DestroyImmediate(physBone); + } + } + void SwitchGameObjectMaterialForAvatar(GameObject avatar, string pathToRenderer, string pathToMaterial, int materialIndex = 0) { Transform rendererTransform = Utils.FindChild(avatar.transform, pathToRenderer); @@ -748,6 +807,13 @@ ActionJson ActionToJson(Action action) { physBoneIndex = (action as RemovePhysBoneAction).physBoneIndex.ToString() }) }; + } else if (action is RemoveAllPhysBonesAction) { + actionJson = new ActionJson() { + type = Types.RemoveAllPhysBones.ToString(), + data = JObject.FromObject(new { + pathToGameObject = (action as RemoveAllPhysBonesAction).pathToGameObject + }) + }; } else { throw new System.Exception("Cannot convert action to JSON: unknown type " + nameof(action)); } @@ -782,6 +848,11 @@ Action ActionJsonToAction(ActionJson actionJson) { physBoneIndex = (int)jsonObject["physBoneIndex"] }; break; + case Types.RemoveAllPhysBones: + action = new RemoveAllPhysBonesAction() { + pathToGameObject = (string)jsonObject["pathToGameObject"] + }; + break; default: throw new System.Exception("Cannot convert action JSON to action: unknown type " + actionJson.type); break;