Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
2
Question by SkandYxyz · Jan 28, 2016 at 01:39 PM · prefabvariableserialization

Script variable reverted to prefab when hit play.

Hello!

I use a c# mono behaviour that is also executed in edit mode. I have a public bool variable that i set to true via script. in edit mode i can see this value is set as aspected to true. when i hit play, this value switches to false, because i have a prefab with a false value. how can i prevent unity from reverting this value when i hit play? when i set this bool manually, it gets bold and is not affected, when i hit play.

Best, Andre

Sorry for the double answer! Here the script attatched - i hope it's not to much to read ;) #if (UNITY_EDITOR_WIN||UNITY_EDITOR||UNITY_EDITOR_64) using UnityEditor; using UnityEngine; using System; using System.Collections;

 /// <summary>
 /// Billboard baker pro class. Needs to be attatched to a GameObject, the billboard object.
 /// Handles all parameters to setup a working multitexture billboard. 
 /// </summary>
 /// Also executed in edit mode to interact with materials and shader.
 [ExecuteInEditMode]
 // The GameObject requires a MeshRenderer component
 [RequireComponent (typeof (MeshRenderer))]
 // The GameObject requires a MeshFilter component
 [RequireComponent (typeof (MeshFilter))]
 
 public class Billboard : MonoBehaviour {
 
     /// <summary>
     /// String defining the billboard class. Billboards of the same billboard class 
     /// share the same billbord textures. Keep in mind that two target objects containing the same render objects can't share the same billboard class if they have different rotations or scalings.
     /// Used to associate prefabs and scene GameObjects for baking process.
     /// </summary>
     [Tooltip("String defining the billboard class. Billboards of the same billboard class share the same billbord textures. Keep in mind that two target objects containing the same render objects can't share the same billboard class if they have different rotations or scalings.")]
     public string _billboardClass="";
 
     /// <summary>
     /// The GameObject to create a billboard from.
     /// </summary>
     [Tooltip("GameObject to bake a billboard from.")]
     public GameObject _targetGameObject;
 
     /// <summary>
     /// The size of one frame in pixel.
     /// </summary>
     [Tooltip("The size (height and width) of one frame in pixel.")]
     public int _size;
 
     /// <summary>
     /// The number of tiles that represent the target GameObject from different views.
     /// </summary>
     [Tooltip("The number of tiles that represent the target object from different views.")]
     public int _count;
 
     /// <summary>
     /// The zoom factor the orthographic size of the camera is divided by.
     /// </summary>
     [Tooltip("The zoom factor the orthographic size of the camera is divided by.")]
     public float _zoomFactor=1.0f;
 
     /// <summary>
     /// You can disable baking this billboard. If you have multiple billboards of the same class
     /// it is sensful to only bake one billboard. If you want to keep your bake, disable all bake
     /// values of all billboards of the same class.
     /// </summary>
     [Tooltip("You can disable baking this billboard class. If you have multiple billboards of the same class it is sensful to only bake one billboard. If you want to keep your bake, disable all bake values of all billboards of the same class.")]
     public bool _bake=true;
 
     public bool _billboardInitialized=false;
 
     /// <summary>
     /// GameObject with information component
     /// </summary>
     private GameObject _billboardInformationGameObject=null;
 
     /// <summary>
     /// At the very begnning of loading scene
     /// </summary>
     void Awake () {
         // If it is in edit mode
         if (!EditorApplication.isPlayingOrWillChangePlaymode) {
             // Check if billboard class is an empty string
             if(_billboardClass=="") {
                 // Billboard class string hasn't been set jet, 
                 // so set string to target game objects name.
                 _billboardClass = _targetGameObject.name;
             }
             // Load Object from Ressources
             UnityEngine.Object _tmpObject = Resources.Load (GetSceneName(EditorApplication.currentScene) + "/" + "info" + _billboardClass);
             // Does the thing we want to load exist?
             if(_tmpObject==null)
                 // Abort if this ressource doesn't exist
                 return;
             // Instantiate GameObject
             _billboardInformationGameObject = (GameObject)Instantiate (_tmpObject);
             // Is the billboard class new baked?
             if (_billboardInformationGameObject.GetComponent<BillboardBakerInformationExchange> ()._newBake == true) {
                 // This billboard class is not baked new anymore
                 _billboardInformationGameObject.GetComponent<BillboardBakerInformationExchange> ()._newBake = false;
                 // Store back as prefab
                 PrefabUtility.CreatePrefab ("Assets/Billboard Baker Pro/Resources/" + GetSceneName(EditorApplication.currentScene) + "/" + "info" + _billboardClass + ".prefab", _billboardInformationGameObject);
                 // Do this only once every billboard class:
                 // Declare texture variable
                 Texture2D _tex;
                 // Load Texture, if not exists, return
                 if ((_tex = Resources.Load (GetSceneName(EditorApplication.currentScene) + "/" + _billboardClass, typeof(Texture2D)) as Texture2D) == null) {
                     // Show warning for debugging.
                     Debug.LogWarning("Load billboard texture " + _billboardClass + " failed.");
                     return;
                 }
                 // As we are now in edit mode, change texture import settings
                 SetTextureImporterFormat (_tex, true);
                 // Declare material variable
                 Material _materialToModify;
                 // Load Material from assets. if no stored material exists, return.
                 if ((_materialToModify = Resources.Load (GetSceneName(EditorApplication.currentScene) + "/" +_billboardClass, typeof(Material)) as Material) == null)
                     return;
                 // Also make changes to the material. They are stored directly, as we are in edit mode. Set materials main texture
                 _materialToModify.mainTexture = _tex;
                 // Set shader frame count
                 _materialToModify.SetFloat ("_Count",(float)_count);
             }
             // Has the billboard class been initialized after last bake?
             if (this._billboardInitialized==false) {
                 // Set billboard class to initialized, so it will initialize only once
                 this._billboardInitialized = true;
 
                 EditorUtility.SetDirty (this);
                 // Declare material variable
                 Material _tmpMaterial;
                 // Load Material from assets, if not exists, return
                 if ((_tmpMaterial = Resources.Load (GetSceneName (EditorApplication.currentScene) + "/" + _billboardClass, typeof(Material)) as Material) == null)
                     return;
                 // Select Renderer
                 Renderer _billboardRenderer = this.gameObject.GetComponent<Renderer> ();
                 // Set Renderer material
                 _billboardRenderer.material = _tmpMaterial;
                 // Resize Billboard transform
                 this.transform.localScale = new Vector3 (_billboardInformationGameObject.GetComponent<BillboardBakerInformationExchange> ()._orthographicSize * 2.0f, _billboardInformationGameObject.GetComponent<BillboardBakerInformationExchange> ()._orthographicSize * 2.0f, _billboardInformationGameObject.GetComponent<BillboardBakerInformationExchange> ()._orthographicSize * 2.0f);
                 // Set Billboard world position to be target world position
                 this.transform.position = _targetGameObject.transform.position;
                 // Retrieve local position
                 Vector3 _tmpLocalPosition = this.transform.localPosition;
                 // Add y offset
                 _tmpLocalPosition.y += _billboardInformationGameObject.GetComponent<BillboardBakerInformationExchange> ()._offset;
                 // Adjust Billboard local position
                 this.transform.localPosition = _tmpLocalPosition;
                 // Retrieve MeshFilter 
                 MeshFilter _tmpMeshFilter = this.gameObject.GetComponent<MeshFilter> ();
                 // If mesh filter is attatched and shared mesh is not empty
                 if ((_tmpMeshFilter != null) && (_tmpMeshFilter.sharedMesh != null)) {
                     // Create a new independant mesh instance with the same propertys as the shared mesh 
                     Mesh _meshCopy = Mesh.Instantiate (_tmpMeshFilter.sharedMesh) as Mesh;
                     // Create uv2 2 dimensional vectors
                     Vector2[] _uv2s = new Vector2[_meshCopy.vertices.Length];
                     // Loop through all vertices
                     for (int i = 0; i < _uv2s.Length; i++) {
                         // Pass object (billboard) position needed for draw call batching support.
                         // Here all mesh objects are combined and the billboard positions get lost.
                         // So we save this information in the unneeded uv's
                         _uv2s [i] = new Vector2 (this.transform.position.x, this.transform.position.y);
                     }
                     // Store uv's in the second slot
                     _meshCopy.uv2 = _uv2s;
                     // Create uv3 2 dimensional vectors
                     Vector2[] _uv3s = new Vector2[_meshCopy.vertices.Length];
                     // Loop through all vertices
                     for (int i = 0; i < _uv3s.Length; i++) {
                         // Pass object (billboard) position needed for draw call batching support.
                         // Also pass object scale. As the billboard should be scaled uniformly (x==y==z)
                         // one value is enough.
                         _uv3s [i] = new Vector2 (this.transform.position.z, this.transform.localScale.x);
                     }
                     // Store uv's in the third slot
                     _meshCopy.uv3 = _uv3s;
                     // Replace the shared mesh with the new instance
                     _tmpMeshFilter.mesh = _meshCopy;
                 }
             }
             // Destroy information GameObject
             _billboardInformationGameObject.GetComponent<BillboardBakerInformationExchange> ()._destroySelf =true;
         }
     }
 
     /// <summary>
     /// OnValidate is called when user makes input
     /// </summary>
     void OnValidate () {
         // Check if billboard class is an empty string
         if ((_billboardClass == "")&&(_targetGameObject!=null))
             // Set billboard class to target GameObject's name
             _billboardClass = _targetGameObject.name;
         // Check count variable
         if (_count < 1)
             // set to 1 if value is below
             _count = 1;
     }
 
     /// <summary>
     /// Sets the isReadable flag of the Texture
     /// </summary>
     /// <param name="texture">Texture.</param>
     /// <param name="isAlphaTransparency">If set to <c>true</c> alpha is transparency.</param>
     public static void SetTextureImporterFormat( Texture2D texture, bool isAlphaTransparency)
     {
         // Nothing to do if no texture passed
         if ( null == texture ) return;
         // Retrieve textures file path
         string assetPath = AssetDatabase.GetAssetPath( texture );
         // Open path with texture importer class
         var tImporter = AssetImporter.GetAtPath( assetPath ) as TextureImporter;
         // Did we succeed wopen the file?
         if ( tImporter != null )
         {
             // Change texture type to advanced
             tImporter.textureType = TextureImporterType.Advanced;
             // Set alpha to be the transparency value
             tImporter.alphaIsTransparency = isAlphaTransparency;
             // Keep the original border pixels in all mip map levels
             tImporter.borderMipmap = true;
             // Reimport the texture with the chosen settings
             AssetDatabase.ImportAsset( assetPath );
             // Refresh the database
             AssetDatabase.Refresh();
         }
     }
     
     /// <summary>
     /// Creates the billboard game object.
     /// </summary>
     /// <param name="menuCommand">Menu command.</param>
     [MenuItem("GameObject/3D Object/Billboard", false, 10)]
     static void CreateBillboardGameObject(MenuCommand menuCommand) {
         // Create a custom game object with quad
         GameObject _gameObject = GameObject.CreatePrimitive (PrimitiveType.Quad);
         // Set Name to default
         _gameObject.name = "Billboard";
         // Remove Mesh Collider as you should use the mesh collider of the original mesh
         DestroyImmediate(_gameObject.GetComponent<MeshCollider>());
         // Add billboard component to the game object
         _gameObject.AddComponent<Billboard>();
         // Enable component
         _gameObject.GetComponent<Billboard> ().enabled = true;
         // Ensure it gets reparented if this was a context click (otherwise does nothing)
         GameObjectUtility.SetParentAndAlign(_gameObject, menuCommand.context as GameObject);
         // If parent exists,
         if (_gameObject.transform.parent.gameObject != null)
             // set parent to be the target game object
             _gameObject.GetComponent<Billboard>()._targetGameObject = _gameObject.transform.parent.gameObject;
         // Initialize count to 16
         _gameObject.GetComponent<Billboard> ()._count = 16;
         // Initialize size to 64 px
         _gameObject.GetComponent<Billboard> ()._size = 64;
         // Register the creation in the undo system
         Undo.RegisterCreatedObjectUndo(_gameObject, "Create " + _gameObject.name);
         // Select the created game object
         Selection.activeObject = _gameObject;
     }
 
     /// <summary>
     /// Gets the name of the scene.
     /// </summary>
     /// <returns>The scene path.</returns>
     public static string GetSceneName(string _scenePath)
     {
         // Return the scene name only
         return System.IO.Path.GetFileNameWithoutExtension(_scenePath);
     }
 }
 
