.gitignore for Unreal Engine

A simple .gitignore file when you work on Unreal Engine.
I exclude non-vital files generated by Unreal Engine with Visual Studio or Xcode, on Window and macOS.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# Unreal Generated Files
Binaries/*
Build/*
!Build/**/*.ico
Content/StarterContent/*
DerivatedDataCache/*
Intermediate/*
Saved/*
SourceArt/**/*.png
SourceArt/**/*.tga
 
# Visual Studio Generated Files
*.a
*.app
*.dll
*.dylib
*.exe
*.gch
*.ipa
*.la
*.lai
*.lib
*.lo
*.mod
*.o
*.obj
*.opensdf
*.out
*.pch
*.sdf
*.sln
*.slo
*.so
*.suo
*.VC.db
*.VC.opendb
.vs/*
 
# XCode Generated Files
contents.xcworkspacedata
*.xcodeproj
**/xcuserdata
 
# Windows
ehthumbs.db
ehthumbs_vista.db
Thumbs.db
 
# macOS
.apdisk
.AppleDB
.AppleDesktop
.AppleDouble
*.DS_Store
.LSOverride
Network Trash Folder
Temporary Items

Setup Visual Studio pour Unreal Engine

Toolbar

Tool > Customize > Onglet Commands > Toolbar > Standard

  • 200 pour Solution Configurations
  • 160 pour Solution Platforms

setup_vs_ue_1

Il faut que config, platform et debugger soient affichés sur la toolbar

Optimisations

Il faut passer par Tools > Options

Project And Solutions

Décocher “Always Show Error List if build finishes with errors”

Text Editor > C/C++ > View

Mettre à False “Show Inactive Blocks” (dans liste Inactive Code)

Text Editor > C/C++ > Advanced

Mettre à True “Disable External Dependencies Folder” (dans liste Browsing/Navigation)
Mettre à True “Auto Quick Info” (dans liste IntelliSense)
Mettre à False “Disable IntelliSense” (dans liste IntelliSense)
Mettre à False “Disable Auto Updating” (dans liste IntelliSense)
Mettre à False “Disable Error Reporting” (dans liste IntelliSense)
Mettre à False “Disable Quiggles” (dans liste IntelliSense)
Mettre à False “Disable IntelliSense” (dans liste IntelliSense)

Debugging

Décocher “Enable Edit and Continue”

Window Layout

Layout des fenêtres, ne garder que Solution Explorer, Output et le code.
Pour enregistrer la config Window > Save Window Layout

UnrealVS

  1. Double cliquer sur le fichier [UE4RootLocation]/Engine/Extras/UnrealVS/2015/UnrealVS.vsix
  2. Faire l’installation
  3. Ajouter à la toolbar le composant UnrealVS et enregistrer le layout

Symboles de débogage

  1. Copier le fichier [UE4Root]/Engine/Extras/VisualStudioDebugging/UE4.natvis
  2. Coller le fichier UE4.natvis dans les dossiers suivants :
    [VisualStudioInstallPath]/Common7/Packages/Debugger/Visualizers/UE4.natvis
    [UserProfile]/My Documents/Visual Studio 2015/Visualizers/UE4.natvis

Macro, UCLASS, UFFUNCTION, etc

  1. Aller sur https://marketplace.visualstudio.com/items?itemName=RxCompiLe.UE4Intellisense
  2. Cliquer sur donwload
  3. Installer le programme en double cliquant sur le fichier

Thread – Coder proprement

Un thread doit :
– respecter le principe de responsabilité unique
– limiter la portée des données
– utiliser des copies des données
– être aussi indépendants que possible
– utliser des api qui sont safe thread

Il existe des modèles d’exécution :
Ressources bornées
Ressources dont la taille ou le nombre est figé et qui sont employées dans un environnement concurrent. Il s’agit, par exemple, des connexions à une base de données ou des tampons de lecture/écriture de taille fixe.

Exclusion mutuelle
Un seul thread à la fois peut accéder à des données ou à des ressources partagées.

Famine
Un thread ou un groupe de threads est interdit de fonctionnement pendant une durée excessivement longue ou indéfiniment. Par exemple, si les threads d’exécution courte sont toujours privilégiés, les threads dont le traitement est plus long peuvent ne jamais être élus si les premiers ne se terminent pas.

Interblocage (deadlock)
Deux threads ou plus attendent chacun la fin de l’autre. Chaque thread dispose d’une ressource dont l’autre a besoin et aucun ne peut se terminer tant qu’il n’a pas obtenu la ressource de l’autre.

Interblocage actif (livelock)
Les threads sont synchrones, chacun tentant de faire son travail mais rencontrant toujours un autre thread “sur son chemin”. Un phénomène de résonance se crée et les threads tentent

