UE5Coro implémente la prise en charge de la coroutine C++20 pour Unreal Engine 5 en mettant l'accent sur la logique de jeu, la commodité et en fournissant une intégration transparente avec le moteur.
Note
La prise en charge de C++17, des anciens compilateurs, plates-formes et versions de moteur est disponible dans l'ancienne série UE5Coro 1.x.
Il existe une prise en charge intégrée pour la création facile d'UFONCTIONS latentes. Modifiez le type de retour d'une UFUNCTION latente pour en faire une coroutine, et vous obtenez gratuitement tout le passe-partout de FPendingLatentAction, avec une prise en charge multithread sécurisée par BP prête à l'emploi :
UFUNCTION (BlueprintCallable, meta = (Latent, LatentInfo = LatentInfo))
FVoidCoroutine Example(FLatentActionInfo LatentInfo)
{
UE_LOGFMT (LogTemp, Display, " Started " );
co_await UE5Coro::Latent::Seconds ( 1 ); // Does not block the game thread!
UE_LOGFMT (LogTemp, Display, " Done " );
co_await UE5Coro::Async::MoveToThread (ENamedThreads::AnyThread);
auto Value = HeavyComputation ();
co_await UE5Coro::Async::MoveToGameThread ();
UseComputedValue (Value);
}
Cette coroutine suivra automatiquement son UObject cible à travers les threads, donc même si son objet propriétaire est détruit avant la fin, il ne plantera pas à cause d'un problème this
le thread du jeu.
Même le type de retour de la coroutine est caché à BP pour ne pas déranger les concepteurs :
Vous n'êtes pas intéressé par les UFUNCTIONS latentes ? Pas de problème. Les coroutines Raw C++ sont également prises en charge, avec exactement le même ensemble de fonctionnalités. L'implémentation de support est sélectionnée au moment de la compilation ; les actions latentes ne sont créées que si vous les utilisez réellement.
Changez votre type de retour en l'un des types de coroutine fournis par ce plugin, et les tâches asynchrones complexes qui seraient difficiles à mettre en œuvre vous-même deviennent des one-liners triviaux que Just Work™, éliminant le besoin de rappels et d'autres gestionnaires.
UObject* HardPtr = co_await AsyncLoadObject(SoftPtr);
vous permet de conserver uniquement les bénéfices (et vos FPS).co_await NextTick();
dans une boucle, et vous avez déjà terminé. Il existe une classe de budget temps qui vous permet de spécifier directement le temps de traitement souhaité et de laisser la coroutine se planifier dynamiquement.co_await Ticks(bCloseToCamera ? 1 : 2);
co_await MoveToTask();
à votre fonction, et tout ce qui suit cette ligne s'exécutera dans le système UE::Tasks sur un thread de travail.co_await MoveToGameThread();
.co_await Timeline(this, From, To, Duration, YourUpdateLambdaGoesHere);
co_await YourDynamicDelegate;
(c'est tout le code)auto [Your, Parameters] = co_await YourDynamicDelegate;
Cela devrait donner un avant-goût de la réduction significative du code et des efforts possibles avec ce plugin. Moins de code et plus simple à écrire se traduit généralement par moins de bogues, et le code asynchrone étant facile à écrire signifie qu'il n'y a pas de friction lorsqu'il s'agit de faire les choses correctement, tout de suite.
Dites adieu à ce LoadSynchronous assez bon pour l'instant™ qui est toujours en expédition, deux mises à jour plus tard. Avec la tâche à accomplir réduite de "écrire tout le passe-partout StreamableManager et déplacer une partie de la fonction appelante dans un rappel" à simplement "coller co_await devant", vous terminerez plus vite qu'il n'aurait fallu pour arriver avec une justification expliquant pourquoi la version de blocage synchrone est en quelque sorte acceptable.
Il existe de nombreuses fonctionnalités supplémentaires dans le plugin, telles que des générateurs qui vous permettent d'éviter d'allouer un TArray entier juste pour renvoyer un nombre variable de valeurs. Plus facile à écrire pour vous, plus facile à optimiser pour le compilateur, vous n'avez besoin que d'un stockage O(1) au lieu de O(N) pour N éléments, qu'est-ce qu'il ne faut pas aimer ?
Les liens suivants vous mèneront aux pages pertinentes de la documentation. Ajoutez cette section à vos favoris si vous préférez lire la dernière documentation dans votre navigateur ou la lire directement depuis votre IDE. Chaque fonction API est documentée dans les en-têtes C++ et les versions contiennent la source Markdown de la documentation que vous lisez actuellement.
Ces fonctionnalités se concentrent sur l’exposition des coroutines au reste du moteur.
Ces wrappers offrent des moyens pratiques d’utiliser les fonctionnalités du moteur à partir de vos coroutines.
Note
La plupart de ces fonctions renvoient des types internes non documentés de l'espace de noms UE5Coro::Private
. Le code client ne doit faire référence directement à rien de cet espace de noms, car tout ce qu'il contient est susceptible de changer dans les versions futures, sans dépréciation préalable.
Le plus souvent, ce n'est pas un problème : par exemple, l'objet temporaire sans nom dans co_await Something()
n'apparaît pas dans le code source. Si une valeur de retour Private
doit être stockée, utilisez auto
(ou un TAwaitable auto
contraint) pour éviter d'écrire le nom du type.
L’appel direct des fonctions attendues C++ publiques par nécessité await_ready
, await_suspend
et await_resume
n’est pris en charge sur aucun waiter.
Seules les versions numérotées sont prises en charge. N'utilisez pas directement les branches Git.
Téléchargez la version que vous avez choisie et extrayez-la dans le dossier Plugins de votre projet. Renommez le dossier uniquement en UE5Coro, sans numéro de version. Fait correctement, vous devriez vous retrouver avec YourProjectPluginsUE5CoroUE5Coro.uplugin
.
Note
Veuillez vous référer au README de la version si vous utilisez 1.x. Il avait une méthode d’installation différente impliquant plusieurs plugins.
Votre projet peut utiliser certains paramètres hérités qui doivent être supprimés pour déverrouiller la prise en charge de C++20, qui est par ailleurs standard dans les nouveaux projets réalisés dans Unreal Engine 5.3 ou version ultérieure.
Dans vos fichiers Target.cs (tous), assurez-vous que vous utilisez les derniers paramètres et incluez la version de la commande :
DefaultBuildSettings = BuildSettingsVersion . Latest ;
IncludeOrderVersion = EngineIncludeOrderVersion . Latest ;
Si vous utilisez l'ancien indicateur bEnableCppCoroutinesForEvaluation
, cela n'est plus nécessaire et il ne devrait plus être explicitement activé ; cela pourrait causer des problèmes. Il est recommandé de supprimer toutes les références à celui-ci de vos fichiers de build.
Si vous définissez CppStandard
sur CppStandardVersion.Cpp17
dans un fichier Build.cs... ne le faites pas :)
Référencez le module "UE5Coro"
de votre Build.cs comme vous le feriez pour n'importe quel autre module C++ et utilisez #include "UE5Coro.h"
. Le plugin lui-même n'a pas besoin d'être activé.
Certaines fonctionnalités se trouvent dans des modules facultatifs qui doivent être référencés séparément. Par exemple, la prise en charge du Gameplay Ability System nécessite "UE5CoroGAS"
dans Build.cs et #include "UE5CoroGAS.h"
. Le module principal UE5Coro dépend uniquement des modules moteur activés par défaut.
Important
N'incluez directement aucun autre en-tête, uniquement celui correspondant au nom du module. Les principaux IDE utilisés avec Unreal Engine sont connus pour avoir des suggestions d'en-tête erronées. Si vous ajoutez UE5Coro.h à votre PCH, vous pouvez le rendre disponible partout.
Pour mettre à jour, supprimez UE5Coro du dossier Plugins de votre projet et installez la nouvelle version en suivant les instructions ci-dessus.
L'empaquetage de UE5Coro séparément (à partir de la fenêtre Plugins) n'est pas nécessaire et n'est pas pris en charge.
Pour supprimer le plugin de votre projet, réimplémentez toutes vos coroutines sans ses fonctionnalités, supprimez toutes les références au plugin et à ses modules et ajoutez une redirection principale de /Script/UE5CoroK2.K2Node_UE5CoroCallCoroutine
vers /Script/BlueprintGraph.K2Node_CallFunction
.