Skip to content

Commit c115dd3

Browse files
authored
Update README.md
1 parent 4ba16b0 commit c115dd3

1 file changed

Lines changed: 56 additions & 63 deletions

File tree

README.md

Lines changed: 56 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -2,141 +2,134 @@
22

33
![](https://i0.wp.com/www.richardfu.net/wp-content/uploads/2020/10/Coding-Guideline-for-Unity-C.jpg)
44

5-
As a programmer, it is very important to follow a coding standard and make sure others can read and easily understand his code. While there’s not majority guideline of coding standard in Unity and C#, [you can/should code whatever you like](http://wiki.c2.com/?UncleBobOnCodingStandards), but in this article I’m going to show you our style and format guideline within the company. We have tried to adopt different styles throughout these years and came out the one we feel most comfortable.
5+
As a programmer, following a coding standard is crucial to ensure code readability and understandability. While Unity and C# lack a definitive coding standard, you have the [freedom to code as you prefer](http://wiki.c2.com/?UncleBobOnCodingStandards). In this article, we present our internal style and formatting guidelines developed over the years to create a comfortable coding environment.
66

7-
Our **3 golden rules** to forms our style standard:
8-
1. Follow Unitys style in [Scripting Reference](https://docs.unity3d.com/ScriptReference/)
9-
2. The rest follow Microsofts [C# Coding Conventions](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/inside-a-program/coding-conventions)
10-
3. Minor tweak where we believe that can make the code clearer
7+
Our **3 golden rules** shape our style standard:
8+
1. Adhere to Unity's style as described in the [Scripting Reference](https://docs.unity3d.com/ScriptReference/).
9+
2. Follow Microsoft's [C# Coding Conventions](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/inside-a-program/coding-conventions) for the rest.
10+
3. Implement minor tweaks to enhance code clarity.
1111

1212
#### Folder Structure
1313

14-
All similar files should be grouped in the root folders:
14+
Group similar files in root folders:
1515

1616
```
1717
Assets
1818
Animations Animation clips
19-
Editor Editor specified scripts, prefabs, etc
20-
Fonts Fonts used in game
19+
Editor Editor-specified scripts, prefabs, etc
20+
Fonts Fonts used in the game
2121
Materials Texture materials
2222
Prefabs In-game prefabs
2323
Resources Unity resources assets
2424
Scenes Scenes
25-
Scripts Code scripts, grouped in sub-folders
25+
Scripts Code scripts, organized in sub-folders
2626
Sounds Musics, sounds
27-
SweatyChair Company folder that share across projects
28-
(ModuleName1) Module name, e.g. DailyLogin
29-
(Scripts) Scripts within the module
30-
(Prefabs) Prefabs within the module
27+
<CompanName> Company folder shared across projects
28+
<ModuleName> Module name, e.g. DailyLogin
29+
Scripts Scripts within the module
30+
Prefabs Prefabs within the module
3131
... Other assets grouped in folders
3232
... Other modules
3333
Textures Image textures
3434
UI Texture used for UI
3535
Icons App icons
3636
```
3737

38-
> We have a `SweatyChair` folder, which containes a number of well-structure modules and sync across projects using Git [submodules](https://www.git-scm.com/book/en/v2/Git-Tools-Submodules). We we are always reuse the commond code and able to perform rapid prototyping.
38+
> We maintain a `<CompanyName>` folder containing well-structured modules that sync across projects using Git [submodules](https://www.git-scm.com/book/en/v2/Git-Tools-Submodules). This approach allows us to reuse common code and facilitate rapid prototyping.
3939
4040
#### File Naming
4141

42-
File naming is simple, always use Pascal Case except for images:
42+
File naming is straightforward, always use PascalCase except for images:
4343

44-
- Folders – PascalCase
45-
`FolderName`/
46-
- Images – hyphen-
47-
`image-name-64x64.jpg`
48-
- The rest – PascalCase
49-
`ScriptName.cs`, `PrefabName.prefab`, `SceneName.unity`
44+
- Folders use PascalCase: `FolderName`/
45+
- Images use hyphen naming: `image-name-64x64.jpg`
46+
- The rest uses PascalCase: `ScriptName.cs`, `PrefabName.prefab`, `SceneName.unity`
5047

51-
> The reason images use hyphen naming is that most images are also used in our website / press-kit. Hyphen naming is the majority naming convention for web image and it’s also [search engine friendly](https://www.natalleblas.com/optimise-images-for-seo/). Using the same name can save us time renaming and easily find the same image switching between Unity and web.
48+
> Images are often given hyphenated names because they are commonly used in both our website and press kit. Hyphenated naming is the prevailing convention for web images and is also favorable for [search engine optimization](https://www.natalleblas.com/optimise-images-for-seo/). Employing consistent names allows us to save time by avoiding the need for renaming and makes it effortless to locate the same image when transitioning between Unity and the web.
5249
5350
#### Scripts Naming
5451

55-
While each script has its unique purpose and use cases, we follow these naming rules and so we can still roughly know what the script is for by simply reading the filenames:
52+
Scripts follow specific naming rules to convey their purpose:
5653

57-
- `XxxPanel`, `XxxSlot`, `XxxButton`, etc for UI
54+
- `XxxPanel`, `XxxSlot`, `XxxButton`, etc for UI:
5855
`MenuPanel`, `AchievementSlot`, `CoinShopButton`
59-
- `XxxManager`, for master scripts that control specific workflow (only ONE instance in the scene)
56+
- `XxxManager`, for master scripts controlling specific workflows (only ONE instance in the scene):
6057
`DailyMissionManager`, `AchievementManager`
61-
- `XxxController`, for scripts controlling a game object (one or many in the scene)
58+
- `XxxController`, for scripts controlling a game object (one or many in the scene):
6259
`PlayerController`, `BossController`, `BackgroundControler`
63-
- `XxxDatabase`, for a database (e.g CSV) which contains a list of data rows
60+
- `XxxDatabase`, for a database (e.g. CSV) containing data rows:
6461
`WeaponDatabase`, `CardDatabase`
65-
- `XxxData`, for data row in a CSV database
62+
- `XxxData`, for data rows in a CSV database:
6663
`WeaponData`, `CardData`
67-
- `XxxItem`, for in-game item instance
64+
- `XxxItem`, for in-game item instances:
6865
`CardItem`, `CharacterItem`
69-
- `XxxGenerator`, for scripts instantiate GameObjects
66+
- `XxxGenerator`, for scripts instantiating GameObjects:
7067
`ObjectGenerator`, `LandGenerator`
71-
- `XxxSettings`, for settings scripts inherent Unitys [`ScriptableObject`](https://docs.unity3d.com/Manual/class-ScriptableObject.html) class
68+
- `XxxSettings`, for settings scripts inherent to Unity's [`ScriptableObject`](https://docs.unity3d.com/Manual/class-ScriptableObject.html) class:
7269
`AchievementSettings`, `DailyLoginSettings`
73-
- `XxxEditor`, for editor-only scripts inherent Unity’s `[Editor](https://docs.unity3d.com/ScriptReference/Editor.html)` class
70+
- `XxxEditor`, for editor-only scripts inherent to Unity’s `[Editor](https://docs.unity3d.com/ScriptReference/Editor.html)` class:
7471
`TutorialTaskEditor`, `AchievementSettingsEditor`
7572

76-
> Difference between `Manager` and `Controller` is `Manager` should be singleton or static, and it controls a specific game logic that may involve multiple objects and assets, while Controller controls an object and may have multiple instances. For example, there are multiple EnemyController in the scene and each control one enemy. We will discuss more on this in a singleton article.
73+
> The distinction between a `Manager` and a `Controller` lies in the fact that a Manager should typically be implemented as a singleton or static entity, overseeing specific game logic that may involve multiple objects and assets. In contrast, a `Controller` is responsible for governing an individual object and can have multiple instances. For instance, within a scene, there may be several `EnemyController`s, each managing a distinct enemy. We will delve deeper into this topic in an upcoming article dedicated to singletons.
7774
78-
> Difference between `Data` and `Item` is that `Item` is an instance in-game, and in most cases `Item` contains a `Data`. For example `CardData` has all preset attributes of a card, while `CardItem` has its `CardData` plus attributes that vary for different players, such as card level. We will talk about more this in another data structure article.
75+
> The differentiation between `Data` and `Item` is that an `Item` represents an in-game instance, and in most cases, it encapsulates a `Data` component. For example, `CardData` encompasses all the preset attributes of a card, while `CardItem` incorporates the `CardData` and additional attributes that vary for different players, such as the card's level. We will explore this concept further in another article focused on data structures.
7976
8077
#### Variable Naming
8178

82-
Similar to file naming, variable naming allow us to know what the variable is for without reading though all code:
79+
Variable naming uses camelCase to convey their purpose without needing to read through all the code:
8380

84-
- Use camcelCase, always as of a noun or in a form of (is/has)Abjective
85-
`hasRewarded`, `currentPosition`, `isInitialized`
86-
- Prefix with an underscore for private and protected variables
81+
- Prefix with an underscore for private and protected variables:
8782
`_itemCount`, `_controller`, `_titleText`
88-
- All capital letters for const
83+
- All capital letters for constants:
8984
`SHOW_SUB_MENU_LEVEL`, `MAX_HP_COUNT`, `BASE_DAMAGE`
90-
- All capital letters and PREFS_XXXX for PlayerPref keys
85+
- All capital letters as PREFS_XXXX for PlayerPref keys:
9186
`private const string PREFS_LAST_FREE_DRAW = “LastFreeDraw”;`
9287
`PlayerPrefs.GetInt(PREFS_LAST_FREE_DRAW)`
93-
- Use `xxxGO` for scene GameObject variables
88+
- Use `xxxGO` for scene GameObject variables:
9489
`optionButtonGO`, `backgroundMaskGO`
95-
- Use `xxxPrefab` for scene GameObject variables
90+
- Use `xxxPrefab` for scene GameObject variables:
9691
`weaponSlotPrefab`, `explosionPrefab`
97-
- Use `xxxTF` for Transform variables
92+
- Use `xxxTF` for Transform variables:
9893
`weaponTF`, `armTF`
99-
- Use `xxxComponent` for all other components, abbreviate if needed
94+
- Use `xxx<Component>` for all other components, abbreviated if necessary:
10095
`eyesSpriteRenderer` / `eyesSR`, `runAnimation` / `runAnim`, `attckAnimationClip` / `attackAC`, `victoryAudioClip` / `victoryAC`
101-
- Use xxxxs for arrays
96+
- Use xxxxs for arrays:
10297
`slotPrefabs = new Prefabs[0]`
10398
`achievementIds = new int [0]`
104-
- Use xxxxList for List and xxxxDict for Dictionary
99+
- Use xxxxList for `List` and xxxxDict for `Dictionary`:
105100
`weaponTransformList = new List()`
106101
`achievementProgressDict = new Dictionary()`
107-
- Use nounVerbed for callback event
102+
- Use nounVerbed for callback event:
108103
`public static event UnityAction gameStarted`
109104
`public static UnityAction characterDied`
110105

111-
> Unity use prefix `m_` for private/protected variables, and `s_` for static variables (see their [BitBucket](https://bitbucket.org/Unity-Technologies/assetbundlegraphtool/src/0e498d12964d7cd1b86728289ff6f8321d127db4/Runtime/AssetBundleBuildMap.cs)). We found that this makes the code very hard to read, so we leave one underscore for private/protected variables and keep it the same for both static and non-static variables.
106+
> In Unity, the convention for naming private/protected variables is to use the prefix `"m_"` and for static variables, `"s_"` (as indicated in their [BitBucket](https://bitbucket.org/Unity-Technologies/assetbundlegraphtool/src/0e498d12964d7cd1b86728289ff6f8321d127db4/Runtime/AssetBundleBuildMap.cs)). However, we've observed that this practice can make the code less readable. As a result, we have adopted a simplified approach by using a single underscore "_" for both private/protected and static variables to enhance code clarity.
112107
113108
> Callback event follow Unity’s event naming convention, e.g. `[SceneManager.activeSceneChanged](https://docs.unity3d.com/ScriptReference/SceneManagement.SceneManager-activeSceneChanged.html)`.
114109
115110
#### Functions Naming
116111

117-
- Use PascalCase, start with a verb and followed by a noun if needed
112+
- Functions use PascalCase, starting with a verb and followed by a noun if necessary:
118113
`Reward()`, `StartGame()`, `MoveToCenter()`
119-
- Use `OnXxxxClick`, for UI button clicks
114+
- Callback functions for UI button clicks are named as `OnXxxClick`:
120115
`OnStartClick()`, `OnCancelClick()`
121-
- Use `OnNounVerbed`, for callbacks
116+
- Callback functions use `OnNounVerbed`:
122117
`OnChestOpened()`, `OnBuyWeaponConfirmed()`
123118

124119
#### Member Properties
125120

126-
If a function has no input, use member property (aka get/set property) instead, in PacelCase as well:
127-
`bool IsRewarded() { }`
128-
to
121+
If a function has no input, use a member property (get/set property) in PascalCase:
129122
`bool IsRewarded {get { return …} }`
130-
Or even in a shortened form as
123+
Or
131124
`bool IsRewarded => ...;`
132125

133-
Also, use member properties where a variable can only set internally but can be accessed publicly:
126+
Member properties are used where a variable can only be set internally but accessed publicly:
134127
`public int Id { get; private set; }`
135128
`public Sprite IconSprite { get; private set; }`
136129

137130
#### Variables / Functions orders
138131

139-
Having a consistent order can greatly save our time on looking for a specific variable or function:
132+
Consistent order saves time searching for specific variables or functions. Here's the preferred order:
140133

141134
```
142135
MyCalss : Monobehavior
@@ -187,7 +180,7 @@ MyCalss : Monobehavior
187180
}
188181
```
189182

190-
You can also group valuables and functions in a region in large scripts (but not too large enough to be split into another script):
183+
You can also consider grouping variables and functions within a region in larger scripts, but ensure that the script remains manageable and doesn't become overly extensive, to the point where it should be split into multiple scripts. This can help improve code organization and readability.
191184

192185
```
193186
#region Timer
@@ -204,11 +197,11 @@ You can also group valuables and functions in a region in large scripts (but not
204197

205198
#### Code Formatting
206199

207-
We use **K&R** style which is already preset in Mac Visual Studio:
200+
We use **K&R** style, which is preset in Mac Visual Studio:
208201

209202
![](https://i1.wp.com/www.richardfu.net/wp-content/uploads/2020/10/KR-style-in-Mac-Visual-Studio.jpg?resize=1022%2C691&ssl=1)
210203

211-
While there’s not K&R in Windows (Why, Microsoft?), just a little bit effort to manually set few ticks:
204+
In Windows, you can manually configure it to match the K&R style:
212205

213206
![](https://i2.wp.com/www.richardfu.net/wp-content/uploads/2020/10/Windows-coding-format-1.jpg?resize=1024%2C173&ssl=1)
214207

@@ -220,7 +213,7 @@ While there’s not K&R in Windows (Why, Microsoft?), just a little bit effort t
220213

221214
#### Brackets and Newlines
222215

223-
For single-line conditional statements we do not need any brackets:
216+
For single-line conditional statements, no brackets are needed:
224217

225218
```
226219
if (1 == 1)
@@ -232,7 +225,7 @@ if (1 == 1) {
232225
}
233226
```
234227

235-
> Many developers, includes Unity, favourite putting newlines after open bracket ( `{` ). It may make the code looks more tidy and symmetric, but also creates a lot of unuseful lines and making script scrolling much more often and longer. Every bit count. If you spend 1 more second on scrolling a day, you probably wasted 5 minutes of valuable time a year.
228+
> Numerous developers, Unity included, have a preference for inserting newlines after an open bracket "{." While this practice can lend a sense of tidiness and symmetry to the code, it can also generate numerous unnecessary lines, leading to more frequent and longer script scrolling. Every bit of efficiency matters, as even spending an extra second on scrolling each day can add up to wasting five minutes of valuable time over the course of a year.
236229
237230
#### Comments
238231

@@ -245,4 +238,4 @@ Temporarily commenting out code should not include a space after the slashes, to
245238

246239
----------
247240

248-
That’s all. This may go bigger when you adopt more latest .Net syntax. There are also a few other good [guidelines](https://github.com/justinwasilenko/Unity-Style-Guide) if you want to read [more](http://www.arreverie.com/blogs/unity3d-best-practices-folder-structure-source-control/). Free feel to follow this style if you think it’s reasonable and helpful, so we may create a better game dev world where code is clean and please to read. 😀
241+
That concludes our coding guideline. It's worth noting that these guidelines may expand as you incorporate more recent .Net syntax. If you're interested in further best practices, there are additional valuable [guidelines](https://github.com/justinwasilenko/Unity-Style-Guide) to [explore](http://www.arreverie.com/blogs/unity3d-best-practices-folder-structure-source-control/). Feel free to embrace this coding style, as it promotes clean and readable code, contributing to the enhancement of the game development community. 😊

0 commit comments

Comments
 (0)