示例#1
0
        public static bool ReleaseAccessory(Outfit outfit, Accessory accessory, float offsetDistance = 0,
                                            RemoveActionType removeType = RemoveActionType.Undefined, bool singleUndo = true, string undoLabel = null)
        {
            if (AssetDatabase.Contains(outfit))
            {
                Debug.LogError("Can't modify an outfit asset.  Outfit must be in the scene.", outfit);
                return(false);
            }

            if (removeType == RemoveActionType.Undefined)
            {
                removeType = (RemoveActionType)EditorUtility.DisplayDialogComplex("Remove accessory from body?",
                                                                                  string.Format("Remove '{0}' from '{1}'?", accessory.name, outfit.name),
                                                                                  "Remove only", "Remove and destroy", "Do not remove");
            }

            if (removeType == RemoveActionType.Cancel)
            {
                return(false);
            }

            undoLabel = string.IsNullOrEmpty(undoLabel) ? "Remove Accessory" : undoLabel;
            if (singleUndo)
            {
                Undo.IncrementCurrentGroup();
            }

            Undo.RecordObjects(Outfit.UnsafeGetUndoObjects(outfit).ToArray(), undoLabel);

            var parent = accessory.transform.parent;

            outfit.Release(accessory);

            accessory.transform.parent = parent;
            Undo.SetTransformParent(accessory.transform, null, undoLabel);

            if (removeType == RemoveActionType.RemoveAndDestroy)
            {
                accessory.Destroy(DestroyType.GameObject, true);
                Undo.DestroyObjectImmediate(accessory.gameObject);
            }
            else if (offsetDistance > 0)
            {
                // This extra record call is needed for some reason.  Otherwise only **part** of the translation
                // is recorded.  Maybe the problem has to do with the unpartenting?  Anyway, more fun with undo...
                Undo.RecordObject(accessory.transform, undoLabel);
                accessory.transform.position += outfit.transform.right * -offsetDistance;
            }

            if (singleUndo)
            {
                Undo.CollapseUndoOperations(Undo.GetCurrentGroup());
            }

            return(true);
        }
示例#2
0
        private static RemoveActionType GetRemoveType(Body body, RemoveActionType removeType)
        {
            if (removeType == RemoveActionType.Undefined)
            {
                return((RemoveActionType)EditorUtility.DisplayDialogComplex("Remove the outfit from its body?",
                                                                            string.Format("Remove '{0}' from '{1}'?", body.Outfit.name, body.name),
                                                                            "Remove only", "Remove and destroy", "Do not remove"));
            }

            return(removeType);
        }
示例#3
0
        private void DrawOutfitApplyRemove()
        {
            var body = Target;

            GUIContent       label;
            bool             isApplyMode;
            RemoveActionType removeType = RemoveActionType.Undefined;
            var btnStyle = GUI.skin.button;

            if (body.Outfit)
            {
                m_OutfitApplyRemoveChoice = body.Outfit;
                isApplyMode = false;
                label       = new GUIContent("Remove", "Remove the outfit from the body.");

                if (OutfitterEditorUtil.IsNonDestructiveConfirmed)
                {
                    btnStyle   = LizEditorGUIUtil.YellowButton;
                    removeType = RemoveActionType.RemoveOnly;
                }
                else if (OutfitterEditorUtil.IsDestructiveConfirmed)
                {
                    btnStyle   = LizEditorGUIUtil.RedButton;
                    removeType = RemoveActionType.RemoveAndDestroy;
                }
            }
            else
            {
                isApplyMode = true;
                label       = new GUIContent("Apply", "Apply the outfit to the body.");

                if (m_OutfitApplyRemoveChoice && m_OutfitApplyRemoveChoice.Owner)
                {
                    label.tooltip += " (Current outfit owner: " + m_OutfitApplyRemoveChoice.Owner.name + ")";
                    btnStyle       = LizEditorGUIUtil.YellowButton;
                }
            }

            EditorGUILayout.BeginHorizontal();

            GUI.enabled = isApplyMode;

            var noutfit = EditorGUILayout.ObjectField(
                m_OutfitApplyRemoveChoice, typeof(Outfit), true, GUILayout.ExpandWidth(true)) as Outfit;

            if (noutfit != m_OutfitApplyRemoveChoice)
            {
                // Can only happen in apply mode.
                if (noutfit && noutfit.IsManaged)
                {
                    // Undo will become too complex if this is allowed.
                    Debug.LogErrorFormat(body,
                                         "Can't take control of an outfit that is already managed by another object."
                                         + " Outfit: {0}, Owner: {1}", noutfit.name, noutfit.Owner.name);
                }
                else
                {
                    m_OutfitApplyRemoveChoice = noutfit;
                }
            }

            GUI.enabled = m_OutfitApplyRemoveChoice;
            if (GUILayout.Button(label, btnStyle, GUILayout.MaxWidth(70)))
            {
                if (isApplyMode)
                {
                    SetOutfit(body, m_OutfitApplyRemoveChoice, OutfitterEditorUtil.AutoOffset, removeType);
                }
                else
                {
                    SetOutfit(body, null, OutfitterEditorUtil.AutoOffset, removeType);
                }
            }
            GUI.enabled = true;

            EditorGUILayout.EndHorizontal();
        }
示例#4
0
        private void DrawOutfitSwap()
        {
            var body = Target;

            if (!body.Outfit)
            {
                // Nothing to do.
                m_OutfitSwapChoice = null;
                return;
            }

            EditorGUILayout.BeginHorizontal();

            var noutfit = EditorGUILayout.ObjectField(
                m_OutfitSwapChoice, typeof(Outfit), true, GUILayout.ExpandWidth(true)) as Outfit;

            if (noutfit != m_OutfitSwapChoice)
            {
                if (noutfit == body.Outfit)
                {
                    Debug.LogWarning("Outfit is already assigned to the body: " + noutfit.name, body);
                }
                else if (noutfit && noutfit.IsManaged)
                {
                    // Undo will become too complex if this is allowed.
                    Debug.LogErrorFormat(body,
                                         "Can't take control of an outfit that is already managed by another object."
                                         + " Outfit: {0}, Owner: {1}", noutfit.name, noutfit.Owner.name);
                }
                else
                {
                    m_OutfitSwapChoice = noutfit;
                }
            }

            RemoveActionType removeType = RemoveActionType.Undefined;
            var btnStyle = GUI.skin.button;

            if (OutfitterEditorUtil.IsNonDestructiveConfirmed)
            {
                btnStyle   = LizEditorGUIUtil.YellowButton;
                removeType = RemoveActionType.RemoveOnly;
            }
            else if (OutfitterEditorUtil.IsDestructiveConfirmed)
            {
                btnStyle   = LizEditorGUIUtil.RedButton;
                removeType = RemoveActionType.RemoveAndDestroy;
            }

            GUI.enabled = m_OutfitSwapChoice;
            if (GUILayout.Button(m_SwapLabel, btnStyle, GUILayout.MaxWidth(70)))
            {
                if (SetOutfit(body, m_OutfitSwapChoice, OutfitterEditorUtil.AutoOffset, removeType, false))
                {
                    var item = m_OutfitSwapChoice;
                    m_OutfitSwapChoice        = m_OutfitApplyRemoveChoice ? m_OutfitApplyRemoveChoice : null;
                    m_OutfitApplyRemoveChoice = item;
                }
                // else there should have been an error message for the body.
            }
            GUI.enabled = true;

            EditorGUILayout.EndHorizontal();
        }
示例#5
0
        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);
        }