- Home /
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.
Cases:
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.
This is a pretty complex problem to understand. $$anonymous$$aybe someone else will have some insight, but in the meantime I would suggest that you isolate this in a separate test project and keep reducing it until you get a very simple and clear example with easy steps to reproduce the problem. You will at least then have a project you can submit with a bug report to Unity, or you may discover an obscure bug in your script.
Answer by edwood_grant · Mar 28, 2012 at 03:42 PM
Hello,
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 overrides.
From here http://unity3d.com/support/documentation/ScriptReference/Editor.html
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.
Cheers, Italo F. Capasso B.
UPDATE
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.
I actually discovered this as well. I should have updated the question but forgot about this one.
After working with the Editor/SerializedObject stuff I kinda prefer it anyway. While it is kind of annoying when the values reset, and I cannot get control the move tool quite the same way (I think it has something to do with the refresh rate) the ability to use CTRL-Z and undo changes is absolutely crucial.
One thing that was not clear from the Unity documentation though, you can do something like this
mvGridPosition = mspGridPosition.vector3Value;
//buttons that manipulate mvGridPosition
mspGridPosition.vector3Value = mvGridPosition;
then serializedObject.Apply$$anonymous$$odifiedProperties();
Which lets you customize quite a bit
Indeed n n, I have added those kinds of examples in the answer to show other ways to work around this (^^)b
Your answer
Follow this Question
Related Questions
A node in a childnode? 1 Answer
my unity is freezing when adding prefab to script 1 Answer
Prefab not saving changes bug 1 Answer
Distance betwen two objects.Error,bug,etc. 2 Answers
Car driving backwards with triggers 1 Answer