{"id":13589590,"url":"https://github.com/landelare/ue5coro","last_synced_at":"2026-01-24T11:12:20.112Z","repository":{"id":38263196,"uuid":"450960774","full_name":"landelare/ue5coro","owner":"landelare","description":"A deeply-integrated C++20 coroutine plugin for Unreal Engine 5.","archived":false,"fork":false,"pushed_at":"2026-01-18T10:53:37.000Z","size":1122,"stargazers_count":995,"open_issues_count":1,"forks_count":95,"subscribers_count":20,"default_branch":"master","last_synced_at":"2026-01-18T19:40:24.316Z","etag":null,"topics":["async-await","coroutines","cpp","unreal-engine"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause-clear","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/landelare.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-01-22T23:32:18.000Z","updated_at":"2026-01-18T10:53:30.000Z","dependencies_parsed_at":"2024-03-23T15:26:23.932Z","dependency_job_id":"2f479dfb-350e-47d1-a853-5069c06eb64d","html_url":"https://github.com/landelare/ue5coro","commit_stats":null,"previous_names":[],"tags_count":44,"template":false,"template_full_name":null,"purl":"pkg:github/landelare/ue5coro","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/landelare%2Fue5coro","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/landelare%2Fue5coro/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/landelare%2Fue5coro/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/landelare%2Fue5coro/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/landelare","download_url":"https://codeload.github.com/landelare/ue5coro/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/landelare%2Fue5coro/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28725869,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-24T10:24:43.181Z","status":"ssl_error","status_checked_at":"2026-01-24T10:24:36.112Z","response_time":89,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["async-await","coroutines","cpp","unreal-engine"],"created_at":"2024-08-01T16:00:32.021Z","updated_at":"2026-01-24T11:12:20.078Z","avatar_url":"https://github.com/landelare.png","language":"C++","funding_links":[],"categories":["Utilities","Game Development"],"sub_categories":["Unreal Engine: Resources"],"readme":"# UE5Coro\n\nUE5Coro implements C++20\n[coroutine](https://en.cppreference.com/w/cpp/language/coroutines) support for\nUnreal Engine 5 with a focus on gameplay logic, convenience, and providing\nseamless integration with the engine.\n\nThere's built-in support for easy authoring of latent UFUNCTIONs.\nChange the return type of a latent UFUNCTION to make it a coroutine, and you get\nall the FPendingLatentAction boilerplate for free, with BP-safe multithreading\nsupport out of the box:\n```cpp\nUFUNCTION(BlueprintCallable, meta = (Latent, LatentInfo = LatentInfo))\nFVoidCoroutine Example(FLatentActionInfo LatentInfo)\n{\n    UE_LOGFMT(LogTemp, Display, \"Before delay\");\n    co_await UE5Coro::Latent::Seconds(1); // Does not block the game thread!\n    UE_LOGFMT(LogTemp, Display, \"After delay\");\n\n    // Moving out of the game thread is as easy...\n    co_await UE5Coro::Async::MoveToTask();\n    UE_LOGFMT(LogTemp, Display, \"In game thread: {0}\", IsInGameThread());\n    FString Value = TEXT(\"Imagine this was expensive to compute\");\n\n    // ...as moving back in:\n    co_await UE5Coro::Async::MoveToGameThread();\n    UE_LOGFMT(LogTemp, Display, \"In game thread: {0}\", IsInGameThread());\n    UE_LOGFMT(LogTemp, Display, \"Value: {0}\", Value);\n}\n```\n\nThis is a real, working example!\nTry putting it into an actor class.\nYou can even destroy the actor while the coroutine is running.\nLatent coroutines will automatically track their target UObject, and clean up\nearly if needed.\n\nEven the coroutine return type is hidden from BP to not disturb designers:\n\n![Latent Blueprint node for the Example function above](Docs/latent_node.png)\n\nNot interested in latent UFUNCTIONs?\nNot a problem.\nRaw C++ coroutines are also supported, with the exact same feature set.\nThe backing implementation is selected at compile time; latent actions are\nonly created if you actually use them.\n\nChange your return type to one of the coroutine types provided by this plugin,\nand complex asynchronous tasks that would be cumbersome to implement yourself\nbecome trivial one-liners that Just Work™, eliminating the need for callbacks\nand other handlers.\n\n* Enjoying the convenience of LoadSynchronous, but not the drawbacks?\u003cbr\u003e\n  `UObject* HardPtr = co_await AsyncLoadObject(SoftPtr);` lets you keep only the\n  benefits (and your FPS).\n* What about spreading a heavy computation across multiple ticks?\u003cbr\u003e\n  Add a `co_await NextTick();` inside a loop, and you're already done.\n  There's a time budget class that lets you specify the desired processing time\n  directly, and let the coroutine dynamically schedule itself.\n* Speaking of dynamic scheduling, throttling can be as simple as this:\u003cbr\u003e\n  `co_await Ticks(bCloseToCamera ? 1 : 2);`\n* Why time slice on the game thread when you have multiple CPU cores eager to\n  work?\u003cbr\u003e\n  Add `co_await MoveToTask();` to your function, and everything after that line\n  will run within the UE\\:\\:Tasks system on a worker thread.\u003cbr\u003e\n* Want to go back?\n  It's `co_await MoveToGameThread();`.\u003cbr\u003e\n  You're free to arbitrarily move between threads, and latent UFUNCTION\n  coroutines automatically move back to the game thread when they're done to\n  resume BP.\n* Still not convinced? Here's how to run an entire timeline:\u003cbr\u003e\n  `co_await Timeline(this, From, To, Duration, YourUpdateLambdaGoesHere);`\n* Hard to please?\n  Here's how you can asynchronously wait for a DYNAMIC delegate without writing\n  a UFUNCTION just for the AddDynamic/BindDynamic, or being in a UCLASS, or any\n  class at all:\u003cbr\u003e\n  `co_await YourDynamicDelegate;` (that's the entire code)\n* Oh, you wanted parameters with that delegate?\u003cbr\u003e\n  `auto [Your, Parameters] = co_await YourDynamicDelegate;`\n\nThis should give a taste of the significant reduction in code and effort that's\npossible with this plugin.\nLess and simpler code to write generally translates to fewer bugs, and\nasynchronous code being easy to write means there's no friction when it comes to\ndoing things the right way, right away.\n\nSay goodbye to that good-enough-for-now™ LoadSynchronous that's still in\nShipping, two updates later.\nWith the task at hand reduced from \"write all the StreamableManager boilerplate\nand move a part of the calling function into a callback\" to merely \"stick\nco_await in front of it\", you'll finish quicker than it would've taken to come\nup with a justification for why the synchronous blocking version is somehow\nacceptable.\n\nThere are plenty of additional features in the plugin, such as generators that\nlet you avoid allocating an entire TArray just to return a variable number of\nvalues.\nEasier for you to write, easier for the compiler to\n[optimize](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1365r0.pdf),\nyou only need O(1) storage instead of O(N) for N items, what's not to like?\n\n# List of features\n\nThe following links will get you to the relevant pages of the documentation.\nBookmark this section if you prefer to read the latest documentation in your\nbrowser, or read it straight from your IDE.\nEvery API function is documented in the C++ headers, and the releases contain\nthe Markdown source of the documentation that you're reading right now.\n\n## Coroutine authoring\n\nThese features focus on exposing coroutines to the rest of the engine.\n\n* [Coroutines](Docs/Coroutine.md) (obviously)\n  * [Cancellation](Docs/Cancellation.md) support has its own page.\n* [Generators](Docs/Generator.md)\n* [Gameplay Ability System](Docs/GAS.md) integration works slightly differently.\n\u003c!-- There is an additional, unlisted documentation page: Private.md --\u003e\n\n## Unreal integration\n\nThese wrappers provide convenient ways to consume engine features from your\ncoroutines.\n\n* [AI](Docs/AI.md) integration (MoveTo, pathfinding...)\n* [Animation awaiters](Docs/Animation.md) (montages, notifies...)\n* [Async awaiters](Docs/Async.md) (multithreading, synchronization...)\n  * [Async chain](Docs/AsyncChain.md) (universal wrapper for functions taking delegates)\n* [HTTP](Docs/Http.md) (asynchronous HTTP requests)\n* [Implicit awaiters](Docs/Implicit.md) (certain engine types are directly\n  co_awaitable, without wrappers)\n* [Latent awaiters](Docs/Latent.md) (game thread interaction, Delay...)\n  * [Asset loading](Docs/LatentLoad.md) (async loading soft pointers, bundles...)\n  * [Async collision queries](Docs/LatentCollision.md) (line traces, overlap checks...)\n  * [Latent chain](Docs/LatentChain.md) (universal latent action wrapper)\n  * [Tick time budget](Docs/LatentTickTimeBudget.md) (run for x ms per frame)\n* [Latent callbacks](Docs/LatentCallback.md) (interaction with the latent\n  action manager)\n\n\u003e [!NOTE]\n\u003e Most of these functions return undocumented internal types from the\n\u003e `UE5Coro::Private` namespace.\n\u003e Client code should not refer to anything from this namespace directly, as\n\u003e everything within is subject to change in future versions, **without** prior\n\u003e deprecation.\n\u003e\n\u003e Most often, this is not an issue: for example, the unnamed temporary object in\n\u003e `co_await Something()` does not appear in source code.\n\u003e If a `Private` return value needs to be stored, use `auto` (or a constrained\n\u003e `TAwaitable auto`) to avoid writing the type's name.\n\u003e\n\u003e Directly calling the public-by-necessity C++ awaitable functions\n\u003e `await_ready`, `await_suspend`, and `await_resume` is not supported on any\n\u003e awaiter.\n\n## Additional features\n\n* [Aggregate awaiters](Docs/Aggregate.md) (WhenAny, WhenAll, Race...)\n* [Latent timelines](Docs/LatentTimeline.md) (smooth interpolation on tick)\n* [Threading primitives](Docs/Threading.md) (semaphores, events...)\n* [Gameplay Debugger](Docs/GameplayDebugger.md) integration\n\n# Installation\n\nOnly numbered releases are supported.\nDo not use the Git branches directly.\n\nDownload the release that you've chosen, and extract it into your project's\nPlugins folder.\nRename the folder to just UE5Coro, without a version number.\nDone correctly, you should end up with\n`YourProject\\Plugins\\UE5Coro\\UE5Coro.uplugin`.\n\n## Project setup\n\nYour project might use some legacy settings that need to be removed to unlock\nC++20 support, which otherwise comes as standard in new projects made in\nUnreal Engine 5.3 or later.\n\nIn your **Target.cs** files (all of them), make sure that you're using the\nlatest settings and include order version:\n\n```c#\nDefaultBuildSettings = BuildSettingsVersion.Latest;\nIncludeOrderVersion = EngineIncludeOrderVersion.Latest;\n```\n\nIf you're using the legacy `bEnableCppCoroutinesForEvaluation` flag, that's not\nneeded anymore, and it should no longer be explicitly turned on; doing so may\ncause issues.\nIt is recommended to remove all references to it from your build files.\n\nIf you're setting `CppStandard` to `CppStandardVersion.Cpp17` in a Build.cs\nfile... don't :)\n\n## Usage\n\nReference the `\"UE5Coro\"` module from your Build.cs as you would any other\nC++ module, and use `#include \"UE5Coro.h\"`.\nThe plugin itself does not need to be enabled.\n\nSome functionality is in optional modules that need to be referenced separately.\nFor instance, Gameplay Ability System support needs `\"UE5CoroGAS\"` in Build.cs,\nand `#include \"UE5CoroGAS.h\"`.\nThe core UE5Coro module only depends on engine modules that are enabled by\ndefault.\n\n\u003e [!IMPORTANT]\n\u003e Do not directly #include any other header, only the one matching the module's\n\u003e name.\n\u003e Major IDEs used with Unreal Engine are known to get header suggestions wrong.\n\u003e If you add UE5Coro.h to your PCH, you can make it available everywhere.\n\n# Updates\n\nTo update, delete UE5Coro from your project's Plugins folder, and install the\nnew version using the instructions above.\n\n# Packaging\n\nPackaging UE5Coro separately (from the Plugins window) is not needed, and not\nsupported.\n\n# Removal\n\nTo remove the plugin from your project, reimplement all your coroutines without\nits functionality, remove all references to the plugin and its modules, and add\na core redirect from `/Script/UE5CoroK2.K2Node_UE5CoroCallCoroutine` to\n`/Script/BlueprintGraph.K2Node_CallFunction`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flandelare%2Fue5coro","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flandelare%2Fue5coro","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flandelare%2Fue5coro/lists"}