ワンクリックで
behaviour-inject
Guide for using Behaviour Inject (BInject) - a lightweight dependency injection framework for Unity3D
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Guide for using Behaviour Inject (BInject) - a lightweight dependency injection framework for Unity3D
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Supports creating, editing, and managing Unity assets (prefabs, materials, asset database, Addressables). Includes dependency analysis and import settings. Use when: prefab creation, material editing, asset search, dependency analysis, Addressables
Supports Unity C# script editing, searching, and refactoring. Enables TDD cycle code editing, symbol navigation, reference searching, and structured editing. Use when: C# editing, script search, symbol search, refactoring, code indexing, class creation, method addition
Comprehensive guide for Unity development. Provides architecture patterns, MCP tool selection, and composite task workflows. Parent skill always referenced for Unity-related tasks. See child skills for detailed implementation. Use when: Unity development in general, C# editing, scene operations, UI implementation, asset management, PlayMode testing
Game UI design using Unity's uGUI (Canvas/RectTransform/Anchors). Includes game UI elements like HUD, health bars, inventory, skill bars, mobile responsive design, and Safe Area support. Use when: game UI design, HUD creation, Canvas setup, mobile UI, Anchors configuration
Game UI design using Unity's UI Toolkit (USS/UXML/Flexbox). Includes game UI elements like HUD, health bars, inventory, skill bars, PanelSettings scaling, and Safe Area support. Use when: game UI design, HUD creation, USS/UXML styling, Flexbox layout, PanelSettings configuration
Supports Unity Play Mode control, input simulation, UI automation, and visual verification. Integrates test execution, screenshot/video capture, and console log checking. Use when: starting Play Mode, input simulation, UI clicks, screenshots, video recording, test execution
| name | behaviour-inject |
| description | Guide for using Behaviour Inject (BInject) - a lightweight dependency injection framework for Unity3D |
BInject is a performant, lightweight dependency injection framework for Unity3D. This skill provides guidance on how to use it effectively in the project.
BInject provides:
[Inject] attributeCreate a context early in the game lifecycle (before Injector components awake):
using BehaviourInject;
public class GameInitializer : MonoBehaviour
{
void Awake()
{
// Create default context
Context context = Context.Create();
// Register dependencies
context.RegisterDependency(new GameSettings());
context.RegisterDependency(new AudioManager());
}
}
[!CAUTION] REQUIRED: For
[Inject]to work in any MonoBehaviour, the Injector component MUST be attached to the same GameObject. The Injector must also have the correct context selected in the Inspector. Without an Injector on the same GameObject, injection via[Inject]attribute will NOT work!
Add the Injector component to GameObjects that need injection. It must be placed before other MonoBehaviours that require dependencies in the component order.
IMPORTANT: Never use the [Inject] attribute on private, protected or internal fields, properties, or methods. BInject must be able to access the member, so apply [Inject] only to public members.
using BehaviourInject;
public class PlayerController : MonoBehaviour
{
// Property injection
[Inject]
public GameSettings Settings { get; private set; }
// Field injection
[Inject]
private AudioManager _audio;
// Method injection (recommended - most explicit)
[Inject]
public void Init(GameSettings settings, AudioManager audio)
{
// Dependencies available here
}
}
For reliable injection, configure execution order:
Set in: Edit → Project Settings → Script Execution Order
// Register instance directly
context.RegisterDependency(myInstance);
// Register instance as interface
context.RegisterDependencyAs<MyClass, IMyInterface>(myInstance);
### Type Registration (Autocomposition)
```csharp
// Register type - created lazily with constructor injection
context.RegisterType<NetworkManager>();
// Register type as interface
context.RegisterTypeAs<MockReader, IReader>();
### Factory Registration
```csharp
// Factory function (derive from existing dependency)
context.RegisterAsFunction<Connection, ConnectionConfig>(conn => conn.Config);
// Custom factory class
context.RegisterFactory<Game, GameFactory>();
BInject automatically creates objects using constructor injection:
public class Connection
{
private readonly Settings _settings;
private readonly Logger _logger;
// Constructor with [Inject] is preferred
[Inject]
public Connection(Settings settings, Logger logger)
{
_settings = settings;
_logger = logger;
}
// Without [Inject], constructor with fewest parameters is used
public Connection() { }
}
// Registration
context.RegisterDependency(new Settings())
.RegisterDependency(new Logger())
.RegisterType<Connection>(); // Auto-created with Settings and Logger
[Create] AttributeUse [Create] to instantiate new objects instead of resolving from context:
public class GameManager : MonoBehaviour
{
// Creates new Connection each time, not from context
[Create]
public void Setup(Connection connection)
{
// connection is newly created, not shared
}
// Mix [Inject] and [Create]
[Inject]
public void Init(Settings settings, [Create] Connection connection)
{
// settings from context, connection newly created
}
}
For runtime object creation with dependency injection:
public class EnemySpawner : MonoBehaviour
{
[Inject]
private IInstantiator _instantiator;
public void SpawnEnemy()
{
// Creates Enemy with all dependencies from context
Enemy enemy = _instantiator.New<Enemy>();
// With additional custom arguments
var config = new EnemyConfig { Damage = 10 };
Enemy customEnemy = _instantiator.New<Enemy>(config);
}
}
For complex creation logic:
public class GameFactory : DependencyFactory<Game>
{
private Connection _connection;
public GameFactory(Connection connection)
{
_connection = connection;
}
public Game Create()
{
if (_connection.Connected)
return new Game(1, "Online Game");
return new Game(0, "Offline Game");
}
}
// Registration
context.RegisterFactory<Game, GameFactory>();
// Usage - factory resolves automatically
public class GameLauncher : MonoBehaviour
{
[Inject]
public Game CurrentGame { get; set; } // Created via factory
[Inject]
public GameFactory Factory { get; set; } // Factory itself available too
}
Events are dispatched through DI without manual subscription:
public class GameEventSender : MonoBehaviour
{
[Inject]
private IEventDispatcher _dispatcher;
public void OnPlayerDied()
{
_dispatcher.DispatchEvent(new PlayerDiedEvent { PlayerId = 1 });
}
}
public class UIManager : MonoBehaviour
{
[InjectEvent]
public void OnPlayerDied(PlayerDiedEvent evt)
{
ShowGameOverScreen(evt.PlayerId);
}
// Receive interface or base type events
[InjectEvent(Inherit = true)]
public void OnGameEvent(IGameEvent evt)
{
// Receives all events implementing IGameEvent
}
}
public class ScoreManager : MonoBehaviour
{
[InjectEvent]
public Action<ScoreChangedEvent> OnScoreChanged;
void Start()
{
OnScoreChanged += HandleScoreChanged;
}
void HandleScoreChanged(ScoreChangedEvent evt) { }
}
Commands execute automatically when specific events occur:
public class SaveGameCommand : ICommand
{
private ISaveService _saveService;
private GameSavedEvent _event;
public SaveGameCommand(ISaveService saveService)
{
_saveService = saveService;
}
[InjectEvent]
public void SetEvent(GameSavedEvent evt)
{
_event = evt;
}
public void Execute()
{
_saveService.Save(_event.SlotId);
}
}
// Registration
context.RegisterCommand<GameSavedEvent, SaveGameCommand>();
For separate dependency scopes:
// In BInject/Resources/BInjectSettings, add context names
// Create named context
Context.Create("game_context");
Context.Create("ui_context");
// Set parent for inheritance
Context.Create("level_context")
.SetParentContext("game_context");
Set context in Inspector on Injector component.
For GameObject-specific dependency scopes:
public class RoomContext : HierarchyContext
{
private Context _context;
public override Context GetContext()
{
if (_context == null)
{
_context = Context.CreateLocal() // CreateLocal for non-global
.SetParentContext("game_context")
.RegisterDependency(new RoomData());
}
return _context;
}
void OnDestroy()
{
_context.Destroy(); // Always destroy local contexts
}
}
Enable "Use Hierarchy" on child Injector components.
// Check if context exists
if (Context.Exists("game_context"))
{
// ...
}
// Destroy context (also destroys child contexts and GameObjects with Injectors)
context.Destroy();
// Hook into destruction
context.OnContextDestroyed += HandleDestroyed;
[Inject] on methods for explicit dependenciesOnDestroy() when using CreateLocal()IInstantiator sparingly, prefer constructor injection// Instead of singleton GameManager.Instance
[Inject]
public GameManager GameManager { get; set; }
// Production
context.RegisterTypeAs<NetworkService, INetworkService>();
// Test
context.RegisterDependencyAs<MockNetworkService, INetworkService>(new MockNetworkService());
// Main context (persistent)
Context.Create("main")
.RegisterDependency(new AudioManager());
// Level context (destroyed with scene)
Context.Create("level")
.SetParentContext("main")
.RegisterDependency(new LevelData());
| Issue | Solution |
|---|---|
| Dependencies null in Awake | Check Script Execution Order |
| "Type not registered" | Ensure registration happens before injection |
| Duplicate events | Component registered both as dependency and Injector target |
| Context cycling | Don't set parent to self or descendant |
| Null context | Ensure context created before Injector awakens |
The package is located at: Packages/com.sergeysychov.behaviour_inject/
Key files:
Scripts/Context.cs - Main context APIScripts/Injector.cs - MonoBehaviour injector componentScripts/Attributes.cs - [Inject], [Create], [InjectEvent]Scripts/DependencyFactory.cs - Factory base classScripts/ICommand.cs - Command interfaceScripts/HierarchyContext.cs - Hierarchy-based context