Comment
Add comment · Show 6
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image SkandYxyz · Jan 28, 2016 at 02:10 PM 0
Share

Yes, you are absolutely right, when i save, close and reopen the scene these values are the prefab values again. I tryed this:

EditorUtility.SetDirty (this);

in my monobehaviour function right after the variable change, but nothing changes. Is there something else i have to put there ins$$anonymous$$d of this? (this is pointing at the mono behaviour instance)

thank you for the quick response!

best, Andre

Edit:

at vivien: so you wrote that the setdirty() function needs a gameobject or component to be passed. as the 'this' statement refers to the monobehaviour instance just edited, EditorUtility.SetDirty (this); should work, but doesn't actually.

at brunocoimbra: so you mean i change the bool variable somewhere else when i hit play. i do not think so, because when i use the script on a gameobject that has no prefab linked, it works as aspected. I use $$anonymous$$onoDevelop as editor.

You can reproduce this case quite easy. Add this script to a GameObject and make a prefab of it. When your prefabs _test value is false and you hit play, _test is false. In edit mode it will be true.

 [ExecuteInEdit$$anonymous$$ode]
 public class Test : $$anonymous$$onoBehaviour() {
     public bool _test=false;
     void Awake() {
         _test=true;
     }
 }

Oh, i tryed it myself and this time it works. Huh. Strange ;)

