devmag.org.za
A game development magazine
Process
1. Avoid branching assets. There should always only ever be one version of any asset. If you absolutely
have to branch a prefab, scene, or mesh, follow a process that makes it very clear which is the right
devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/
1/31
19/08/13
version. The wrong branch should have a funky name, for example, use a double underscore prefix:
__MainScene_Backup. Branching prefabs requires a specific process to make it safe (see under the section
Prefabs).
2. Each team member should have a second copy of the project checked out for testing if you are
using version control. After changes, this second copy, the clean copy, should be updated and tested. Noone should make any changes to their clean copies. This is especially useful to catch missing assets.
3. Consider using external level tools for level editing. Unity is not the perfect level editor. For
example, we have used TuDee to build levels for a 3D tile-based game, where we could benefit from the
tile-friendly tools (snapping to grid, and multiple-of-90-degrees rotation, 2D view, quick tile selection).
Instantiating prefabs from an XML file is straightforward. See Guerrilla Tool Development for more ideas.
4. Consider saving levels in XML instead of in scenes. This is a wonderful technique:
It makes it unnecessary to re-setup each scene.
It makes loading much faster (if most objects are shared between scenes).
It makes it easier to merge scenes (even with Unitys new text-based scenes there is so much data
in there that merging is often impractical in any case).
It makes it easier to keep track of data across levels.
You can still use Unity as a level editor (although you need not). You will need to write some code to
serialize and deserialize your data, and load a level both in the editor and at runtime, and save levels from
the editor. You may also need to mimic Unitys ID system for maintaining references between objects.
5. Consider writing generic custom inspector code. To write custom inspectors is fairly
straightforward, but Unitys system has many drawbacks:
It does not support taking advantage of inheritance.
It does not let you define inspector components on a field-type level, only a class-type level. For
instance, if every game object has a field of type SomeCoolType, which you want rendered
differently in the inspector, you have to write inspectors for all your classes.
You can address these issues by essentially re-implementing the inspector system. Using a few tricks of
reflection, this is not as hard as it seems, details are provided at the end of the article.
Scene Organisation
6. Use named empty game objects as scene folders. Carefully organise your scenes to make it easy to
find objects.
7. Put maintenance prefabs and folders (empty game objects) at 0 0 0. If a transform is not
specifically used to position an object, it should be at the origin. That way, there is less danger of running
devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/
2/31
19/08/13
into problems with local and world space, and code is generally simpler.
8. Minimise using offsets for GUI components. Offsets should always be used to layout components
in their parent component only; they should not rely on the positioning of their grandparents. Offsets
should not cancel each other out to display correctly. It is basically to prevent this kind of thing:
Parent container arbitrarily placed at (100, -50). Child, meant to be positioned at (10, 10), then placed at
(90, 60) [relative to parent].
This error is common when the container is invisible, or does not have a visual representation at all.
9. Put your world floor at y = 0. This makes it easier to put objects on the floor, and treat the world as a
2D space (when appropriate) for game logic, AI, and physics.
10. Make the game runnable from every scene. This drastically reduces testing time. To make all
scenes runnable you need to do two things:
First, provide a way to mock up any data that is required from previously loaded scenes if it is not
available.
Second, spawn objects that must persist between scene loads with the following idiom:
myObject = FindMyObjectInScene();
if (myObjet == null)
{
myObject = SpawnMyObject();
}
Art
11. Put character and standing object pivots at the base, not in the centre. This makes it easy to
put characters and objects on the floor precisely. It also makes it easier to work with 3D as if it is 2D for
game logic, AI, and even physics when appropriate.
12. Make all meshes face in the same direction (positive or negative z axis). This applies to meshes
such as characters and other objects that have a concept of facing direction. Many algorithms are
simplified if everything have the same facing direction.
13. Get the scale right from the beginning. Make art so that they can all be imported at a scale factor
of 1, and that their transforms can be scaled 1, 1, 1. Use a reference object (a Unity cube) to make scale
comparisons easy. Choose a world to Unity units ratio suitable for your game, and stick to it.
14. Make a two-poly plane to use for GUI components and manually created particles. Make the plane
devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/
3/31
19/08/13
face the positive z-axis for easy billboarding and easy GUI building.
15. Make and use test art
Squares labelled for skyboxes.
A grid.
Various flat colours for shader testing: white, black, 50% grey, red, green, blue, magenta, yellow,
cyan.
Gradients for shader testing: black to white, red to green, red to blue, green to blue.
Black and white checkerboard.
Smooth and rugged normal maps.
A lighting rig (as prefab) for quickly setting up test scenes.
Prefabs
16. Use prefabs for everything. The only game objects in your scene that should not be prefabs should
be folders. Even unique objects that are used only once should be prefabs. This makes it easier to make
changes that dont require the scene to change. (An additional benefit is that it makes building sprite
atlases reliable when using EZGUI).
17. Use separate prefabs for specialisation; do not specialise instances. If you have two enemy
types, and they only differ by their properties, make separate prefabs for the properties, and link them in.
This makes it possible to
make changes to each type in one place
make changes without having to change the scene.
If you have too many enemy types, specialisation should still not be made in instances in the editor. One
alternative is to do it procedurally, or using a central file / prefab for all enemies. A single drop down could
be used to differentiate enemies, or an algorithm based on enemy position or player progress.
18. Link prefabs to prefabs; do not link instances to instances. Links to prefabs are maintained
when dropping a prefab into a scene; links to instances are not. Linking to prefabs whenever possible
reduces scene setup, and reduce the need to change scenes.
19. As far as possible, establish links between instances automatically. If you need to link
instances, establish the links programmatically. For example, the player prefab can register itself with the
GameManagerwhen it starts, or the GameManagercan find the Playerprefab instance when it starts.
Dont put meshes at the roots of prefabs if you want to add other scripts. When you make the
prefab from a mesh, first parent the mesh to an empty game object, and make that the root. Put scripts
on the root, not on the mesh node. That way it is much easier to replace the mesh with another mesh
without loosing any values that you set up in the inspector.
devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/
4/31
19/08/13
Use linked prefabs as an alternative to nested prefabs. Unity does not support nested prefabs, and
existing third-party solutions can be dangerous when working in a team because the relationship
between nested prefabs is not obvious.
20. Use safe processes to branch prefabs. The explanation use the Player prefab as an example.
Make a risky change to the Player prefab is as follows:
1. Duplicate the Playerprefab.
2. Rename the duplicate to __Player_Backup.
3. Make changes to the Playerprefab.
4. If everything works, delete __Player_Backup.
Do not name the duplicate Player_New, and make changes to it!
Some situations are more complicated. For example, a certain change may involve two people, and
following the above process may break the working scene for everyone until person two finished. If it is
quick enough, still follow the process above. For changes that take longer, the following process can be
followed:
1. Person 1:
1. Duplicate the Playerprefab.
2. Rename it to __Player_WithNewFeatureor __Player_ForPerson2.
3. Make changes on the duplicate, and commit / give to Person 2.
2. Person 2:
1. Make changes to new prefab.
2. Duplicate Playerprefab, and call it __Player_Backup.
3. Drag an instance of __Player_WithNewFeatureinto the scene.
4. Drag the instance onto the original Playerprefab.
5. If everything works, delete __Player_Backupand __Player_WithNewFeature.
devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/
5/31
19/08/13
23. Use extensions to work with components that share an interface. It is sometimes convenient
to get components that implement a certain interface, or find objects with such components.
The implementations below uses typeofinstead of the generic versions of these functions. The generic
versions dont work with interfaces, but typeofdoes. The methods below wraps this neatly in generic
methods.
//Defined in the common base class for all mono behaviours
public I GetInterfaceComponent<I>() where I : class
{
return GetComponent(typeof(I)) as I;
}
public static List<I> FindObjectsOfInterface<I>() where I : class
{
MonoBehaviour[] monoBehaviours = FindObjectsOfType<MonoBehaviour>();
List<I> list = new List<I>();
foreach(MonoBehaviour behaviour in monoBehaviours)
{
I component = behaviour.GetComponent(typeof(I)) as I;
if(component != null)
{
list.Add(component);
}
}
return list;
}
6/31
19/08/13
found.
public static T GetSafeComponent<T>(this GameObject obj) where T : MonoBehaviour
{
T component = obj.GetComponent<T>();
if(component == null)
{
Debug.LogError("Expected to find component of type "
+ typeof(T) + " but found none", obj);
}
return component;
}
Idioms
26. Avoid using different idioms to do the same thing. In many cases there are more than one
idiomatic way to do things. In such cases, choose one to use throughout the project. Here is why:
Some idioms dont work well together. Using one idiom well forces design in one direction that is
not suitable for another idiom.
Using the same idiom throughout makes it easier for team members to understand what is going
on. It makes structure and code easier to understand. It makes mistakes harder to make.
Examples of idiom groups:
Coroutines vs. state machines.
Nested prefabs vs. linked prefabs vs. God prefabs.
Data separation strategies.
Ways of using sprites for states in 2D games.
Prefab structure.
Spawning strategies.
Ways to locate objects: by type vs. name vs. tag vs. layer vs. reference (links).
Ways to group objects: by type vs. name vs. tag vs. layer vs. arrays of references (links).
Finding groups of objects versus self registration.
Controlling execution order (Using Unitys execution order setup versus yield logic versus Awake /
Start and Update / Late Update reliance versus manual methods versus any-order architecture).
Selecting objects / positions / targets with the mouse in-game: selection manager versus local selfmanagement.
Keeping data between scene changes: through PlayerPrefs, or objects that are not Destroyed when
a new scene is loaded.
Ways of combining (blending, adding and layering) animation.
Time
devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/
7/31
19/08/13
27. Maintain your own time class to make pausing easier. Wrap Time.DeltaTimeand
Time.TimeSinceLevelLoadto account for pausing and time scale. It requires discipline to use it, but will
make things a lot easier, especially when running things of different clocks (such as interface animations
and game animations).
Spawning Objects
28. Dont let spawned objects clutter your hierarchy when the game runs. Set their parents to a
scene object to make it easier to find stuff when the game is running. You could use a empty game object,
or even a singleton with no behaviour to make it easier to access from code. Call this object
DynamicObjects.
Class Design
29. Use singletons for convenience. The following class will make any class that inherits from it a
singleton automatically:
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
protected static T instance;
/**
Returns the instance of this singleton.
*/
public static T Instance
{
get
{
if(instance == null)
{
instance = (T) FindObjectOfType(typeof(T));
if (instance == null)
{
Debug.LogError("An instance of " + typeof(T) +
" is needed in the scene, but there is none.");
}
}
return instance;
}
}
}
8/31
19/08/13
Define static properties and methods for public variables and methods that are used often from
outside the class. This allows you to write GameManager.Playerinstead of
GameManager.Instance.player.
30. For components, never make variables public that should not be tweaked in the inspector.
Otherwise it will be tweaked by a designer, especially if it is not clear what it does. In some rare cases it is
unavoidable. In that case use a two or even four underscores to prefix the variable name to scare away
tweakers:
public float __aVariable;
31. Separate interface from game logic. This is essentially the MVC pattern.
Any input controller should only give commands to the appropriate components to let them know the
controller has been invoked. For example in controller logic, the controller could decide which commands
to give based on the player state. But this is bad (for example, it will lead to duplicate logic if more
controllers are added). Instead, the Player object should be notified of the intent of moving forward, and
then based on the current state (slowed or stunned, for example) set the speed and update the player
facing direction. Controllers should only do things that relate to their own state (the controller does not
change state if the player changes state; therefore, the controller should not know of the player state at
all). Another example is the changing of weapons. The right way to do it is with a method on Player
SwitchWeapon(Weapon newWeapon), which the GUI can call. The GUI should not manipulate transforms
Gameplay objects should know virtually nothing of the GUI. The one exception is the pause behaviour,
which is may be controlled globally through Time.timeScale(which is not a good idea as well see ).
Gameplay objects should know if the game is paused. But that is all. Therefore, no links to GUI
components from gameplay objects.
In general, if you delete all the GUI classes, the game should still compile.
You should also be able to re-implement the GUI and input without needing to write any new game logic.
32. Separate state and bookkeeping. Bookkeeping variables are used for speed or convenience, and
can be recovered from the state. By separating these, you make it easier to
save the game state, and
devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/
9/31
19/08/13
10/31
19/08/13
34. Dont use strings for anything other than displayed text. In particular, do not use strings for
identifying objects or prefabs etc. One unfortunate exception is animations, which generally are accessed
with their string names.
35. Avoid using public index-coupled arrays. For instance, do not define an array of weapons, an array
of bullets, and an array of particles , so that your code looks like this:
public void SelectWeapon(int index)
{
currentWeaponIndex = index;
Player.SwitchWeapon(weapons[currentWeapon]);
}
public void Shoot()
{
Fire(bullets[currentWeapon]);
FireParticles(particles[currentWeapon]);
}
The problem for this is not so much in the code, but rather setting it up in the inspector without making
mistakes.
Rather, define a class that encapsulates the three variables, and make an array of that:
[Serializable]
public class Weapon
{
public GameObject prefab;
public ParticleSystem particles;
public Bullet bullet;
}
The code looks neater, but most importantly, it is harder to make mistakes in setting up the data in the
inspector.
36. Avoid using arrays for structure other than sequences. For example, a player may have three
types of attacks. Each uses the current weapon, but generates different bullets and different behaviour.
You may be tempted to dump the three bullets in an array, and then use this kind of logic:
public void FireAttack()
{
/// behaviour
Fire(bullets[0]);
}
devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/
11/31
19/08/13
12/31
19/08/13
Text
38. If you have a lot of story text, put it in a file. Dont put it in fields for editing in the inspector. Make
it easy to change without having to open the Unity editor, and especially without having to save the
scene.
39. If you plan to localise, separate all your strings to one location. There are many ways to do this.
One way is to define a Text class with a public string field for each string, with defaults set to English, for
example. Other languages subclass this and re-initialize the fields with the language equivalents.
More sophisticated techniques (appropriate when the body of text is large and / or the number of
languages is high) will read in a spread sheet and provide logic for selecting the right string based on the
chosen language.
13/31
19/08/13
44. Implement shortcuts for printing the players world position. This makes it easy to report the
position of bugs that occur in specific places in the world, which in turns makes it easier to debug.
45. Implement debug options for making testing easier. Some examples:
Unlock all items.
Disable enemies.
Disable GUI.
Make player invincible.
Disable all gameplay.
46. For teams that are small enough, make a prefab for each team member with debug options.
Put a user identifier in a file that is not committed, and is read when the game is run. This why:
Team members do not commit their debug options by accident and affect everyone.
Changing debug options dont change the scene.
47. Maintain a scene with all gameplay elements. For instance, a scene with all enemies, all objects
you can interact with, etc. This makes it easy to test functionality without having to play too long.
48. Define constants for debug shortcut keys, and keep them in one place. Debug keys are not
normally (or conveniently) processed in a single location like the rest of the game input. To avoid shortcut
key collisions, define constants in a central place. An alternative is to process all keys in one place
regardless of whether it is a debug function or not. (The downside is that this class may need extra
references to objects just for this).
Documentation
49. Document your setup. Most documentation should be in the code, but certain things should be
documented outside code. Making designers sift through code for setup is time-wasting. Documented
setups improved efficiency (if the documents are current).
Document the following:
Layer uses (for collision, culling, and raycasting essentially, what should be in what layer).
Tag uses.
GUI depths for layers (what should display over what).
Scene setup.
Idiom preferences.
Prefab structure.
Animation layers.
devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/
14/31
19/08/13
15/31
19/08/13
Structure
The organisation of your scenes, project folder, and script folder should follow a similar pattern.
Folder Structure
Materials
GUI
Effects
Meshes
Actors
DarkVampire
LightVampire
...
Structures
Buildings
...
Props
Plants
...
...
Plugins
Prefabs
Actors
Items
...
Resources
Actors
Items
...
Scenes
GUI
Levels
TestScenes
Scripts
Textures
GUI
Effects
...
Scene Structure
Cameras
devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/
16/31
19/08/13
Dynamic Objects
Gameplay
Actors
Items
...
GUI
HUD
PauseMenu
...
Management
Lights
World
Ground
Props
Structure
...
ThirdParty
...
MyGenericScripts
Debug
Extensions
Framework
Graphics
IO
Math
...
MyGameScripts
Debug
Gameplay
Actors
Items
...
Framework
Graphics
GUI
...
17/31
19/08/13
BaseEditor<T> : Editor
where T : MonoBehaviour
{
override public void OnInspectorGUI()
{
T data = (T) target;
GUIContent label = new GUIContent();
label.text = "Properties"; //
DrawDefaultInspectors(label, data);
if(GUI.changed)
{
EditorUtility.SetDirty(target);
}
}
}
18/31
19/08/13
Note that it uses an annotation in your class code to generate a tooltip in the inspector.
In theory this step can be automated, but I have not tried it.
devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/
19/31
19/08/13
Tw eet
Me gusta
343
537
130
No related posts.
This entry was posted in Development and tagged best practices, unity on 12 July 2012
[http://devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/] by Herman Tulleken.
76 comments
Leave a message...
Best
Share
Community
David Goemans
2 months ago
Great list!
Just a pointer for #30:
If you have public variables, but don't want them accessible in the inspector, you can
add [HideInInspector] ( C# ) or @HideInInspector (JS) before the declaration.
Conversely, if you want variables to be set in the inspector, but invisible in public scope,
you can add [SerializeField] (C#) or @SerializeField.
5
Tim
Reply
Share
a year ago
This is probably the best Unity "tips" article I've ever read. Very informative! I came up
with a few questions while I was reading and was wondering if Herman, or any one else
had any comments/answers to my questions.
#4 - Any example projects, code examples, or direction on how to acheive this?
devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/
20/31
19/08/13
#26 - "Coroutines vs. state machines." Are you saying use Coroutines or State
Machines, but not both? Or, Deciding if you are going to create state machines through
the use of coroutines or if you are going to create state machines by some other
method?
In addition to #26. I'm really struggling trying to decide how I want manage state. I've
seen several good FSMs and then there are some who say don't both, just use
coroutines. Then I've seen a hybrid of both. Any thoughts/tips on this, or examples of
how you manage state on an object?
#27 I understand what you are trying to achieve and why, but I don't understand how
you are explaining to do it. Could I get a short example of how you are wrapping
Time.DeltaTime and Time.SinceLevelLoad?
#34 says "Dont use strings for anything other than displayed text". Do you not use
Tags at all? Aren't strings the only way to reference tags/layers through code?
Any feedback is greatly appreciated, Thanks!
3
Reply
Share
Herman Tullek en
> Tim
a year ago
Thanks Tim!
About #4. It's quite a big chunk of code. I will see and post some if it at some
stage. The basic idea is to split off data that needs to be saved into Serializable
classes, implement a common interface for Savable classes (that includes presaving and post-loading logic, for example, to copy transforms), then implement
methods that serialize and deserialize lists of your Savable objects [and do the
stuff necessary to link this data up to the actual game objects] (including
instantiating assets from Resources), and a method to clear Savables from the
scene. The save and load needs to work both run time and edit time. It is easier
to start getting things work runtime, and then specialize behaviour for edit time
(so reducing the risk of stuffing up scenes).
All in all, not worth it if your levels are simple, and you only have a few. It also
requires very clear thinking, otherwise everything can become real messy.
#26. Yes, deciding to use co-routines for states, vs a nice wrapped solution. We
use light weight state machines that transition on command; each object
maintains it's own. The main reason not to mix these (or other idioms on the
1
Tim
see more
Reply
Share
a year ago
Thanks for all the great information! You said " We use light weight state
machines that transition on command" could you give a quick snippet of
how your state machines work? Since there are endless ways to do
state machines I would like to see one that someone has/is using within
devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/
21/31
19/08/13
B arrie Treloar
Reply
Share
4 months ago
Can you elaborate on point "34. Dont use strings for anything other than displayed text."
What should use for identifying objects?
2
Reply
Share
weez z
2 months ago
.Net strings allocate memory each time you instance them or modify them
Reply
Iowas k a
Share
2 months ago
B runo
Reply
Share
3 months ago
A mir A biri
Reply
Share
8 months ago
Reply
Chris A my ot
Share
10 months ago
First of all - thank you for this GREAT article. I've been using the pattern you've
described in #'s 32 and 37, using serializable non-monobehavior classes to
encapsulate groups of variables. I'm relatively new to C#, so you kind of blew my mind
there.
While using this technique in Unity, I came to a stumbling block - copy/pasting the code
from either of those examples provided the error:
"Assets/Scripts/TestClass.cs(9,2): error CS0246: The type or namespace name
`Serializable' could not be found. Are you missing a using directive or an assembly
reference?"
The fix I found for this is to use [System.Serializable] instead of [Serializable] - not sure
if there's a better way of doing this..?
Also - it's worth noting that you must include the [System.Serializable] attribute above
devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/
22/31
19/08/13
Also - it's worth noting that you must include the [System.Serializable] attribute above
any class declaration that you want to show up in your inspector.
Thanks again Herman - this is exactly the kind of resource I'd been looking for!
1
Reply
Share
Chris A my ot
10 months ago
Actually - just realized that if I included "using System;" at the top of my CS file I
could use [Serializable] instead of [System.Serializable]. It seems to me (as a
newcomer to C#), that including the System namespace in your classes would
bring in a lot of unnecessary functionality.. Is this not the case? Is the compiler
smart enough to include only the required functionality from that namespace?
3
Reply
Share
A mir A biri
8 months ago
Farrell
Reply
Share
14 days ago
This is awesome. I'm a veteran game developer, but new to Unity. There were some
really nice tips.
am
Reply
Share
25 days ago
Could you provide an example for point 31? I think there is some tight coupling in Unity
that makes modifying state of an object update it on screen automatically. Especially
when using physics. In your example where you modify the player velocity, if you do that
on a rigidbody in unity you'll move the object. Or do you mean that you should have:
controller - code which calls something like Input.GetAxis and then calls a method on
the model/game logic. i.e. like Move(Vector3 inputDirection).
model/game logic - updates the player direction and velocity in the model class, but
doesn't touch the rigidBody or anything to actually move it. Then using some sort of
event manager possibly send out a notification message for this?
devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/
23/31
19/08/13
view/interface : Looks up the new velocity from the model code and just modifies the
physics velocity on the rigid body. Also may change the direction sprite or rotation of the
3d model?
Would you typically make this in one monobehavior script? Or multiple?
There is a logical order that things must happen.
Get the input - A MonoBehaviour class which gets the input
see more
Reply
Share
a month ago
Reply
Share
2 months ago
FANTASTIC Overview. So when we open a new project and import any Unity
Technologies package and the only folder organization enforced is an 'Assets' folder
with a subfolder of 'Standard Assets'. What about our custom assets?
Here is the SOLUTION. What Unity Folder Structure Do you Use? - http://bit.ly/1b7cLyq
-Sam!
t hak k
Reply
Share
3 months ago
Reply
Share
Mario A z evedo
> thakk
2 months ago
Reply
Share
Charles InCharge
2 months ago
It is more of a problem when debugging in the scene view. Lets say you
put all your spawns in a spawns folder so you don't clutter the hierarchy.
If you call them "DarkVampire" and "MrVampire", then your vampires are
going to be all over the list. You could add a logic code to your spawning
code though and have it create the empty game object folders at run
time. That way your scene view would have "Spawns\Vampires\
[Dark,Mr]". You could then put all that in an #if UNITY_EDITOR block so
your performance isn't even remotely hit.
1
Reply
devmag
Share
Mod
> CharlesInCharge
a month ago
24/31
19/08/13
A milia Jones
Reply
Share
3 months ago
This article is great, but the part I was most excited about is the part with which I'm
having the most difficulty. The code in "How to Re-implement Inspector Drawing" looks
great, but I'm not sure how to actually set this up in a cs file. I've tried, but I get many
errors no matter what I seem to do.
Flavio
Reply
Share
3 months ago
Reply
Share
4 months ago
Bookmarked so hard. I am completely new to Unity but far from new in Game
development in general. This is just the type of guide I needed to get started. Thank you
so very much!
If I had a suggestion for an improvement I would recommend putting in a single
sentence for all the folders in the folder structure detailing what they contain. But I bet
it's obvious if you have been using Unity for any period of time.
c aue
Reply
Share
4 months ago
I'm not sure I follow what you mean on steps 1, 2 and 30.
1. By "branch" you mean just having an asset backup copy outside of the repository? If
so, I completely agree - this should never be done.
2. By second copy, you basically mean having the whole project with its compiled
library at hand? That makes a lot of sense, but then why not also enforcing the
repository usage on the rule? I don't see why that's not included.
30. Why not simply using [System.NonSerialized] to hide public parameters from the
inspector?
Additionally, I'd advice using POedit for dealing with text languages, on the tip #39:
http://wiki.unity3d.com/index....
Fucking awesome list, by the way. Kinda sad it's good being that big... Hope Unity can
"fix" most of it soon enough, though I couldn't bother taking note of how many here are
things Unity could "fix". :-)
Reply
Share
devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/
25/31
19/08/13
Reply
Share
devmag
Mod
> caue
a month ago
1. By branch I mean making any duplicate that is not the *actual working* one
(not made through a formal version controlled branching process). This occurs
frequently when programmers or artists work on complicated prefabs or
gameObjects and are scared that they will break something. Although notbreaking-anything is a noble pursuit, the wrong version almost *always* come
and confuse the hell out of somebody, wasting many hours.
2. Yup, that is what I mean. On some projects version control is not used, in
which case the rule does not apply. (I don't recommend going without version
control of course).
30. Yes, the "on a rare occasion" part of that rule is really rare (I have not had
the need for it for over a year now). I like the extremely ugly name for something
that is also extremely ugly in itself. For me, a public variable _means_ it is a
tweakable. So if I am not in the class, I treat it as something that should not be
modified. The double underscore signifies something fishy is going on, and puts
the programmer on alert. Of course, if for you public means public in the
traditional sense, then simply using the annotation is perfectly fine. In either
event, it really should be very rare, and is in itself not so important compared to
the main part of the rule.
39. Thanks for the suggestion. I admit the solution I give is a bit poor-man-style.
Thanks for the feedback; it's very interesting to hear other's take on these
points.
1
Reply
c aue
Share
> devmag
a month ago
Thank you for the post! I'm trying to apply several of the rules here and
the prefabbing scene one helped a great deal already, for merging
scenes.
I just think you should enforce way more the "use version control" idea.
Even for 1 person minor projects free unity, just never go without a VCS.
I see both rules #1 and #2 exist because people aren't using it or are
using it poorly.
Reply
devmag
Share
Mod
> caue
a month ago
>
Reply
Mat t S c hoen
caue a month
devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/
Share
ago
26/31
19/08/13
Mat t S c hoen
> caue
We've actually just created a tool for this purpose and released it on the Asset
Store. Check it out:
https://www.assetstore.unity3d...
Reply
c aue
Share
a month ago
That sounds unreal! And seems like it even works with git!
I hate the Asset Server, and I advice no one to ever use it (in its current
form anyway). It's basically older than svn in terms of version control.
Just saying that because you do mention it twice on the documentation,
and seems like there is an issue with scene missing references and ID
mismatches in which you say AssetServer might be needed... No idea
what you meant there, but that might be because I haven't tried your tool.
The way I see it, a missing reference is missing. There's nothind to be
done there. Just report it's missing.
Rohit
Reply
Share
4 months ago
I found your tips very interesting. I have a problem. I made an object in Maya and
imported it into unity but the movement speed on device while testing is very slow. Can
you please tell me that whether is it fault with some maya fbx file or in Unity? I spent 2
days on this and reached nowhere. Please help. (Maya file is an office view)
Reply
Thomas
Share
5 months ago
Hey all,
I'm not able to recreate the steps from "How to Re-implement Inspector Drawing" into
final cs files. Could someone share that final or near work?
Thanks for this article !
Bye
Reply
Share
Mat t S c hoen
> Thomas
a month ago
This is a bit of a complicated answer (which I won't go into too deeply), but you
should look into SerializedProperty. Once you get a hang of the iterator pattern,
it makes re-creating the inspector a breeze!
W hit ebread
Reply
Share
5 months ago
I know this is a bit old at this point, but I had a question in regards to the MakeLabel
function. I am getting an error on field.Name.SplitCamelCase() saying that string does
not contain a definition for it. Is this defined somewhere else?
devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/
27/31
19/08/13
Jac ob
Reply
Share
7 months ago
Reply
t hallippoli
Share
8 months ago
Reply
Share
devmag
Mod
> thallippoli
8 months ago
Reply
t hallippoli
Share
> devmag
devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/
8 months ago
28/31
19/08/13
s hac har Oz
Reply
Share
9 months ago
excellent.
our team at Omek has learned not a few out of the 50 you wrote, so these tips are fully
supported by us too.
Reply
s hinriy o
Share
11 months ago
Reply
c aue
Share
> shinriyo
2 months ago
As reference for one way this could be done, and while not sure if this would be
a best practice, I've changed the singleton implementation for myself so we
don't need to manually attach it to an object (same way as DebugConsole
works). Here's just the part changed:
if (_instance == null)
{
GameObject singleton = new GameObject();
singleton.AddComponent<t>();
singleton.name = "(singleton) "+ typeof(T).ToString();
DontDestroyOnLoad(singleton);
_instance = FindObjectOfType( typeof(T) ) as T;
Debug.Log("[Singleton] An instance of " + typeof(T) +
" is needed in the scene, so '" + singleton +
"' was created.");
}
</t>
s hinriy o
Reply
Share
> shinriyo
11 months ago
Reply
Share
devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/
29/31
19/08/13
s hinriy o
11 months ago
Reply
Tim A idley
Share
11 months ago
Re #30, is there any reason why you wouldn't just use [HideInInspector] to prevent
someone playing with a public member variable?
Reply
Share
11 months ago
I've been trying to sort out the rewriting-custom-inspector jazz, but I can't make heads
of tails of it. When I try to enter the code as-is, much of it won't compile (for example,
due to the SplitCamelCase method present). Do the three methods listed here belong
under one common class (BaseEditor)?
I'm fairly new to Unity and to C# in general, and I can't sort it out! :(
Reply
Share
11 months ago
What are your thoughts on how Unity mingles assets and folders together in the Project
view? Do you think it's worthwhile to set up the folder hierarchy in such a way that there
are only ever folders *or* assets within a folder?
Reply
Share
Herman Tullek en
11 months ago
A dam Reed
Reply
Share
a year ago
Thanks for the tips especially the ones on the custom editor. I have one concern
though: I noticed that you did not use SerializedObject for your editor, is there a reason?
I have been planning on building a Editor base class that used reflection and the
SerializedPropertys to allow the flexibility I want and also the benefits from using
SerializedObject (prefab override, undo, multi editing etc) but I wonder if there is
somethingthat I am not aware of that made you decide not to in your example.
Thanks again for the wonderful tips.
devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/
30/31
19/08/13
Reply
Share
Herman Tullek en
a year ago
There is a reason, although not a very good one. I could not get it to work, or it
did not work as expected (or I wanted it to work). I started using it, but gave up at
some point. It would be nice if you can get it to work to post an example
somewhere.
Henning
Reply
Share
a year ago
Thank you SO much! As I'm new to Unity (12 days) and just putting the final tuchses on
my first Unity game. It's really nice to find some good solid guidelines/best practices.
Now I have a better grasp of what to do different for my next game, to make the
process a lot easier.
What is you input on GUI design.. After testing my game in different resolutions and
aspect ratios, I'm getting a serious urge to make all menus using Text Meshs instead of
using UnityGUI/Skin placement hell.
Thanks again.
Reply
Share
Herman Tullek en
> Henning
a year ago
A GUI is one of the few things that is almost in every game; I can't understand
why better systems has not been available for much longer. (At least the GUI
system in Unity 4 looks great).
We always use EZGUI, because Unity's build-in GUI framework is so slow (on
mobile it makes a huge difference). It has it's own sets of problems, but I think
overall it's a powerful system.
Reply
Share
C o m m e n t fe e d
Su b s cri b e vi a e m a i l
devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/
31/31