void OnEnable() { var outfit = target as StandardOutfit; // Assume auto-detect has already been performed if the motion root is assigned // Want to be conservative. if (!Application.isPlaying && outfit && !StandardOutfit.IsMotionRootAssigned(outfit)) { StandardOutfitEditor.RefreshAllSettings(outfit); } m_IsAsset = AssetDatabase.Contains(target); m_ContextChoice = outfit.gameObject; }
public static bool SetOutfit(Body body, Outfit outfit, float repoOffset = 0, RemoveActionType removeType = RemoveActionType.Undefined, bool singleUndo = true, string undoLabel = "Set Outfit") { // Design note: It would be much simpler to just remove and add in separate transactions. But that // sends the wrong type of event to observers, so have to go the messy route in order to properly // mimic runtime behavior. // Validations if (!CheckValidAction(body)) { return(false); } if (outfit == body.Outfit) { Debug.LogWarning("No action taken. Outfit is the same as the body's current outfit: " + (outfit ? outfit.name : "null"), body); return(true); // This is the correct behavior. } if (outfit && outfit.IsManaged) { Debug.LogError("Can't set outfit. The outfit is already managed by: " + outfit.Owner.name, body); return(false); } // Keep last since it may involve a dialog box. Transform origParent = null; if (body.Outfit) { removeType = GetRemoveType(body, removeType); if (removeType == RemoveActionType.Cancel) { return(false); } origParent = body.Outfit.transform.parent; } // Prepare for transaction. if (singleUndo) { Undo.IncrementCurrentGroup(); } bool isNew = false; Transform outfitParent = null; if (outfit) { isNew = AssetDatabase.Contains(outfit); if (isNew) { var name = outfit.name; outfit = outfit.Instantiate(); outfit.name = name; // Will register the undo after success has been determined. } else { Undo.RecordObjects(Outfit.UnsafeGetUndoObjects(outfit).ToArray(), undoLabel); } outfitParent = outfit.transform.parent; } Undo.RecordObjects(Body.UnsafeGetUndoObjects(body).ToArray(), undoLabel); // Set the outfit. var orig = body.SetOutfit(outfit); var success = (orig != outfit); if (success) { if (orig) { // Finalize the original outfit. orig.transform.parent = origParent; Undo.SetTransformParent(orig.transform, null, undoLabel); if (removeType == RemoveActionType.RemoveAndDestroy) { orig.Destroy(DestroyType.GameObject, true); Undo.DestroyObjectImmediate(orig.gameObject); } else if (repoOffset > 0) { // This extra call is needed, otherwise only **part** of the translation is recorded. The // problem might be due to the change in the parent. Anyway, more fun with undo... Undo.RecordObject(orig.transform, undoLabel); orig.transform.position += body.transform.right * repoOffset; } } if (outfit) { // Finalize the outfit that was set. if (isNew) { Undo.RegisterCreatedObjectUndo(outfit.gameObject, undoLabel); } var parent = outfit.transform.parent; outfit.transform.parent = outfitParent; Undo.SetTransformParent(outfit.transform, parent, undoLabel); if (body is StandardBody) { // HACK: Addition of body as outfit observer is not being recorded for serialization. // This fixes it until the cause and proper fix can be determined. StandardOutfitEditor.AddObserverWithUndo(outfit, (StandardBody)body); } } success = true; } else { if (isNew) { outfit.gameObject.SafeDestroy(); } success = false; } if (singleUndo) { Undo.CollapseUndoOperations(Undo.GetCurrentGroup()); } return(success); }