at brunocoimbra:

The first bool _bake is not in use jet, as it's a future feature. It's this bool causing issues: _billboardInitialized

I tried to set up my gameobject from scratch and it still doesn't work although having the same structure as the working test script above.

Unbelievable! This was the solution! You have to add the undo line, else it won't work in this case: Undo.RecordObject(this,"Set Value");

So really thank you all for your effort and saving my day ;)

avatar image VivienS SkandYxyz · Jan 28, 2016 at 02:21 PM 1
Share

just edited my answer!

avatar image brunocoimbra SkandYxyz · Jan 28, 2016 at 02:25 PM 2
Share

Convert your answer to a comment, never post something as answer that is not meant to be the answer to the question.

Back to the question, can you post the script? I believe that maybe you are initializing it somewhere in your code. If you use Visual Studio, you can right click on the variable name and click in "Find all references", it will make the search easier and more accurate.

avatar image VivienS SkandYxyz · Jan 28, 2016 at 03:37 PM 1
Share

And edited it again ;)

Show more comments
avatar image brunocoimbra · Jan 28, 2016 at 03:11 PM 1
Share

There are just 2 bools:

   public bool _bake = true;
   public bool _billboardInitialized = false;

The first one is never referenced in that script, while the other is setted to true on Awake in line 111 (the line number will look diferent in your project, as you did not formated your entire code).

