The process I use for renaming monobehaviours is so terrible that I end up frequently avoiding renaming poorly named behaviours. This kind of thing might sound minor, but good naming is an important tool to avoid code quality deterioration.
The annoying part is that, most of the time when you want to rename a monobehaviour it’s being driven from the code side. So the process is really:
In visual studio, decide that a file needs to be changed
tab into unity
search for the file name (may require upward of 4 clicks and/or typing)
rename the file
tab into visual studio
reload the project change
find the new file
resharper, rename class and references
recompile
tab into unity
refresh project
It’s also extremely dangerous if you use something like resharper in that a class+file rename from inside visual studio will break all the script references. So a careless change from the visual studio side be very time consuming to deal with.
There has really gotta be a better way to deal with this, isn’t there? Am I the only one that ends up just leaving poorly named monobehaviours around because it’s such a pain?
Is there something like [FormerlySerializedAs(“CrappyName”)] for classes that I missed?
Edit: To help clarify
The problem is not from the code side - automated refactoring and renaming will handle code that needs to be updated. The problem is that unity serializes inspector script references based on a matching filename + class name. Changing the class name from outside of unity will then break all of the script references set within unity’s inspector (or file browser in the case of scriptable object).
Unity does provide a tool for renaming fields, the [FormerlySerializedAs] attribute, but afaik, there is no good way to deal with file/class renames for monobehaviours.
Well, ideally, you name things properly from the start. The name should be clean an reflective of what it does. I often stub out most of the structure from the beginning, to try to avoid needing to rename. (though it still happens)
But, sometimes things do change. If I need to change a class name and it has scene/object references, I’ll just duplicate it and rename the copy. Then in inspector, you can just swap the script, and if you haven’t changed anything else, the values will persist. Then after I have dealt with scene refs, I’ll just do a project wide find and replace as required.
Ideally, we as programmers never make mistakes, never write bugs, and never have changing requirements.
I’m not sure I understand, can you clarify this?
Let’s say there’s a monobehaviour being used across 10 different scenes, do you manually go through each scene, find each reference to the script and manually change it??
If you care about efficiency, you should really use resharper, this process you describe above is ctr r + r, then type new name. Resharper renames the class, file, all references to the class and searches for all strings and variables that contain the class name or a variation and corrects this as well. But renaming references in code isn’t the problem - the problem is unity script references don’t get updated if you do this, so all your monobehaviour script references (in inspector) will break.
The best way I have found to deal with this, is to change the file name from unity (this will update unity’s internal script reference pointer, so every script reference will be updated to the new file name, unity will tell you the script is missing until you rename the class to match the updated file name) - you then go into the code and do the refactor → rename. But that process is (as described above) is arduous at best.
Mistakes? Never, not once. Sure, often I have pre-optimized code, and un-documented test cases, but never mistakes or bugs.
Yea, that is what I mean. Not pretty, but it helps retain that stuff.
I did once create an editor tool to help with swapping classes and maintaining links/values. Unfortunately, getting all the edge cases and conditions meant I spent more time building it than just doing it manually. I kinda gave up on after that. Mostly now I just try to keep inspector values to bare minimum, or in some cases have the settings as separate struct/class just for a bit more modularity. Not a perfect solution by any means, but generally works most of the time for me.
I’m on Mac and don’t use VS but in MonoDevelop you just refactor (rename in this case) the class name and it will take care of the rest, even renaming the file name.
I would never use replace in files except for very specific cases. It’s too risky in complex projects.
Could’ve sworn Unity just picked up the rename change I made in VS2013 and automatically updated the references. I think I just did that a few min ago. Anyway, yeah, I make my change in VS2013 and have Unity pick up the change. I could be wrong, I’ll check it later.
With MonoDevelop at least you must first rename the class file in the project, then open it in MonoDevelop and rename using F2, and it will work exactly as expected. If you don’t do the first step then in my experience all script references will be lost and it will show as missing in the inspector.
I think most people here miss one important thing: Unity’s policy of “Monobehaviour must be named same as the file it’s in herpaderp” is utterly stupid. This is not Java. This is C#. If I want to have file named droigohygodfitjohyidftoyijt.cs that contains class diurhgAUNHilrffgdouiOIUJfgojfjuigj (e.g. to confuse people trying to decompile my game), I better be able to.
Right after you rename something in VS a smart tool tip will pop up (in 2013 it’s a little rectangle near where you changed a name, in 2015, its a lightbulb in the left margin). If you click it, it will have an option “Rename classA to classB”. It will handle all of the references in code, but you have any string literals that contain the name, it cannot handle it.