Component Value Reverts to Prefab Value under certain conditions when Scene is Tested

So… There is a single value called gridPosition attacked to a component called GridItem. There is a Editor window that is used to edit these items ( Item Size, Transform offsets, position, gizmo stuff etc.) when such an item is selected. When the user has this window open, and is adjusting the transform of the gameObject, the window snaps the transform to the grid, based on some values from a gridManager(grid start, grid unit sizes) and updates the grid position based on this, as this value is used to draw gizmos, and generate box colliders on certain objects at runtime.

When the grid position value is modified directly in the Inspector, the changes are fine. When I change the values through the Editor Window(which happens when you move an object with the move tool) the values revert to whatever was the last value that was set in the inspector was. If there was not a value set in the inspector, it revert to the prefab if it has one. the value is modified before Awake is called on the script.
This behavior is only seen on Grid Items that are part of a prefab.


Case 1:
So Prefab Grid Item Grid Position is set to Value A;
If we move an instance of the prefab with the move tool, the item is moved, and Grid Position is set to Value B.
On test, Awake states the gridPosition is Value A. On test exit, Grid position is Value A.

Case 2:
Again a prefab is created waith values being Value A.
The grid position is changed directly in the inspector, and a context menu function adjust the transform to the new grid position, with Value Being B.
On test, value is still Value B.
If we move the item with the built in move tool, to Value C, then test, the value return to B by Awake, and is still B when the test concludes.

Case 3:
A Gameobject has the gridItem behavior attached to it, the gridPosition is A. It is not an instance of a prefab.
It is moved with the Move Tool, the gridPosition updated by the window, to grid Position B.
On test, the grid Position is B.

Case 4:
A game object that is not an instance of a prefab has the GridItem behavior attached to it, with gridPosition set to A. Item is moved by modifing values in the inspector, then transform is told to update to new position. Grid Position is now Value B. On test, Grid Position is B. Item is then modified using the window again, to Grid Position C.
On test, grid Position is C.

So basically, the determining factors of the bug are

A) The object must be a prefab.
and to a lesser extent
B) The value must have been edited by the gridwindow.
((B is lesser, because is A is false, B does not matter, it works correctly(See Case 3/4)))

For this Bug: The grid position is set to the last value set from the inspector. If one does not exist, the value is set to the prefab value.

This system worked before we updated to Unity 3.5(Pro)
I can make some workarounds that deal with the symptoms of the bug, like updating the grid position based on transform at awake and when the game returns from test, however, I would really like to find the source of this bug.

Thank you in advance. Also, if you think I should make a new post, let me know. This is my first time posting a bug to Unity Answers, so I’m trying to be slightly conservative.


I do have a similar problem. I had this when creating an event system, and has many of the same issues (like only ocurring when its a prefab, working in 3.4 and not in 3.5 and such). The only workaround I have to solve this for now is to actually break the prefab instance connection by selecting in the menu “GameObject->Break PRefab instance”.

However, I do have some suspicions when reading this in the scripting reference for 3.5.

Instead of modifying script variables
directly, it’s advantageous to use the
SerializedObject and
SerializedProperty system to edit
them, since this automatically handles
multi-object editing, undo, and prefab

From here

Note the crucial keyword “prefab overrides” and “undo”
So what I believe is that the old system by referencing vairables directly will not work well with all cases due to the new multiobject editing features of 3.5, so it is a matter of replacing all objects with this type of code:

class MyPlayerEditor : Editor {
    private SerializedProperty myProperty;
    private SerializedProperty anotherProperty;
    private SerializedProperty lastProperty;

    function OnEnable () {
        myProperty= serializedObject.FindProperty ("myFieldProperty");
        anotherProperty= serializedObject.FindProperty ("myFieldAnotherProperty");
        lastProperty= serializedObject.FindProperty ("myFieldLastProperty");

    function OnInspectorGUI() {
        serializedObject.Update ();
        // Use your custom editorGuilayoutfield here
        EditorGUILayout.IntSlider (myProperty, 0, 100, new GUIContent ("myFieldProperty label"));

        // Other ways to do it
        EditorGUILayout.PropertyField(this.anotherProperty, new GUIContent("anotherProperty"));
        this.lastProperty.enumValueIndex = EditorGUILayout.Popup("lastProperty", this.lastProperty.enumValueIndex, this.lastProperty.enumNames);

        serializedObject.ApplyModifiedProperties ();

I still have to test this approach by myself, but I believe that this might be the correct path to solve it.

Italo F. Capasso B.


Well I have tested it in a ver simple script that handled a grid, and now it works… so I guess this sould be the right approach to solve this problem.