Which one is causing you trouble?

1 Reply

· Add your reply
  • Sort: 
avatar image
9
Best Answer

Answer by VivienS · Jan 28, 2016 at 01:53 PM

Try http://docs.unity3d.com/ScriptReference/EditorUtility.SetDirty.html when you execute the script that changes the public variable.

I guess the value is not correctly flagged as an override to the prefab and probably also wont be stored if you save / re-open the scene?

Edit:

@SkandYxyz

You have to Execute the SetDirty() on the Component that you are modifying. Plus, since Unity 5.3 you apparently need to record an Undo action too. (Had to google that myself)

I stripped your code down a bit (for visibility's sake ;)) and tested it. This combination of calls works: the variable becomes an override (you can recognize it by the fat font in the editor).

 [ExecuteInEditMode]
 public class Billboard : MonoBehaviour
 {
     public bool _billboardInitialized = false;
 
     void Awake ()
     {
         if (!EditorApplication.isPlayingOrWillChangePlaymode) 
         {
             if (this._billboardInitialized == false) 
             {
                 Undo.RecordObject (this, "Set Value");
                 this._billboardInitialized = true;
                 EditorUtility.SetDirty (this);
             }
         }
     }
 }


Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image GiyomuGames · Feb 15, 2017 at 02:44 AM 0
Share

Thanks! Just what I needed :)

avatar image moonpoint · Oct 09, 2018 at 03:23 PM 0
Share

Thank you,really helpful !

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

50 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to access a variable from a game object once instantiated (C#) 1 Answer

How do I assign a prefab reference to a private variable? 1 Answer

How to force variables in a script to be unique to every instance? 0 Answers

Clone of prefabs copy original´s script state during runtime? 0 Answers

Unity custom editor, values will not serialize 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges