Search Unity

Saving prefab after ContextMenu change

Discussion in 'Prefabs' started by xKosta, Dec 17, 2018.

  1. xKosta

    xKosta

    Joined:
    Oct 15, 2014
    Posts:
    22
    Hello,

    I just started using the new prefab workflow and i noticed, if i change a prefab over a ContextMenu command, the following change appears correctly in the hierarchy and inspector, but after leaving the prefab view. It get's lost.

    Project sceanrio:
    In open prefab view, a context menu reads the transform and saves the values into a struct that is marked as Serializable. Hierarchy and inspector shows value. Leaving the prefab view and open it again shows the old values.

    Auto save is enabled.
    It only saves the changes that are made by hand.

    Am i doing something wrong?
     
  2. SteenLund

    SteenLund

    Unity Technologies

    Joined:
    Jan 20, 2011
    Posts:
    456
    Please share your script.

    But it does sound like you are not marking the Prefab Mode scene dirty.
    There are different ways to fix this.

    1: Use SerializedObject and SerializedProperty to make your modifications https://docs.unity3d.com/ScriptReference/SerializedObject.html
    This gives marks your scene dirty, handles undo and handles nested prefabs.

    2: Manually implement Undo. Doing this will give you undo and mark the scene dirty.

    3: Mark the scene dirty yourself. https://docs.unity3d.com/ScriptReference/SceneManagement.EditorSceneManager.MarkSceneDirty.html

    EditorSceneManager.MarkSceneDirty(gameObject.scene);
     
    metinevren likes this.
  3. xKosta

    xKosta

    Joined:
    Oct 15, 2014
    Posts:
    22
    The problem is, i am not using a custom inspector or any kind of editor extension, it is only the context menu. Here the link to docs.
    https://docs.unity3d.com/ScriptReference/ContextMenu.html

    I already tried MarkSceneDirty for another feature and it worked correctly.

    I made a little test. This is the script. Even with empty project i can reproduce this, dont know if this is a bug or a feature :)

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PrefabContextMenuSave : MonoBehaviour
    6. {
    7.     public Transform OwnTransform;
    8.  
    9.     [ContextMenu("DoSomething")]
    10.     private void DoSomething()
    11.     {
    12.         this.OwnTransform = this.transform;
    13.     }
    14. }
    Steps:
    Attach this script to a gameobject.
    Make gameobject prefab.
    Open prefab, goto prefab view.
    Execute ContextMenu command via Inspector.
    See the change happen.
    Leave the Prefab view.
    Enter it again the change is not saved.
     
  4. runevision

    runevision

    Unity Technologies

    Joined:
    Nov 28, 2007
    Posts:
    1,679
    That doesn't matter, you still need to use one of the approaches Steen mentioned in order for changes to be saved.
     
  5. xKosta

    xKosta

    Joined:
    Oct 15, 2014
    Posts:
    22
    So I need to use EditorSceneManager.MarkSceneDirty? That would always include the Editor Namespace in a script as well as the handling during builds to ignore the namespace.
     
  6. runevision

    runevision

    Unity Technologies

    Joined:
    Nov 28, 2007
    Posts:
    1,679
    Hmm, right. You can use something like this:
    Code (CSharp):
    1. #if UNITY_EDITOR
    2. UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(gameObject.scene);
    3. #endif
     
  7. rabishan-maharjan

    rabishan-maharjan

    Joined:
    Jul 3, 2016
    Posts:
    6
    hi, i'm having same problem too.
    i created a simple UI Text and changed it's text from context menu and it worked without any problem.
    when i created prefab from that UI Text and tried to change it again, the text value changed. but when i enter play mode the change was replaced with the value from the prefab. i tried making scene dirty but it still didn't work.
     
  8. rabishan-maharjan

    rabishan-maharjan

    Joined:
    Jul 3, 2016
    Posts:
    6
    found the solution. had to record prefab modification too.

    UnityEditor.PrefabUtility.RecordPrefabInstancePropertyModifications(GetComponent<Text>());
     
    unity_ZVVVASk-TG7J1A likes this.