Attention aux dépendances entre des méthodes synchronisées

Evitez d’utiliser plusieurs méthodes sur un objet partagé

Garder des sections synchronisées courtes

Il faut écrire le code d’arrêt pour se rendre compte des problèmes de locks entre threads

Pour tester du code multithread il faut :
– considérer les faux dysfonctionnements comme des problèmes potentiellement liés au multithread
– commencer par rendre le code normal (sans thread) opérationnel
– faire en sorte que le code multithread soit enfichable (utilisable dans différentes configurations)
– faire en sorte que le code multithread soit réglable (nombre de thread)
– exécuter le code avec plus de threads que de processeurs
– exécuter le code sur différentes plates-formes
– instrumenter (manuellement et/ou automatiquement) le code pour essayer et forcer des échecs

Emergences – Coder proprement

Une conception est “simple” si elle respecte les 4 règles suivantes, données par ordre d’importances :
elle réussit tous les tests
elle ne contient aucune redondance
elle exprime les intentions du programmeur
elle réduit le nombre de classes et de méthodes

L’écriture des tests conduit à de meilleures conceptions car :
– classes plus petites
– couplage moins étroit
– utilisations d’injection de dépendances, interface et abstractions

Grâce aux tests on peut modifier le code sans craindre de tout casser pour :
– augmenter la cohésion
– réduire le couplage
– séparer les préoccupations
– modulariser les préoccupations du système
– diminuer la taille de nos fonctions et nos classes
– choisir de meilleurs noms
– éliminer la redondance
– assurer l’expressivité
– minimiser le nombre de classes et de méthodes

Classes – Coder proprement

Une classe se structure dans cet ordre :
– constantes statiques publiques
– variables statiques privées
– variables d’instance privées
– fonctions publiques
– fonctions privées invoquées par une fonction publique juste après

Il faut garder les variables en privées jamais en publiques
On peut les mettre en protégées si c’est vraiment nécessaire pour un test unitaire

Faire de petites classes en se basant sur le principe de responsabilités

Le nom d’une classe doit décrire ses responsabilités

Etre en mesure de décrire brièvement la classe, en employant environ 25 mots, sans utiliser “si”, “et”, “ou” ou “mais”

Respecter le principe de responsabilité unique

Contenir un nombre réduit de variables d’instance

Chaque méthode d’une classe doit manipuler une ou plusieurs variables d’instance

Maintenir la cohésion mène à de nombreuses petites classes

Organiser les classes en vue du changement (ajout de concept)

Cloisonner les changements avec des interfaces pour réduire le couplage et adhérer au principe d’inversion des dépendances

Tests unitaires – Coder proprement

Le code de test est aussi important que le code de production

Il existe 3 lois à suivre pour les tests unitaires :

  1. Vous ne devez pas écrire un code de production tant que vous n’avez pas écrit un test unitaire d’échec
  2. Vous devez uniquement écrire le test unitaire suffisant pour échouer ; l’impossibilité de compiler est un échec
  3. Vous devez uniquement écrire le code de production suffisant pour réussir le test d’échec courant

Le test doit avoir le motif BUILD-OPERATE-CHECK

Une assertion par test si possible

Un seul concept par test (donc multiple assertions possible)

Les tests propres suivent cinq autres règles :
Fast (rapide) : les tests doivent être rapides
Independent (indépendant) : les tests ne doivent pas dépendre les uns des autres
Repeatable (reproductible) : les tests doivent pouvoir être reproduits dans n’importe quel environnement
Self-Validating (auto validant) : les tests doivent avoir un résultat binaire : ils réussissent ou ils échouent
Timely (au moment opportun) : Les tests doivent être écrits au moment opportun

Limites – Coder proprement

Encapsuler certaine fonctionnalité (Object Map) pour éviter que les personnes utilisant votre code fasse des modifications non prévues

Faire des tests d’apprentissage pour découvrir les limites d’une API tierce et garder ces tests à jour

Encapsuler une API tierce ou du code tierce dans une classe afin de limiter les problèmes de régressions dans le cas de changement de cette dernière

Quand le code n’existe pas, prévoir les interfaces et fausses classes pour limiter l’impact lors de la migration

Réduire les références au code tiers

Gestion des erreurs – Coder proprement

Le traitement des erreurs est important, mais s’il masque la logique il est mauvais

Utiliser des exceptions à la place des codes de retours

Le message que l’exception lève doit permettre d’identifier l’opération qui a échoué et son contexte

Les classes d’exception sont utiles si c’est pour intercepter une exception et ignorer les autres

Ne pas retourner null, à la place retourner un objet ou une collection vide par exemple

Ne pas passer null en argument, si c’est le cas cela doit être traité comme une erreur avec exception