- ✨ Aspect-Oriented Programming for Unity 2021.3+ with full UniTask/async support.
- 🚀 Replace boilerplate: logging, profiling, error handling → up to −60% repetitive code.
- ⚡️ Zero runtime overhead — weaving happens at compile time via IL injection.
- 🛠️ Extensible: create custom aspects (caching, validation, authorization, etc.).
- 📊 Increases development speed by ~20–30% in projects with heavy async workflows.
- 🔒 Stable: tested with async lambdas, compiler-generated state machines, and IL2CPP builds.
- 🧩 Integrates seamlessly with existing Unity projects and Zenject-based architectures.
Unity development is full of common patterns: logging method calls, handling exceptions, and measuring performance. This results in the same try-catch
, Debug.Log
, and Stopwatch
code being scattered across your entire project.
❌ Before AOP:
public async UniTask LoadPlayerData(string playerId)
{
Debug.Log($"[LoadPlayerData] Loading data for {playerId}");
var stopwatch = Stopwatch.StartNew();
try
{
var data = await _api.GetPlayerData(playerId);
stopwatch.Stop();
Debug.Log($"[LoadPlayerData] Completed in {stopwatch.ElapsedMilliseconds}ms");
return data;
}
catch (Exception ex)
{
Debug.LogError($"[LoadPlayerData] Failed: {ex.Message}");
throw;
}
}
This plugin allows you to encapsulate cross-cutting concerns into reusable attributes. Focus on your core logic and let aspects handle the rest.
✅ After AOP:
[LogMethod]
[ProfileMethod]
[HandleExceptions]
public async UniTask LoadPlayerData(string playerId)
{
var data = await _api.GetPlayerData(playerId);
return data;
}
- Modern Async Support: Full, native support for UniTask, including compiler-generated state machines and lambda expressions. This is the core feature that makes AOP viable in modern Unity projects.
- Custom Aspects: Easily create your own attributes to handle any cross-cutting concern, such as caching, validation, authorization, and more.
- Zero Runtime Overhead: All the magic happens at compile time. The plugin "weaves" your aspect logic directly into your assembly's IL code, introducing no performance cost at runtime.
- Exception Handling: Wrap methods in a safe
try-catch
block with a single attribute. - Method Interception: Hook into the entry and exit points of any method for powerful logging and profiling.
Note
🧠 A Deeper Look...
Supporting async/await
methods, especially with a modern library like UniTask
, is a non-trivial challenge for compile-time weaving tools. The C# compiler transforms async
methods into complex, hidden state-machine classes.
This plugin's key achievement is its ability to correctly identify and inject code into these compiler-generated classes. It ensures that your aspects work reliably with UniTask
, async
lambdas, and other modern C# features, a capability often missing in legacy AOP tools for Unity.
Add the following packages in the Unity Package Manager using the "Add package from git URL..." option:
https://github.com/vovgou/loxodon-framework.git?path=/Loxodon.Framework.Fody/Packages/com.vovgou.loxodon-framework-fody
https://github.com/finerace/MethodBoundaryAspect.Fody-for-Unity.git
Create or update the FodyWeavers.xml
file located in Assets/LoxodonFramework/Editor/AppData/
to include the aspect weaver.
<?xml version="1.0" encoding="utf-8"?>
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<AssemblyNames>
<Item>Assembly-CSharp</Item>
<!-- You can add other assemblies to be woven here -->
</AssemblyNames>
<MethodBoundaryAspect />
</Weavers>
Important
A Unity restart or project re-import may be required for the compile-time weaving to activate for the first time.
Creating a custom aspect is straightforward. Inherit from OnMethodBoundaryAspect
and override the methods you need.
Example: A [SafeExecution]
attribute that catches and logs exceptions without crashing the game.
using System;
using UnityEngine;
using MethodBoundaryAspect.Fody.Attributes;
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor)]
public sealed class SafeExecutionAttribute : OnMethodBoundaryAspect
{
public override void OnException(MethodExecutionArgs args)
{
Debug.LogError($"[SafeExecution] Exception in method {args.Method.Name}: {args.Exception.Message}");
// Suppress the exception and allow execution to continue
args.FlowBehavior = FlowBehavior.Return;
}
}
Warning
Do not apply AOP attributes directly to classes (e.g., [LogMethod] public class MyClass
). This is unsupported and will break your build process. Attributes should only be applied to methods and constructors.
- Unity Version: 2021.3 or newer
- Scripting Backend: Mono or IL2CPP
Changelog
- Added support for anonymous methods and lambdas
- Fixed handling of compiler-generated classes
- Improved weaving stability
- Fixed errors in async methods with UniTask
- Improved UniTask compatibility
- Added UniTask support
- Automatic detection of async state machines
- Optimized async/await handling
Acknowledgements...
This plugin is a modernized version based on the work of the following projects:
- MethodBoundaryAspect.Fody — The original .NET library on which the plugin is based.
- Loxodon Framework — The framework that provided the initial integration of Fody into the Unity environment.
The key contribution of this version is the deep integration and robust support for modern C# asynchronous features like UniTask.
- ✨ AOP (Aspect-Oriented Programming) для Unity 2021.3+ с полной поддержкой UniTask/async.
- 🚀 Убирает бойлерплейт: логирование, профайлинг, обработка ошибок → до −60% повторяющегося кода.
- ⚡️ Нулевая нагрузка в рантайме — весь код внедряется на этапе компиляции через IL.
- 🛠️ Расширяемость: легко создавать свои аспекты (кэширование, валидация, авторизация и др.).
- 📊 Ускоряет разработку примерно на ~20–30% в проектах с активным использованием асинхронности.
- 🔒 Стабильная работа: протестирован с async-лямбдами, стейт-машинами компилятора и IL2CPP-билдами.
- 🧩 Легко интегрируется в существующие Unity-проекты и архитектуры на Zenject.
Разработка на Unity полна однотипных задач: логирование вызовов методов, обработка исключений, измерение производительности. В итоге один и тот же код с try-catch
, Debug.Log
и Stopwatch
оказывается разбросан по всему проекту.
❌ До AOP:
public async UniTask LoadPlayerData(string playerId)
{
Debug.Log($"[LoadPlayerData] Загрузка данных для {playerId}");
var stopwatch = Stopwatch.StartNew();
try
{
var data = await _api.GetPlayerData(playerId);
stopwatch.Stop();
Debug.Log($"[LoadPlayerData] Завершено за {stopwatch.ElapsedMilliseconds}мс");
return data;
}
catch (Exception ex)
{
Debug.LogError($"[LoadPlayerData] Ошибка: {ex.Message}");
throw;
}
}
Этот плагин позволяет инкапсулировать сквозную функциональность в переиспользуемые атрибуты. Сконцентрируйтесь на основной логике, а остальное доверьте аспектам.
✅ После AOP:
[LogMethod]
[ProfileMethod]
[HandleExceptions]
public async UniTask LoadPlayerData(string playerId)
{
var data = await _api.GetPlayerData(playerId);
return data;
}
- Поддержка современного Async: Полная, нативная поддержка UniTask, включая сгенерированные компилятором стейт-машины и лямбда-выражения. Это ключевая особенность, которая делает AOP жизнеспособным в современных Unity-проектах.
- Собственные аспекты: Легко создавайте свои атрибуты для решения любых сквозных задач: кэширование, валидация, авторизация и т.д.
- Нулевые затраты в рантайме: Вся магия происходит на этапе компиляции. Плагин "вплетает" логику аспектов напрямую в IL-код вашей сборки, не создавая никакой дополнительной нагрузки во время выполнения игры.
- Обработка исключений: Оберните методы в безопасный
try-catch
блок с помощью одного атрибута. - Перехват вызовов методов: Встраивайтесь в начало и конец выполнения любого метода для мощного логирования и профилирования.
Note
🧠 Подробнее о разработке...
Поддержка async/await
методов, особенно с такой современной библиотекой, как UniTask
— это нетривиальная задача для инструментов, работающих на этапе компиляции. Компилятор C# превращает async
-методы в сложные, скрытые классы-стейтмашины.
Главное достижение этого плагина — его способность корректно находить эти сгенерированные классы и внедрять в них код. Это гарантирует, что ваши аспекты будут надежно работать с UniTask
, async
-лямбдами и другими современными возможностями C#, что часто является проблемой в устаревших AOP-инструментах для Unity.
Добавьте следующие пакеты в Unity Package Manager, используя опцию "Add package from git URL...":
https://github.com/vovgou/loxodon-framework.git?path=/Loxodon.Framework.Fody/Packages/com.vovgou.loxodon-framework-fody
https://github.com/finerace/MethodBoundaryAspect.Fody-for-Unity.git
Создайте или обновите файл FodyWeavers.xml
в папке Assets/LoxodonFramework/Editor/AppData/
, чтобы подключить обработчик аспектов.
<?xml version="1.0" encoding="utf-8"?>
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<AssemblyNames>
<Item>Assembly-CSharp</Item>
<!-- Здесь можно добавить другие сборки для обработки -->
</AssemblyNames>
<MethodBoundaryAspect />
</Weavers>
Important
Может потребоваться перезапуск Unity или повторный импорт ассетов, чтобы изменения на этапе компиляции активировались в первый раз.
Создать собственный аспект очень просто. Унаследуйте класс от OnMethodBoundaryAspect
и переопределите нужные вам методы.
Пример: атрибут [SafeExecution]
, который ловит и логирует исключения, не приводя к падению игры.
using System;
using UnityEngine;
using MethodBoundaryAspect.Fody.Attributes;
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor)]
public sealed class SafeExecutionAttribute : OnMethodBoundaryAspect
{
public override void OnException(MethodExecutionArgs args)
{
Debug.LogError($"[SafeExecution] Исключение в методе {args.Method.Name}: {args.Exception.Message}");
// Подавить исключение и позволить выполнению продолжиться
args.FlowBehavior = FlowBehavior.Return;
}
}
Warning
Не применяйте атрибуты AOP напрямую к классам (например, [LogMethod] public class MyClass
). Это не поддерживается и приведет к ошибке при сборке проекта. Атрибуты следует применять только к методам и конструкторам.
- Версия Unity: 2021.3 или новее
- Scripting Backend: Mono или IL2CPP
История изменений (Changelog)
- Добавлена поддержка анонимных методов и лямбд
- Исправлена обработка сгенерированных компилятором классов
- Улучшена стабильность "вплетения" кода
- Исправлены ошибки в асинхронных методах с UniTask
- Улучшена совместимость с UniTask
- Добавлена поддержка UniTask
- Автоматическое определение асинхронных стейт-машин
- Оптимизирована обработка async/await
Благодарности...
Этот плагин является модернизированной версией, основанной на работе следующих проектов:
- MethodBoundaryAspect.Fody — Оригинальная библиотека для .NET, на которой основан плагин.
- Loxodon Framework — Фреймворк, предоставивший первоначальную интеграцию Fody в среду Unity.
Ключевой вклад этой версии — глубокая интеграция и надежная поддержка современных асинхронных возможностей C#, таких как UniTask.