From 9eb20f21585019b217c6382736b4d9af5bc28e05 Mon Sep 17 00:00:00 2001
From: Bas de Reus <70578065+bas-boop@users.noreply.github.com>
Date: Fri, 29 Mar 2024 13:18:10 +0100
Subject: [PATCH 1/4] Create AssetNamingConventions.md
---
AssetNamingConventions.md | 218 ++++++++++++++++++++++++++++++++++++++
1 file changed, 218 insertions(+)
create mode 100644 AssetNamingConventions.md
diff --git a/AssetNamingConventions.md b/AssetNamingConventions.md
new file mode 100644
index 0000000..04bc5c1
--- /dev/null
+++ b/AssetNamingConventions.md
@@ -0,0 +1,218 @@
+Everything is typed in English.
+
+Most things are prefixed with the prefix generally being an acronym of the asset type followed by an underscore.
+
+`[AssetTypePrefix]_[AssetName]_[Descriptor]_[OptionalVariantLetterOrNumber]`
+
+* `AssetTypePrefix`identifies the type of Asset, refer to the table below for details.
+* `AssetName` is the Asset's name.
+* `Descriptor` provides additional context for the Asset, to help identify how it is used. For example, whether a texture is a normal map or an opacity map.
+* `OptionalVariantLetterOrNumber` is optionally used to differentiate between multiple versions or variations of an asset.
+
+------
+### Asset Prefixes
+
+This list is not exhaustive, as new features can require new Asset types. If you are using an Asset type not listed, use the existing list as a guideline for your naming convention for that Asset.
+
+Examples based on the contentions in the table below:
+
+* `M_Collectable`
+* `T_Collectable_Normal`
+
+------
+### Base Asset Name
+All assets should have a _Base Asset Name_. A Base Asset Name represents a logical grouping of related assets. Any asset that is part of this logical group
+should follow the the standard of `Prefix_BaseAssetName_Variant_Suffix`.
+
+Keeping the pattern `Prefix_BaseAssetName_Variant_Suffix` in mind and using common sense is generally enough to warrant good asset names. Here are some detailed rules regarding each element.
+
+`Prefix` and `Suffix` are to be determined by the asset type through the following [Asset Name Modifier](#asset-name-modifiers) tables.
+
+`BaseAssetName` should be determined by short and easily recognizable name related to the context of this group of assets. For example, if you had a character named Calvin, all of Calvin's assets would have the `BaseAssetName` of `Calvin`.
+
+For unique and specific variations of assets, `Variant` is either a short and easily recognizable name that represents logical grouping of assets that are a subset of an asset's base name. For example, if Calvin had multiple skins these skins should still use `Calvin` as the `BaseAssetName` but include a recognizable `Variant`. An 'Evil' skin would be referred to as `Calvin_Evil` and a 'Retro' skin would be referred to as `Calvin_Retro`.
+
+For unique but generic variations of assets, `Variant` is a two digit number starting at `01`. For example, if you have an environment artist generating nondescript rocks, they would be named `Rock_01`, `Rock_02`, `Rock_03`, etc. Except for rare exceptions, you should never require a three digit variant number. If you have more than 100 assets, you should consider organizing them with different base names or using multiple variant names.
+
+Depending on how your asset variants are made, you can chain together variant names. For example, if you are creating flooring assets for an Arch Viz project you should use the base name `Flooring` with chained variants such as `Flooring_Marble_01`, `Flooring_Maple_01`, `Flooring_Tile_Squares_01`.
+
+#### Examples
+
+##### Character
+
+| Asset Type | Asset Name |
+| ------------------------ | ------------ |
+| Skeletal Mesh | SK_Calvin |
+| Material | M_Calvin |
+| Texture (Diffuse/Albedo) | T_Calvin_D |
+| Texture (Normal) | T_Calvin_N |
+| Texture (Evil Diffuse) | T_Calvin_Evil_D |
+
+##### Prop
+
+| Asset Type | Asset Name |
+| ------------------------ | ------------ |
+| Static Mesh (01) | SM_Rock_01 |
+| Static Mesh (02) | SM_Rock_02 |
+| Static Mesh (03) | SM_Rock_03 |
+| Material | M_Rock |
+| Material Instance (Snow) | MI_Rock_Snow |
+
+------
+### Asset Name Modifiers
+
+When naming an asset use these tables to determine the prefix and suffix to use with an asset's [Base Asset Name](#base-asset-name).
+
+- [Most Common](#most-common)
+ - [FBX](#3d-models-fbx-files)
+ - [3ds](#3d-models-3ds-max-files)
+- [Animations](#animations)
+- [Artificial Intelligence](#artificial-intelligence)
+- [Prefabs](#prefabs)
+- [materials](#materials)
+- [Textures](#textures)
+ - [Texture Packing](#texture-packing)
+- [Miscellaneous](#miscellaneous)
+- [Physics](#physics)
+- [Audio](#audio)
+- [User Interface](#user-interface)
+- [Effects](#effects)
+
+#### Most Common
+
+| Asset Type | Prefix | Suffix | Notes |
+| ----------------------- | ---------- | ---------- |-------------------------------------------------------------------------------------------|
+| Level / Scene | * | | Should be in a folder called Scenes. e.g. `Scenes/ArtTest.unity` |
+| Level (Persistent) | | _P | |
+| Level (Audio) | | _Audio | |
+| Level (Lighting) | | _Lighting | |
+| Level (Geometry) | | _Geo | |
+| Level (Gameplay) | | _Gameplay | |
+| Prefab | | | |
+| Material | M_ | | |
+| Static Mesh | SM_ | | |
+| Skeletal Mesh | SK_ | | |
+| Texture | T_ | _? | See [Textures](#textures) |
+| Particle System | PS_ | | |
+
+#### 3D Models FBX Files
+
+PascalCase
+
+| Asset Type | Prefix | Suffix | Notes |
+| ------------- | ------ | ------ | ----- |
+| Characters | CH_ | | |
+| Vehicles | VH_ | | |
+| Weapons | WP_ | | |
+| Static Mesh | SM_ | | |
+| Skeletal Mesh | SK_ | | |
+| Skeleton | SKEL_ | | |
+| Rig | RIG_ | | |
+
+#### 3D Models 3ds Max Files
+
+All meshes in 3ds Max are lowercase to differentiate them from their FBX export.
+
+| Asset Type | Prefix | Suffix | Notes |
+| ------------- | ------ | ----------- | --------------------------------------- |
+| Mesh | | _mesh_lod0* | Only use LOD suffix if model uses LOD's |
+| Mesh Collider | | _collider | |
+
+#### Animations
+| Asset Type | Prefix | Suffix | Notes |
+| -------------------- | ------ | ------ | ----- |
+| Animation Clip | A_ | | |
+| Animation Controller | AC_ | | |
+| Avatar Mask | AM_ | | |
+| Morph Target | MT_ | | |
+
+#### Artificial Intelligence
+
+| Asset Type | Prefix | Suffix | Notes |
+| ----------------------- | ---------- | ---------- | -------------------------------- |
+| AI Controller | AIC_ | | |
+| Behavior Tree | BT_ | | |
+| Blackboard | BB_ | | |
+| Decorator | BTDecorator_ | | |
+| Service | BTService_ | | |
+| Task | BTTask_ | | |
+| Environment Query | EQS_ | | |
+| EnvQueryContext | EQS_ | Context | |
+
+#### Prefabs
+
+| Asset Type | Prefix | Suffix | Notes |
+| ----------------------- | ---------- | ---------- |-------|
+| Prefab | | | |
+| Prefab Instance | I | | |
+| Scriptable Object | | | |
+
+#### Materials
+| Asset Type | Prefix | Suffix | Notes |
+| ----------------- | ------ | ------ | ----- |
+| Material | M_ | | |
+| Material Instance | MI_ | | |
+| Physical Material | PM_ | | |
+
+#### Textures
+| Asset Type | Prefix | Suffix | Notes |
+| ----------------------- | ---------- | ---------- |--------------------------------|
+| Texture | T_ | | |
+| Texture (Diffuse/Albedo/Base Color)| T_ | _D | |
+| Texture (Normal) | T_ | _N | |
+| Texture (Metallic) | T_ | _MT | |
+| Texture (Height) | T_ | _H | |
+| Texture (Roughness) | T_ | _R | |
+| Texture (Alpha/Opacity) | T_ | _A | |
+| Texture (Ambient Occlusion) | T_ | _AO | |
+| Texture (Bump) | T_ | _B | |
+| Texture (Emissive) | T_ | _E | |
+| Texture (Mask) | T_ | _M | |
+| Texture (Specular) | T_ | _S | |
+| Texture (Packed) | T_ | _* | See notes below about packing |
+| Texture Cube | TC_ | | |
+| Media Texture | MT_ | | |
+| Render Target | RT_ | | |
+| Cube Render Target | RTC_ | | |
+| Texture Light Profile | TLP_ | | |
+
+##### Texture Packing
+It is common practice to pack multiple layers of texture data into one texture. An example of this is packing Emissive, Roughness, Ambient Occlusion together as the Red, Green, and Blue channels of a texture respectively. To determine the suffix, simply stack the given suffix letters from above together, e.g. `_ERO`.
+
+> It is generally acceptable to include an Alpha/Opacity layer in your Diffuse/Albedo's alpha channel and as this is common practice, adding `A` to the `_D` suffix is optional.
+
+Packing 4 channels of data into a texture (RGBA) is not recommended except for an Alpha/Opacity mask in the Diffuse/Albedo's alpha channel as a texture with an alpha channel incurs more overhead than one without.
+
+#### Miscellaneous
+
+| Asset Type | Prefix | Suffix | Notes |
+| ------------------------------- | ------ | ------ | ----- |
+| Universal Render Pipeline Asset | URP_ | | |
+| Post Process Volume Profile | PP_ | | |
+| User Interface | UI_ | | |
+
+#### Physics
+
+| Asset Type | Prefix | Suffix | Notes |
+| ----------------- | ------ | ------ | ----- |
+| Physical Material | PM_ | | |
+
+#### Audio
+
+| Asset Type | Prefix | Suffix | Notes |
+| -------------- | ------ | ------ | ------------------------------------------------------------ |
+| Audio Clip | A_ | | |
+| Audio Mixer | MIX_ | | |
+| Dialogue Voice | DV_ | | |
+| Audio Class | | | No prefix/suffix. Should be put in a folder called AudioClasses |
+
+#### User Interface
+| Asset Type | Prefix | Suffix | Notes |
+| ---------------- | ------ |--------| ----- |
+| Font | Font_ | | |
+| Texture (Sprite) | T_ | | |
+
+#### Effects
+| Asset Type | Prefix | Suffix | Notes |
+| --------------- | ------ | ------ | ----- |
+| Particle System | PS_ | | |
From 19f2c7d13020bed747fce0861231a8216ba62598 Mon Sep 17 00:00:00 2001
From: Bas de Reus <70578065+bas-boop@users.noreply.github.com>
Date: Fri, 29 Mar 2024 13:19:36 +0100
Subject: [PATCH 2/4] Create CodeConventions.md
---
CodeConventions.md | 595 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 595 insertions(+)
create mode 100644 CodeConventions.md
diff --git a/CodeConventions.md b/CodeConventions.md
new file mode 100644
index 0000000..1744e6d
--- /dev/null
+++ b/CodeConventions.md
@@ -0,0 +1,595 @@
+Team-swamp's Unity & C# code conventie. Everything is typed in the English languegue.
+
+Always try to make your code less [coupled](https://en.wikipedia.org/wiki/Coupling_(computer_programming)) / dependant on other code, and try to adhere to [SRP (Single Responsability Princple)](https://en.wikipedia.org/wiki/Single-responsibility_principle) doing so will prevent scripts from breaking entire systems if something breaks.
+Also try to make your code [DRY (Dont Repeat Yourself)](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself#:~:text=%22Don't%20repeat%20yourself%22,data%20normalization%20to%20avoid%20redundancy.)
+
+- [Namespaces](#namespaces)
+ - [Importing namespaces](#importing-namespaces)
+- [Classes](#classes)
+- [Functions](#functions)
+- [Variables](#variables)
+ - [Hungarian notation](#hungarian-notation)
+- [Structs](#structs)
+- [Enums](#enums)
+- [If statement](#if-statements)
+ - [Ternary operator](#ternary-operator)
+- [Loops](#loops)
+- [Scriptable object](#scriptable-object)
+- [Styling](#styling)
+ - [Namespaces](#namespaces-style)
+ - [Bracket Placement](#bracket-placement)
+ - [If statement and loop](#if-statement-and-loop)
+ - [Regions](#regions)
+
+------
+### Namespaces
+The namespace name is written in PascalCasing. The lines in the namespaces should should not exstend a chracter count of 120.
+Every class, scriptableObject and struct needs to be inside of a namespace.
+```cs
+namespace ExampleNamespace
+{
+ public class ExampleScript : MonoBehaviour
+ {
+
+ }
+}
+```
+```cs
+using UnityEngine;
+
+namespace ExampleNamespace.ScriptableObjects
+{
+ public class ExampleScriptableObject : ScriptableObject
+ {
+
+ }
+}
+```
+```cs
+using Systems;
+
+namespace ExampleNamespace
+{
+ public struct ExampleStruct
+ {
+
+ }
+}
+```
+
+#### Importing namespaces
+When using namespaces we put the default namespaces first then a white space followed by our namespaces.
+
+```cs
+using System;
+using System.Collections;
+using UnityEngine;
+
+using FrameWork;
+using FrameWork.Enums;
+using FrameWork.Extensions;
+using Player;
+```
+
+------
+### Classes
+The Class name is written in PascalCasing.
+If the function GetComponent is used to get a component from this gameObject you use RequireComponent above the class. I suggest using the 'sealed' and 'abstract' keywords to minmize confusion.
+```cs
+[RequireComponent(typeof(ExampleComponent))]
+public sealed class ExampleScript : MonoBehaviour
+{
+
+}
+
+public abstract class BaseExampleScript : MonoBehaviour
+{
+
+}
+
+public class NonBaseExampleScript : BaseExampleScript
+{
+
+}
+```
+
+Class members should be grouped into sections:
+
+- Constant Fields
+- Static Fields
+- Fields
+- Constructors
+- Properties
+- Events / Delegates
+- LifeCycle Methods (Awake, OnEnable, OnDisable, OnDestroy, IEnumerator)
+- Public Methods
+- Protected Methodes
+- Private Methods
+- Nested types
+
+Within each of these groups order by access:
+- public
+- serializedFields
+- internal
+- protected
+- private
+
+------
+### Functions
+All functions and events perform some form of action, whether its getting info, calculating data, or causing something to explode. Therefore, all functions should **start with verbs**. They should be worded in the present tense whenever possible. They should also have some context as to what they are doing.
+
+When writing a function that does not change the state of or modify any object and is purely for getting information, state, or computing a yes/no value, it should ask a question. This should also follow the verb rule.
+
+This is extremely important as if a question is not asked, it may be assumed that the function performs an action and is returning whether that action succeeded.
+
+The Function name is written in PascalCasing.
+```cs
+private void ExampleFunction()
+{
+
+}
+```
+
+**Access modifiers** are always written with functions.
+```cs
+void ExampleFunction()
+{
+ Debug.Log("Not allowed");
+}
+
+private void ExampleFunction()
+{
+ Debug.Log("I'm a private function.");
+}
+
+protected void ExampleFunction()
+{
+ Debug.Log("I'm a protected function.");
+}
+
+public void ExampleFunction()
+{
+ Debug.Log("I'm a public function.");
+}
+```
+
+**Public & protected functions** require a summary including the parameters and returns.
+```cs
+///
+/// Function description.
+///
+/// Parameter value to pass.
+/// What the function return.
+public int ExampleFunction(string parameter)
+{
+ Return 0;
+}
+
+///
+/// Function description.
+///
+protected void ExampleFunction()
+{
+ Debug.log("I am example!");
+}
+```
+
+When there is more than 2 parameter, we add this rule for readability. This does defeat the rule below.
+```cs
+// Good
+private void ExampleFunction(int firstNumber, int secondNumber)
+{
+
+}
+
+// Good
+private void ExampleFunction(
+ int firstNumber,
+ int secondNumber,
+ float numberWithComma,
+ ExampleComponent targetClass,
+ bool isTrue,
+ double funnyNumber)
+{
+
+}
+
+// Bad
+private void ExampleFunction(int firstNumber, int secondNumber, float numberWithComma, ExampleComponent targetClass, bool isTrue, double funnyNumber)
+{
+
+}
+```
+
+When there is only 1 line of code inside of an function you can use a lambda expresion.
+
+When the lambda expression is over the character limit of 120. You need to break-up the code in local variables.
+```cs
+public void ExampleFunction() => SecondExampleFunction();
+
+// with parameters
+public void ExampleFunction(
+ int firstNumber,
+ int secondNumber,
+ float numberWithComma,
+ ExampleComponent targetClass,
+ bool isTrue,
+ double funnyNumber)
+ => SecondExampleFunction();
+```
+
+------
+### Variables
+When writing a function that does not change the state of or modify any object and is purely for getting information, state, or computing a yes/no value, it should ask a question. This should also follow the verb rule.
+
+This is extremely important as if a question is not asked, it may be assumed that the function performs an action and is returning whether that action succeeded.
+
+A varbile is almost always private. If you need the value make a getter for it. This is also why serialized have a '_' exception.
+
+**Access modifiers** are always written with variables.
+```cs
+// Allowed
+private int _variableExample0;
+protected int p_variableExample1;
+public int variableExample2;
+
+// Not allowed
+int _variableExample3;
+```
+
+**Private variable** names always start with an '_' (Except when serialized) after which it is written in camelCasing. If the variable is accisable in the **Unity Inspector** and it's an int or float it needs the Range attribute.
+```cs
+private Object _variableExample;
+
+[SerializeField] private Object secondVariableExample;
+
+[SerializeField, Range(0, 10)] private int thirdVariableExample;
+
+[SerializeField, Range(0, 1)] private float fourthVariableExample;
+```
+
+**Public variable** names are written in camelCasing. If not a number, char, string or bool, it needs to has the Tooltip attribute.
+```cs
+[Tooltip("Explaination of this varible.")] public Object variableExample;
+```
+
+**Readonly variable** names are written the same as public variables so in camelCasing.
+```cs
+public readonly Object variableExample;
+```
+
+**Constant variable** names are written in FULL_CAPITALS with snake_casing.
+```cs
+public const int EXAMPLE_CONSTANT_VALUE;
+```
+
+**Internal variable** names always start with 'i_' after which it is written in camelCasing.
+```cs
+internal int i_variableExample;
+```
+
+**Protected variable** names always start with 'p_' after which it is written in camelCasing.
+```cs
+protected int p_variableExample;
+```
+
+**Internal & protected variable** names always start with 'pi_' after which it is written in camelCasing.
+```cs
+protected internal int pi_variableExample;
+```
+
+**Temporary variables** inside of an function always need to be written out and are written in camelCasing.
+```cs
+private void ExampleFunction()
+{
+ float temporaryFloat = 1f;
+ int temporaryInt = 1;
+ double temporaryDouble = 1.00;
+}
+```
+
+**Temporary constants** inside of an function always need to be written out and are written in FULL_CAPITALS with snake_casing.
+```cs
+private void ExampleFunction()
+{
+ const float TEMPORARY_FLOAT = 1f;
+ const int TEMPORARY_INT = 1;
+ const double TEMPORARY_DOUBLE = 1.00;
+}
+```
+
+**Property** names are written in PascalCasing.
+```cs
+public int ExampleInteger
+{
+ get => _exampleInterger;
+ set
+ {
+ if(value < 0) _exampleInterger = 0;
+ }
+}
+```
+#### Hungarian notation
+
+We don't do that here. It's crucial to note that Hungarian notation is considered a suboptimal practice in coding standards.
+
+```cs
+// good
+private int _targetAmount;
+private ExampleComponent _system;
+private ExampleStruct _currentStruct;
+
+//bad
+private int _intTargetAmount;
+private ExampleComponent _exampleComponetSystem;
+private ExampleStruct _exampleStructCurrentStruct;
+```
+This also apply to collections. They follow the same naming rules as mentioned before, but should be named as a plural noun.
+```
+// good
+'Enemies', `Targets` and `Hats`
+
+// bad
+'DictionaryEnemies', `TargetList` and `HatArray`
+```
+
+------
+### Structs
+The struct name is written in PascalCasing and everything inside the struct follows the usual code conventions.
+```cs
+public struct ExampleStruct
+{
+ public double x;
+ public double y;
+}
+```
+
+------
+### Enums
+The enum name is written in PascalCasing while the constants are in FULL_CAPITALS with snake_casing.
+```cs
+enum ExampleEnum
+{
+ FIRST_CONSTANT,
+ SECOND_CONSTANT
+}
+```
+Always have the default type at the top.
+
+```cs
+enum CookedState
+{
+ NONE,
+ RAW,
+ COOKED
+}
+```
+
+------
+### If statements
+When there is only 1 line of code after an if statement it comes right after it and same with the else.
+```cs
+if (_exampleBoolean)
+ ExampleFunction();
+else
+ SeccondExampleFunction();
+
+if (_exampleBoolean)
+ return;
+```
+
+If either the if or the else in the statement contains multiple lines of code, the if and the else do not need brackets both.
+```cs
+if (_exampleBoolean)
+ ExampleFunction();
+else
+{
+ SeccondExampleFunction();
+ ThirdExampleFunction();
+}
+```
+
+When the condition has multiple condtions, make new lines for it.
+```cs
+// bad example
+if (_exampleBoolean && 0 == 0 || true)
+ ExampleFunction();
+
+// good example
+if (_exampleBoolean
+ && 0 == 0
+ || true)
+ ExampleFunction();
+
+// good example
+if (_exampleBoolean && _otherExampleBoolean
+ || true)
+ ExampleFunction();
+
+// also good example
+bool canBeCalled = _exampleBoolean && 0 == 0 || true;
+if (canBeCallled)
+ ExampleFunction();
+```
+
+##### ternary operator
+I highly recommand ternary operators when dynamicly change 1 varible. Also a note, don't make them to big, no ternary operator in ternary operator.
+```cs
+// bad example
+if (_exampleBoolean)
+ _exampleFloat = 1;
+else
+ _exampleFloat = 69;
+
+// good example
+_exampleFloat = _exampleBoolean ? 1 : 69;
+```
+
+------
+### Loops
+For better performance (even very small) we make the length it's own (local)varible.
+```cs
+int listLength = _exampleList.Length;
+
+for (int i = 0; i < listLength; i++)
+{
+
+}
+```
+
+------
+### Scriptable object
+Scriptable objects holds data and/or settings, this needs to be reflected in the name. Do not forget the CreateAssetMenu attribute and put it in the correct namespace.
+```cs
+[CreateAssetMenu(fileName = "NewGunData", menuName = "Gun Data")]
+public sealed class GunData : ScriptableObject
+{
+ private int _maxAmmoAmount;
+ public int currentAmmoAmount;
+
+ public void ResetAmmoAmount() => currentAmmoAmount = _maxAmmoAmount;
+ public int MaxAmmoAmount() => _maxAmmoAmount;
+}
+```
+
+Just in case, here is a bad way to make an scriptable object.
+```cs
+[CreateAssetMenu(fileName = "ScriptableObject / Song info")]
+public sealed class SongInfo : ScriptableObject
+{
+ [field: SerializeField, Tooltip("This is the MP3 file that should play")] public AudioClip Song { get; private set; }
+ [field: SerializeField, Tooltip("The person who made the song")] public string Artist { get; private set; }
+
+ [Serializable] public struct LyricNode
+ {
+ [field: SerializeField, TextArea(5, 50)] public string TextPart { get; private set; }
+ [field: SerializeField, Tooltip("The delay till the next lyric node")] public float TimeStamp { get; private set; }
+ [field: SerializeField, Range(0.05f, 1f)] public float Speed { get; private set; }
+ }
+ [field: SerializeField] public LyricNode[] Nodes { get; private set; }
+}
+```
+
+------
+### Styling
+Code style is a personal preference. It is needed for a group project, so here is a style that we use.
+
+Want to look at a [class with good code style](https://github.com/Team-Swamp/IceBites/blob/develop/Assets/Scripts/Framework/SceneSwitcher.cs)?
+
+#### Namespaces style
+There needs to be line between the namespaces in use and the current namespace.
+```cs
+using System;
+using System.Collections;
+using FrameWork.Extensions;
+using UnityEngine;
+using UnityEngine.Events;
+
+namespace Framework {}
+```
+
+#### Bracket placement
+A good usage of brackets:
+```cs
+namespace ExampleNamespace
+{
+ public class ExampleScript : MonoBehaviour
+ {
+ private void ExampleMethod()
+ {
+
+ }
+ }
+}
+```
+A bad usage of brackets:
+```cs
+namespace ExampleNamespace{
+ public class ExampleScript : MonoBehaviour{
+ private void ExampleMethod(){
+
+
+} }
+
+
+}
+```
+
+#### If statement and loop
+Around an if and loop there needs to be an empty line above and below.
+```cs
+float exampleFloat;
+
+if (_exampleBoolean)
+ exampleFloat = 1;
+
+ExampleMethod(exampleFloat);
+```
+```cs
+int listLength = _exampleList.Length;
+
+for (int i = 0; i < listLength; i++)
+{
+ Debug.LogError($"Item {listLenght} is {_exampleList[listLength].name}.");
+}
+
+ExampleMethod();
+```
+
+#### Regions
+A region has a line between its content.
+```cs
+#region Private variables
+
+private int _targetAmount;
+private ExampleComponent _system;
+private ExampleStruct _currentStruct;
+
+#endregion
+```
+```cs
+#region Public functions
+
+public void ExampleMethod()
+{
+ Debug.Log("Example")
+}
+
+#endregion
+```
+
+#### Functions
+Have a line in between functions. This is how it should be done:
+```cs
+///
+/// Function description.
+///
+/// Parameter value to pass.
+/// What the function return.
+public int ExampleFunction(string parameter)
+{
+ Return 0;
+}
+
+private void ExampleFunction()
+{
+ Debug.log("I am example!");
+}
+```
+Not like this:
+
+```cs
+///
+/// Function description.
+///
+/// Parameter value to pass.
+/// What the function return.
+public int ExampleFunction(string parameter)
+{
+ Return 0;
+}
+private void ExampleFunction()
+{
+ Debug.log("I am example!");
+}
+```
From ea8cf2432b70a806f93525c5d383b3435e21429e Mon Sep 17 00:00:00 2001
From: Bas de Reus <70578065+bas-boop@users.noreply.github.com>
Date: Fri, 29 Mar 2024 13:24:17 +0100
Subject: [PATCH 3/4] Chnaged readme to a home page
---
README.md | 599 +-----------------------------------------------------
1 file changed, 4 insertions(+), 595 deletions(-)
diff --git a/README.md b/README.md
index 36b8200..3ff3838 100644
--- a/README.md
+++ b/README.md
@@ -1,597 +1,6 @@
-# unity-code-convention
+# Teaw-Swamp conventions
-Team-swamp's Unity & C# code conventie. Everything is typed in the English languegue.
+These following files are some conventions we have decided on.
-Always try to make your code less [coupled](https://en.wikipedia.org/wiki/Coupling_(computer_programming)) / dependant on other code, and try to adhere to [SRP (Single Responsability Princple)](https://en.wikipedia.org/wiki/Single-responsibility_principle) doing so will prevent scripts from breaking entire systems if something breaks.
-Also try to make your code [DRY (Dont Repeat Yourself)](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself#:~:text=%22Don't%20repeat%20yourself%22,data%20normalization%20to%20avoid%20redundancy.)
-
-- [Namespaces](#namespaces)
- - [Importing namespaces](#importing-namespaces)
-- [Classes](#classes)
-- [Functions](#functions)
-- [Variables](#variables)
- - [Hungarian notation](#hungarian-notation)
-- [Structs](#structs)
-- [Enums](#enums)
-- [If statement](#if-statements)
- - [Ternary operator](#ternary-operator)
-- [Loops](#loops)
-- [Scriptable object](#scriptable-object)
-- [Styling](#styling)
- - [Namespaces](#namespaces-style)
- - [Bracket Placement](#bracket-placement)
- - [If statement and loop](#if-statement-and-loop)
- - [Regions](#regions)
-
-------
-### Namespaces
-The namespace name is written in PascalCasing. The lines in the namespaces should should not exstend a chracter count of 120.
-Every class, scriptableObject and struct needs to be inside of a namespace.
-```cs
-namespace ExampleNamespace
-{
- public class ExampleScript : MonoBehaviour
- {
-
- }
-}
-```
-```cs
-using UnityEngine;
-
-namespace ExampleNamespace.ScriptableObjects
-{
- public class ExampleScriptableObject : ScriptableObject
- {
-
- }
-}
-```
-```cs
-using Systems;
-
-namespace ExampleNamespace
-{
- public struct ExampleStruct
- {
-
- }
-}
-```
-
-#### Importing namespaces
-When using namespaces we put the default namespaces first then a white space followed by our namespaces.
-
-```cs
-using System;
-using System.Collections;
-using UnityEngine;
-
-using FrameWork;
-using FrameWork.Enums;
-using FrameWork.Extensions;
-using Player;
-```
-
-------
-### Classes
-The Class name is written in PascalCasing.
-If the function GetComponent is used to get a component from this gameObject you use RequireComponent above the class. I suggest using the 'sealed' and 'abstract' keywords to minmize confusion.
-```cs
-[RequireComponent(typeof(ExampleComponent))]
-public sealed class ExampleScript : MonoBehaviour
-{
-
-}
-
-public abstract class BaseExampleScript : MonoBehaviour
-{
-
-}
-
-public class NonBaseExampleScript : BaseExampleScript
-{
-
-}
-```
-
-Class members should be grouped into sections:
-
-- Constant Fields
-- Static Fields
-- Fields
-- Constructors
-- Properties
-- Events / Delegates
-- LifeCycle Methods (Awake, OnEnable, OnDisable, OnDestroy, IEnumerator)
-- Public Methods
-- Protected Methodes
-- Private Methods
-- Nested types
-
-Within each of these groups order by access:
-- public
-- serializedFields
-- internal
-- protected
-- private
-
-------
-### Functions
-All functions and events perform some form of action, whether its getting info, calculating data, or causing something to explode. Therefore, all functions should **start with verbs**. They should be worded in the present tense whenever possible. They should also have some context as to what they are doing.
-
-When writing a function that does not change the state of or modify any object and is purely for getting information, state, or computing a yes/no value, it should ask a question. This should also follow the verb rule.
-
-This is extremely important as if a question is not asked, it may be assumed that the function performs an action and is returning whether that action succeeded.
-
-The Function name is written in PascalCasing.
-```cs
-private void ExampleFunction()
-{
-
-}
-```
-
-**Access modifiers** are always written with functions.
-```cs
-void ExampleFunction()
-{
- Debug.Log("Not allowed");
-}
-
-private void ExampleFunction()
-{
- Debug.Log("I'm a private function.");
-}
-
-protected void ExampleFunction()
-{
- Debug.Log("I'm a protected function.");
-}
-
-public void ExampleFunction()
-{
- Debug.Log("I'm a public function.");
-}
-```
-
-**Public & protected functions** require a summary including the parameters and returns.
-```cs
-///
-/// Function description.
-///
-/// Parameter value to pass.
-/// What the function return.
-public int ExampleFunction(string parameter)
-{
- Return 0;
-}
-
-///
-/// Function description.
-///
-protected void ExampleFunction()
-{
- Debug.log("I am example!");
-}
-```
-
-When there is more than 2 parameter, we add this rule for readability. This does defeat the rule below.
-```cs
-// Good
-private void ExampleFunction(int firstNumber, int secondNumber)
-{
-
-}
-
-// Good
-private void ExampleFunction(
- int firstNumber,
- int secondNumber,
- float numberWithComma,
- ExampleComponent targetClass,
- bool isTrue,
- double funnyNumber)
-{
-
-}
-
-// Bad
-private void ExampleFunction(int firstNumber, int secondNumber, float numberWithComma, ExampleComponent targetClass, bool isTrue, double funnyNumber)
-{
-
-}
-```
-
-When there is only 1 line of code inside of an function you can use a lambda expresion.
-
-When the lambda expression is over the character limit of 120. You need to break-up the code in local variables.
-```cs
-public void ExampleFunction() => SecondExampleFunction();
-
-// with parameters
-public void ExampleFunction(
- int firstNumber,
- int secondNumber,
- float numberWithComma,
- ExampleComponent targetClass,
- bool isTrue,
- double funnyNumber)
- => SecondExampleFunction();
-```
-
-------
-### Variables
-When writing a function that does not change the state of or modify any object and is purely for getting information, state, or computing a yes/no value, it should ask a question. This should also follow the verb rule.
-
-This is extremely important as if a question is not asked, it may be assumed that the function performs an action and is returning whether that action succeeded.
-
-A varbile is almost always private. If you need the value make a getter for it. This is also why serialized have a '_' exception.
-
-**Access modifiers** are always written with variables.
-```cs
-// Allowed
-private int _variableExample0;
-protected int p_variableExample1;
-public int variableExample2;
-
-// Not allowed
-int _variableExample3;
-```
-
-**Private variable** names always start with an '_' (Except when serialized) after which it is written in camelCasing. If the variable is accisable in the **Unity Inspector** and it's an int or float it needs the Range attribute.
-```cs
-private Object _variableExample;
-
-[SerializeField] private Object secondVariableExample;
-
-[SerializeField, Range(0, 10)] private int thirdVariableExample;
-
-[SerializeField, Range(0, 1)] private float fourthVariableExample;
-```
-
-**Public variable** names are written in camelCasing. If not a number, char, string or bool, it needs to has the Tooltip attribute.
-```cs
-[Tooltip("Explaination of this varible.")] public Object variableExample;
-```
-
-**Readonly variable** names are written the same as public variables so in camelCasing.
-```cs
-public readonly Object variableExample;
-```
-
-**Constant variable** names are written in FULL_CAPITALS with snake_casing.
-```cs
-public const int EXAMPLE_CONSTANT_VALUE;
-```
-
-**Internal variable** names always start with 'i_' after which it is written in camelCasing.
-```cs
-internal int i_variableExample;
-```
-
-**Protected variable** names always start with 'p_' after which it is written in camelCasing.
-```cs
-protected int p_variableExample;
-```
-
-**Internal & protected variable** names always start with 'pi_' after which it is written in camelCasing.
-```cs
-protected internal int pi_variableExample;
-```
-
-**Temporary variables** inside of an function always need to be written out and are written in camelCasing.
-```cs
-private void ExampleFunction()
-{
- float temporaryFloat = 1f;
- int temporaryInt = 1;
- double temporaryDouble = 1.00;
-}
-```
-
-**Temporary constants** inside of an function always need to be written out and are written in FULL_CAPITALS with snake_casing.
-```cs
-private void ExampleFunction()
-{
- const float TEMPORARY_FLOAT = 1f;
- const int TEMPORARY_INT = 1;
- const double TEMPORARY_DOUBLE = 1.00;
-}
-```
-
-**Property** names are written in PascalCasing.
-```cs
-public int ExampleInteger
-{
- get => _exampleInterger;
- set
- {
- if(value < 0) _exampleInterger = 0;
- }
-}
-```
-#### Hungarian notation
-
-We don't do that here. It's crucial to note that Hungarian notation is considered a suboptimal practice in coding standards.
-
-```cs
-// good
-private int _targetAmount;
-private ExampleComponent _system;
-private ExampleStruct _currentStruct;
-
-//bad
-private int _intTargetAmount;
-private ExampleComponent _exampleComponetSystem;
-private ExampleStruct _exampleStructCurrentStruct;
-```
-This also apply to collections. They follow the same naming rules as mentioned before, but should be named as a plural noun.
-```
-// good
-'Enemies', `Targets` and `Hats`
-
-// bad
-'DictionaryEnemies', `TargetList` and `HatArray`
-```
-
-------
-### Structs
-The struct name is written in PascalCasing and everything inside the struct follows the usual code conventions.
-```cs
-public struct ExampleStruct
-{
- public double x;
- public double y;
-}
-```
-
-------
-### Enums
-The enum name is written in PascalCasing while the constants are in FULL_CAPITALS with snake_casing.
-```cs
-enum ExampleEnum
-{
- FIRST_CONSTANT,
- SECOND_CONSTANT
-}
-```
-Always have the default type at the top.
-
-```cs
-enum CookedState
-{
- NONE,
- RAW,
- COOKED
-}
-```
-
-------
-### If statements
-When there is only 1 line of code after an if statement it comes right after it and same with the else.
-```cs
-if (_exampleBoolean)
- ExampleFunction();
-else
- SeccondExampleFunction();
-
-if (_exampleBoolean)
- return;
-```
-
-If either the if or the else in the statement contains multiple lines of code, the if and the else do not need brackets both.
-```cs
-if (_exampleBoolean)
- ExampleFunction();
-else
-{
- SeccondExampleFunction();
- ThirdExampleFunction();
-}
-```
-
-When the condition has multiple condtions, make new lines for it.
-```cs
-// bad example
-if (_exampleBoolean && 0 == 0 || true)
- ExampleFunction();
-
-// good example
-if (_exampleBoolean
- && 0 == 0
- || true)
- ExampleFunction();
-
-// good example
-if (_exampleBoolean && _otherExampleBoolean
- || true)
- ExampleFunction();
-
-// also good example
-bool canBeCalled = _exampleBoolean && 0 == 0 || true;
-if (canBeCallled)
- ExampleFunction();
-```
-
-##### ternary operator
-I highly recommand ternary operators when dynamicly change 1 varible. Also a note, don't make them to big, no ternary operator in ternary operator.
-```cs
-// bad example
-if (_exampleBoolean)
- _exampleFloat = 1;
-else
- _exampleFloat = 69;
-
-// good example
-_exampleFloat = _exampleBoolean ? 1 : 69;
-```
-
-------
-### Loops
-For better performance (even very small) we make the length it's own (local)varible.
-```cs
-int listLength = _exampleList.Length;
-
-for (int i = 0; i < listLength; i++)
-{
-
-}
-```
-
-------
-### Scriptable object
-Scriptable objects holds data and/or settings, this needs to be reflected in the name. Do not forget the CreateAssetMenu attribute and put it in the correct namespace.
-```cs
-[CreateAssetMenu(fileName = "NewGunData", menuName = "Gun Data")]
-public sealed class GunData : ScriptableObject
-{
- private int _maxAmmoAmount;
- public int currentAmmoAmount;
-
- public void ResetAmmoAmount() => currentAmmoAmount = _maxAmmoAmount;
- public int MaxAmmoAmount() => _maxAmmoAmount;
-}
-```
-
-Just in case, here is a bad way to make an scriptable object.
-```cs
-[CreateAssetMenu(fileName = "ScriptableObject / Song info")]
-public sealed class SongInfo : ScriptableObject
-{
- [field: SerializeField, Tooltip("This is the MP3 file that should play")] public AudioClip Song { get; private set; }
- [field: SerializeField, Tooltip("The person who made the song")] public string Artist { get; private set; }
-
- [Serializable] public struct LyricNode
- {
- [field: SerializeField, TextArea(5, 50)] public string TextPart { get; private set; }
- [field: SerializeField, Tooltip("The delay till the next lyric node")] public float TimeStamp { get; private set; }
- [field: SerializeField, Range(0.05f, 1f)] public float Speed { get; private set; }
- }
- [field: SerializeField] public LyricNode[] Nodes { get; private set; }
-}
-```
-
-------
-### Styling
-Code style is a personal preference. It is needed for a group project, so here is a style that we use.
-
-Want to look at a [class with good code style](https://github.com/Team-Swamp/IceBites/blob/develop/Assets/Scripts/Framework/SceneSwitcher.cs)?
-
-#### Namespaces style
-There needs to be line between the namespaces in use and the current namespace.
-```cs
-using System;
-using System.Collections;
-using FrameWork.Extensions;
-using UnityEngine;
-using UnityEngine.Events;
-
-namespace Framework {}
-```
-
-#### Bracket placement
-A good usage of brackets:
-```cs
-namespace ExampleNamespace
-{
- public class ExampleScript : MonoBehaviour
- {
- private void ExampleMethod()
- {
-
- }
- }
-}
-```
-A bad usage of brackets:
-```cs
-namespace ExampleNamespace{
- public class ExampleScript : MonoBehaviour{
- private void ExampleMethod(){
-
-
-} }
-
-
-}
-```
-
-#### If statement and loop
-Around an if and loop there needs to be an empty line above and below.
-```cs
-float exampleFloat;
-
-if (_exampleBoolean)
- exampleFloat = 1;
-
-ExampleMethod(exampleFloat);
-```
-```cs
-int listLength = _exampleList.Length;
-
-for (int i = 0; i < listLength; i++)
-{
- Debug.LogError($"Item {listLenght} is {_exampleList[listLength].name}.");
-}
-
-ExampleMethod();
-```
-
-#### Regions
-A region has a line between its content.
-```cs
-#region Private variables
-
-private int _targetAmount;
-private ExampleComponent _system;
-private ExampleStruct _currentStruct;
-
-#endregion
-```
-```cs
-#region Public functions
-
-public void ExampleMethod()
-{
- Debug.Log("Example")
-}
-
-#endregion
-```
-
-#### Functions
-Have a line in between functions. This is how it should be done:
-```cs
-///
-/// Function description.
-///
-/// Parameter value to pass.
-/// What the function return.
-public int ExampleFunction(string parameter)
-{
- Return 0;
-}
-
-private void ExampleFunction()
-{
- Debug.log("I am example!");
-}
-```
-Not like this:
-
-```cs
-///
-/// Function description.
-///
-/// Parameter value to pass.
-/// What the function return.
-public int ExampleFunction(string parameter)
-{
- Return 0;
-}
-private void ExampleFunction()
-{
- Debug.log("I am example!");
-}
-```
+* [Assets naming](https://github.com/Team-Swamp/conventions/blob/develop/AssetNamingConventions.md)
+* [Code](https://github.com/Team-Swamp/conventions/blob/develop/CodeConventions.md)
From cf70cba1cf323d2adeb541fd888b2f58d0791b6d Mon Sep 17 00:00:00 2001
From: Bas de Reus <70578065+bas-boop@users.noreply.github.com>
Date: Tue, 23 Apr 2024 21:32:41 +0200
Subject: [PATCH 4/4] Applied the feedback of @swzwij
---
AssetNamingConventions.md | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/AssetNamingConventions.md b/AssetNamingConventions.md
index 04bc5c1..1424fc1 100644
--- a/AssetNamingConventions.md
+++ b/AssetNamingConventions.md
@@ -1,6 +1,6 @@
Everything is typed in English.
-Most things are prefixed with the prefix generally being an acronym of the asset type followed by an underscore.
+Most assets are prefixed with an acronym representing the asset type, followed by an underscore.
`[AssetTypePrefix]_[AssetName]_[Descriptor]_[OptionalVariantLetterOrNumber]`
@@ -14,7 +14,7 @@ Most things are prefixed with the prefix generally being an acronym of the asset
This list is not exhaustive, as new features can require new Asset types. If you are using an Asset type not listed, use the existing list as a guideline for your naming convention for that Asset.
-Examples based on the contentions in the table below:
+Examples based on the contents in the table below:
* `M_Collectable`
* `T_Collectable_Normal`
@@ -22,9 +22,9 @@ Examples based on the contentions in the table below:
------
### Base Asset Name
All assets should have a _Base Asset Name_. A Base Asset Name represents a logical grouping of related assets. Any asset that is part of this logical group
-should follow the the standard of `Prefix_BaseAssetName_Variant_Suffix`.
+should follow the standard of `Prefix_BaseAssetName_Variant_Suffix`.
-Keeping the pattern `Prefix_BaseAssetName_Variant_Suffix` in mind and using common sense is generally enough to warrant good asset names. Here are some detailed rules regarding each element.
+Keeping the pattern `Prefix_BaseAssetName_Variant_Suffix` in mind and using common sense is generally enough to ensure good asset names. Here are some detailed rules regarding each element.
`Prefix` and `Suffix` are to be determined by the asset type through the following [Asset Name Modifier](#asset-name-modifiers) tables.
@@ -32,9 +32,9 @@ Keeping the pattern `Prefix_BaseAssetName_Variant_Suffix` in mind and using comm
For unique and specific variations of assets, `Variant` is either a short and easily recognizable name that represents logical grouping of assets that are a subset of an asset's base name. For example, if Calvin had multiple skins these skins should still use `Calvin` as the `BaseAssetName` but include a recognizable `Variant`. An 'Evil' skin would be referred to as `Calvin_Evil` and a 'Retro' skin would be referred to as `Calvin_Retro`.
-For unique but generic variations of assets, `Variant` is a two digit number starting at `01`. For example, if you have an environment artist generating nondescript rocks, they would be named `Rock_01`, `Rock_02`, `Rock_03`, etc. Except for rare exceptions, you should never require a three digit variant number. If you have more than 100 assets, you should consider organizing them with different base names or using multiple variant names.
+For unique but generic variations of assets, `Variant` is a two digit number starting at `01`. For example, if you have an environment artist generating nondescript rocks, they would be named `Rock_01`, `Rock_02`, `Rock_03`, etc. Except for rare exceptions, you should never require a three-digit variant number. If you have more than 100 assets, you should consider organizing them with different base names or using multiple variant names.
-Depending on how your asset variants are made, you can chain together variant names. For example, if you are creating flooring assets for an Arch Viz project you should use the base name `Flooring` with chained variants such as `Flooring_Marble_01`, `Flooring_Maple_01`, `Flooring_Tile_Squares_01`.
+Depending on how your asset variants are made, you can chain variant names together. For example, if you are creating flooring assets for an Arch Viz project you should use the base name `Flooring` with chained variants such as `Flooring_Marble_01`, `Flooring_Maple_01`, `Flooring_Tile_Squares_01`.
#### Examples
@@ -46,7 +46,7 @@ Depending on how your asset variants are made, you can chain together variant na
| Material | M_Calvin |
| Texture (Diffuse/Albedo) | T_Calvin_D |
| Texture (Normal) | T_Calvin_N |
-| Texture (Evil Diffuse) | T_Calvin_Evil_D |
+| Texture (Evil_Diffuse) | T_Calvin_Evil_D |
##### Prop
@@ -63,7 +63,7 @@ Depending on how your asset variants are made, you can chain together variant na
When naming an asset use these tables to determine the prefix and suffix to use with an asset's [Base Asset Name](#base-asset-name).
-- [Most Common](#most-common)
+- [Most Common Prefixes and Suffixes](#most-common-prefixes-and-suffixes)
- [FBX](#3d-models-fbx-files)
- [3ds](#3d-models-3ds-max-files)
- [Animations](#animations)
@@ -78,7 +78,7 @@ When naming an asset use these tables to determine the prefix and suffix to use
- [User Interface](#user-interface)
- [Effects](#effects)
-#### Most Common
+#### Most Common Prefixes and Suffixes
| Asset Type | Prefix | Suffix | Notes |
| ----------------------- | ---------- | ---------- |-------------------------------------------------------------------------------------------|
@@ -111,7 +111,7 @@ PascalCase
#### 3D Models 3ds Max Files
-All meshes in 3ds Max are lowercase to differentiate them from their FBX export.
+All meshes in 3ds Max are lowercase to differentiate them from their FBX exports.
| Asset Type | Prefix | Suffix | Notes |
| ------------- | ------ | ----------- | --------------------------------------- |
@@ -204,7 +204,7 @@ Packing 4 channels of data into a texture (RGBA) is not recommended except for a
| Audio Clip | A_ | | |
| Audio Mixer | MIX_ | | |
| Dialogue Voice | DV_ | | |
-| Audio Class | | | No prefix/suffix. Should be put in a folder called AudioClasses |
+| Audio Class | | | No prefix or suffix. Should be put in a folder called AudioClasses |
#### User Interface
| Asset Type | Prefix | Suffix | Notes |