Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
0
Question by xenix2012 · Jan 05, 2015 at 09:06 PM · c#editoraddremove

Adding new script, copying values, removing old script without selecting GO.

Hi, here is my problem. I have old system(script) attached to 300 GO in "random" folders. I need to find all object with this script in my project, add new system(script), copy values from old one to new one and remove old one. Do I have to do it manualy or it is possible to use script?

Comment
Add comment · Show 4
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 HYPERSAVV · Jan 05, 2015 at 09:55 PM 0
Share

Are all these objects the same? Sounds like you should be using a prefab.

avatar image xenix2012 · Jan 05, 2015 at 10:59 PM 0
Share

Those are prefabs :)

avatar image richyrich · Jan 05, 2015 at 11:07 PM 0
Share

Why not just update the old script to include new script functionality?

avatar image xenix2012 · Jan 05, 2015 at 11:44 PM 0
Share

Cause there is a mess and i have 3 scripts doing this same thing. I want to replace them using one script (with a lot of changes, but variables will be the same)

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by Scribe · Jan 06, 2015 at 02:49 PM

Hey, here is an Editor script that should do this.

WARNING: I would suggest you thoroughly test this on a small number of assets first to make sure everything is working as you expect. I have tested it somewhat and it seems to be working nicely, but if it goes wrong, you will have permanently changed those assets, possibly even duplicate your project first to make sure you don't loose 300 lots of data!

I will feel very sorry if it goes wrong but I take no responsibility if that happens :D

  1. So create a new C# script named 'ScriptReplacer' and add the code to it. Once it is saved when you click somewhere on the top menu bar it should update to have a drop down called 'EditorUtility' (if it doesn't appear, restart unity).

  2. Click the dropdown and select the (probably) only option 'Script Replacer' and an editor window should show up.

  3. The first (left) object field is the script that you want to change to (I will refer to this as script B), the second object field is the script to copy and then delete (and refer to this as script A).

  4. Once you have selected two scripts you should have a list on the left of the changeable values in B (public variables) and a set of drop-down selections containing the public variables of A and finally a set of text boxes for default values.

  5. You should select from the drop-downs the values you want to set the respective B variable to or select ' use default' to automatically use the value in the default box. ~Hopefully~ it should stop you trying to set a value to an incompatible type, e.g. it should let you set an Int variable in B to a Int of Float variable in A, but it should not let you set an Int to a string.

  6. Once you have set up everything and double-checked what you are setting to what is sensible then hit replace and then yes.

Note: if an object has both script B and A already attached, it will copy the values from A into the existing instance of B and delete the A component

Code:

 using UnityEngine;
 using UnityEditor;
 using System;
 using System.Collections;
 using System.Reflection;
 
 public class ScriptReplacer : EditorWindow {
     static ScriptReplacer window;
     static MonoScript oldOriginalScript;
     static MonoScript oldReplacerScript;
     static MonoScript originalScript;
     static MonoScript replacerScript;
     System.Type t;
     
     static int GOcount = 0;
     
     static System.Reflection.FieldInfo[] originalVariableList;
     static System.Reflection.FieldInfo[] replacerVariableList;
     
     static UnityEngine.Object[] gameobjectList;
     static System.Object[] defaultVal;
     static int[] replacerIndex;
     static string[] replaceOptions;
     
     bool checkPrompt = false;
     
     [MenuItem("EditorUtility/Script Replacer")]
     static void OpenScriptFinder(){
         window = (ScriptReplacer)EditorWindow.GetWindow(typeof(ScriptReplacer));
     }
     
     void OnGUI(){
         EditorGUILayout.LabelField(GOcount.ToString() + " script instance(s) to be replaced");
         
         EditorGUILayout.BeginVertical();
         
         EditorGUILayout.BeginHorizontal();
         
         EditorGUILayout.BeginVertical();
         
         oldReplacerScript = replacerScript;
         replacerScript = (MonoScript)EditorGUILayout.ObjectField("Use Script", replacerScript, typeof(MonoScript), false);
         if(oldReplacerScript != replacerScript){
             t = replacerScript.GetClass();
             replacerVariableList = t.GetFields(BindingFlags.Instance | BindingFlags.Public);
         }
         
         if(replacerVariableList != null){
             for(int i = 0; i < replacerVariableList.Length; i++){
                 EditorGUILayout.LabelField(string.Format("set value of {0} ({1}) in {2} to", replacerVariableList[i].Name, replacerVariableList[i].FieldType.Name, replacerScript.name));
             }
         }
         
         EditorGUILayout.EndVertical();
         EditorGUILayout.Space();
         EditorGUILayout.BeginVertical();    
         
         oldOriginalScript = originalScript;
         originalScript = (MonoScript)EditorGUILayout.ObjectField("to replace", originalScript, typeof(MonoScript), false);
         
         if(oldOriginalScript != originalScript){
             t = originalScript.GetClass();
             gameobjectList = Resources.FindObjectsOfTypeAll(t) as UnityEngine.Object[];
             GOcount = gameobjectList.Length;
             originalVariableList = t.GetFields(BindingFlags.Instance | BindingFlags.Public);
             defaultVal = new System.Object[replacerVariableList.Length];
             replaceOptions = new string[originalVariableList.Length+1];
             replacerIndex = new int[replacerVariableList.Length];
             for(int k = 0; k < originalVariableList.Length; k++){
                 replaceOptions[k] = (originalVariableList[k].Name + " in " + originalScript.name);
             }
             replaceOptions[originalVariableList.Length] = "Use default";
         }
         
         if(replacerVariableList != null && originalVariableList != null && replacerIndex != null && replaceOptions != null){
             for(int j = 0; j < replacerVariableList.Length; j++){
                 EditorGUILayout.BeginHorizontal();
                 
                 replacerIndex[j] = EditorGUILayout.Popup(replacerIndex[j], replaceOptions);
                 
                 if(replacerIndex[j] != originalVariableList.Length){
                     try{
                         System.Type oT = originalVariableList[replacerIndex[j]].FieldType;
                         System.Type rT = replacerVariableList[j].FieldType;
                         System.Object tester;
                         try{
                             tester = Activator.CreateInstance(oT);
                         }catch{
                             tester = "";
                         }
                         var test = Convert.ChangeType(tester, rT);
                     }catch{
                         replacerIndex[j] = originalVariableList.Length;
                     }
                 }
                 
                 EditorGUILayout.LabelField(" or default to ");
                 
                 if(defaultVal[j] == null){
                     try{
                         defaultVal[j] = Activator.CreateInstance(replacerVariableList[j].FieldType);
                     }catch{
                         defaultVal[j] = "";
                     }
                 }
                 defaultVal[j] = EditorGUILayout.TextField(defaultVal[j].ToString());
                 
                 try{
                     defaultVal[j] = Convert.ChangeType(defaultVal[j], replacerVariableList[j].FieldType);
                 }catch{
                     try{
                         defaultVal[j] = Activator.CreateInstance(replacerVariableList[j].FieldType);
                     }catch{
                         defaultVal[j] = "";
                     }
                 }
                 EditorGUILayout.EndHorizontal();
             }
         }
         
         EditorGUILayout.EndVertical();
         EditorGUILayout.EndHorizontal();
         
         EditorGUILayout.Space();
         
         if(replacerScript != null && originalScript != null){
             if(!checkPrompt){
                 if(GUILayout.Button("Replace")){
                     checkPrompt = true;
                     //Replace();
                 }
             }else{
                 EditorGUILayout.LabelField("Are you sure you wish to continue? This will permanently change your assets!");
                 
                 EditorGUILayout.BeginHorizontal();
                 
                 if(GUILayout.Button("Yes")){
                     checkPrompt = false;
                     Replace();
                 }
                 
                 if(GUILayout.Button("No")){
                     checkPrompt = false;
                 }
                 
                 EditorGUILayout.EndHorizontal();
             }
         }
         EditorGUILayout.EndVertical();
     }
     
     void Replace(){
         GameObject[] gos = Resources.FindObjectsOfTypeAll<GameObject>() as GameObject[];
         t = originalScript.GetClass();
         gameobjectList = Resources.FindObjectsOfTypeAll(t) as UnityEngine.Object[];
         GOcount = gameobjectList.Length;
         
         for(int g = 0; g < gos.Length; g++){
             GameObject go = gos[g];
             
             if(go.hideFlags == HideFlags.NotEditable || go.hideFlags == HideFlags.HideAndDontSave){
                 continue;
             }
             
             string assetPath = AssetDatabase.GetAssetPath(go.transform.root.gameObject);
             if (String.IsNullOrEmpty(assetPath)){
                 continue;
             }
             
             System.Type tOld = originalScript.GetClass();
             System.Type tNew = replacerScript.GetClass();
             
             if(go.GetComponent(tOld) == null){
                 continue;
             }
             
             Component cOld = go.GetComponent(tOld);
             Component cNew;
             if(go.GetComponent(tNew) == null){
                 cNew = go.AddComponent(tNew);
             }else{
                 cNew = go.GetComponent(tNew);
             }
             
             for(int j = 0; j < replacerVariableList.Length; j++){
                 if(replacerIndex[j] != originalVariableList.Length){
                     try{
                         System.Object obj = Convert.ChangeType(originalVariableList[replacerIndex[j]].GetValue(cOld), replacerVariableList[j].FieldType);
                         
                         replacerVariableList[j].SetValue(cNew, obj);
                     }catch{
                         try{
                             replacerVariableList[j].SetValue(cNew, Activator.CreateInstance(replacerVariableList[j].FieldType));
                         }catch{}
                     }
                 }else{
                     try{
                         replacerVariableList[j].SetValue(cNew, defaultVal[j]);
                     }catch{}
                 }
                 DestroyImmediate(cOld, true);
             }
         }
     }
 }



Hope that helps and saves some time!

Scribe

Comment
Add comment · 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

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

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Initialising List array for use in a custom Editor 1 Answer

Distribute terrain in zones 3 Answers

Multiple Cars not working 1 Answer

How would you go about 'painting' images onto terrain 0 Answers

Custom editor field accepting multiple drag and drops? 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