ΠΡΠ³ΠΊΠΈΠΉ DI-ΡΡΠ΅ΠΉΠΌΠ²ΠΎΡΠΊ Π΄Π»Ρ Unity. ΠΡΠ½ΠΎΠ²Π° β ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΎΠΉ:
- Π±ΠΈΠ½Π΄ΠΈΠ½Π³ΠΎΠ² ΠΏΠΎ ΡΠΈΠΏΡ, ΠΈΠ½ΡΡΠ°Π½ΡΡ ΠΈ ΡΠ°Π±ΡΠΈΠΊΠ΅,
- ΡΠ΅Π³ΠΎΠ² Π΄Π»Ρ ΠΏΠ°ΡΠ°Π»Π»Π΅Π»ΡΠ½ΡΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΉ,
- ΠΈΠ½ΡΠ΅ΠΊΡΠΈΠΉ ΡΠ΅ΡΠ΅Π· ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ (Π² ΡΠΎΠΌ ΡΠΈΡΠ»Π΅ Ρ Π°ΡΡΠΈΠ±ΡΡΠ°ΠΌΠΈ
[InjectionConstructor]
ΠΈ[Tag]
), - ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠΎΠ² ΠΏΡΠΎΠ΅ΠΊΡΠ° ΠΈ ΡΡΠ΅Π½Ρ,
- Π²ΡΠΏΠΎΠΌΠΎΠ³Π°ΡΠ΅Π»ΡΠ½ΡΡ Π±ΠΈΠ½Π΄ΠΈΠ½Π³ΠΎΠ² Π΄Π»Ρ MonoBehaviour (ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ GO, ΠΏΡΠ΅ΡΠ°Π±Ρ, Π·Π°Ρ Π²Π°Ρ ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠΈΡ ΠΈΠ½ΡΡΠ°Π½ΡΠΎΠ²).
Π€ΡΠ΅ΠΉΠΌΠ²ΠΎΡΠΊ ΡΠ΄Π΅Π»Π°Π½ ΠΏΡΠ΅ΠΆΠ΄Π΅ Π²ΡΠ΅Π³ΠΎ Π΄Π»Ρ Π²Π½ΡΡΡΠ΅Π½Π½Π΅Π³ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ Π² AbyssMoth Studios. ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ Π½Π° ΡΠ²ΠΎΠΉ ΡΡΡΠ°Ρ ΠΈ ΡΠΈΡΠΊ; API ΠΌΠΎΠΆΠ΅Ρ ΡΠ²ΠΎΠ»ΡΡΠΈΠΎΠ½ΠΈΡΠΎΠ²Π°ΡΡ.
-
ΠΠΌΠΏΠΎΡΡΠΈΡΡΠΉΡΠ΅ ΠΏΠ°ΠΊΠ΅Ρ. ΠΠ°ΠΏΠΊΠ° ΠΏΠ»Π°Π³ΠΈΠ½Π° ΠΎΠΊΠ°ΠΆΠ΅ΡΡΡ Π·Π΄Π΅ΡΡ:
Assets/Plugins/RimuruDev/CuteDI
-
ΠΡΠΊΡΠΎΠΉΡΠ΅ ΠΏΡΠΈΠΌΠ΅Ρ:
Assets/Plugins/RimuruDev/CuteDI/Example
β ΡΠ°ΠΌ Π³ΠΎΡΠΎΠ²ΡΠ΅ ΡΡΠ΅Π½Ρ Boot, MainMenu, Gameplay, Other ΠΈ Π΄Π΅ΠΌΠΎΠ½ΡΡΡΠ°ΡΠΈΡ Π²ΡΠ΅Ρ Π²ΠΈΠ΄ΠΎΠ² Π±ΠΈΠ½Π΄ΠΈΠ½Π³Π°.
ΠΡΠΎΠ΅ΠΊΡΠ½ΡΠΉ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ Π²Ρ ΡΠΎΠ·Π΄Π°ΡΡΠ΅ ΡΠ°ΠΌΠΈ Π² ΡΠΎΡΠΊΠ΅ Π²Ρ ΠΎΠ΄Π° (ΠΊΠ°ΠΊ Π² ΠΏΡΠΈΠΌΠ΅ΡΠ΅):
using UnityEngine;
namespace AbyssMoth.CuteDI.Example
{
public sealed class Bootstrapper : MonoBehaviour
{
private IProjectContext projectContext;
private IGameNavigation navigation;
private void Awake()
{
projectContext = new ProjectContext();
projectContext.Register();
projectContext.Resolve();
navigation = projectContext.Container.Resolve<IGameNavigation>();
DontDestroyOnLoad(gameObject);
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Alpha1)) navigation.GoToMainMenu();
if (Input.GetKeyDown(KeyCode.Alpha2)) navigation.GoToGameplay();
if (Input.GetKeyDown(KeyCode.Alpha3)) navigation.GoToOther();
}
private void OnDestroy() => projectContext?.Release();
}
}
ProjectContext
Π²Π½ΡΡΡΠΈ ΡΠΎΠ·Π΄Π°ΡΡ DIContainer
, Π΄Π΅Π»Π°Π΅Ρ Π±Π°Π·ΠΎΠ²ΡΠ΅ ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΠΈ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ICoroutineRunner
, IGameNavigation
), ΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ Π²ΠΎ ΡΡΠ΅ΠΉΠΌΠ²ΠΎΡΠΊ ΡΠ΅ΡΠ΅Π· DiProvider.SetProject(...)
.
Π’Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄ Π΄Π°ΡΡ ΠΏΠΎΠ»Π½ΡΠΉ ΠΊΠΎΠ½ΡΡΠΎΠ»Ρ Π½Π°Π΄ ΡΠ΅ΠΌ, ΡΡΠΎ Π½Π°Ρ
ΠΎΠ΄ΠΈΡΡΡ Π½Π° ΡΡΠΎΠ²Π½Π΅ ΠΏΡΠΎΠ΅ΠΊΡΠ°.
ΠΠ° ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΡΡΠ΅Π½Π΅ ΠΏΠΎΠ»ΠΎΠΆΠΈΡΠ΅ SceneContext
(Π΅ΡΡΡ Π³ΠΎΡΠΎΠ²ΡΠΉ SceneContextBootstrap
, ΠΊΠΎΡΠΎΡΡΠΉ Π³Π°ΡΠ°Π½ΡΠΈΡΡΠ΅Ρ Π½Π°Π»ΠΈΡΠΈΠ΅ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ°).
Π SceneContext
ΠΌΠΎΠΆΠ½ΠΎ Π½Π°Π·Π½Π°ΡΠΈΡΡ ScriptableObject-ΠΈΠ½ΡΡΠ°Π»Π»Π΅ΡΡ β ΠΎΠ½ΠΈ Π²ΡΠ·ΡΠ²Π°ΡΡΡΡ Π² Awake
ΠΈ Π½Π°ΠΏΠΎΠ»Π½ΡΡΡ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ ΡΡΠ΅Π½Ρ.
ΠΡΠΈΠΌΠ΅Ρ ΠΏΡΠΎΡΡΠΎΠ³ΠΎ ΠΈΠ½ΡΡΠ°Π»Π»Π΅ΡΠ° ΠΌΠ΅Π½Ρ:
using UnityEngine;
namespace AbyssMoth.CuteDI.Example
{
[CreateAssetMenu(fileName = "MainMenuInstaller", menuName = "DI/Scene Installers/MainMenu")]
public sealed class MainMenuInstaller : SceneInstallerSO
{
[SerializeField] private GameObject menuRootPrefab;
public override void Compose(in DIContainer scene, in DIContainer project)
{
scene.RegisterInstance(this).AsSingle().NonLazy();
scene.RegisterType<IMenuService, MenuService>().AsSingle().NonLazy();
scene.Register(c => new MenuViewModel(c.Resolve<IMenuService>())).AsSingle().NonLazy();
if (menuRootPrefab)
scene.BindPrefab<IMenuRoot, MenuRoot>(menuRootPrefab, isUI: true);
}
}
}
ΠΠ΄ΠΎΡ Π½ΠΎΠ²Π»Π΅Π½ΠΎ Reflex. ΠΠ΅Π»Π°Π΅Ρ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡΠ½ΡΡ ΠΈΠ½ΡΠ΅ΠΊΡΠΈΡ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ.
scene.RegisterType<IEnemySpawner, EnemySpawner>().AsSingle().NonLazy();
scene.RegisterType(typeof(IAnalytics), typeof(DummyAnalytics)).AsSingle().NonLazy();
scene.RegisterInstance(this).AsSingle().NonLazy();
scene.RegisterInstance(configSo).AsSingle().NonLazy();
scene.Register(c => new GameplayController(
c.Resolve<IEnemySpawner>(),
project.Resolve<IGameNavigation>()))
.AsSingle()
.NonLazy();
ΠΠ»ΡΡ Π² ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ΅ β (tag, serviceType)
. ΠΠ»Ρ ΠΏΠ°ΡΠ°Π»Π»Π΅Π»ΡΠ½ΡΡ
ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΉ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ ΡΠ΅Π³ΠΈ:
scene.RegisterType<IClock, UtcClock>("utc").AsSingle().NonLazy();
scene.RegisterType<IClock, GameClock>("game").AsSingle().NonLazy();
ΠΠ½ΡΠ΅ΠΊΡΠΈΡ Π½ΡΠΆΠ½ΠΎΠΉ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΡΠ΅ΡΠ΅Π· [Tag]
:
public sealed class AttrConsumer
{
public IStorage File { get; }
public IClock Clock { get; }
[InjectionConstructor]
public AttrConsumer([Tag("file")] IStorage file, [Tag("utc")] IClock clock)
{
File = file;
Clock = clock;
}
}
Π‘Π±ΠΎΡ Π²ΡΠ΅Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ°:
scene.RegisterType<IProcessor, ProcA>("proc_a").AsSingle();
scene.RegisterType<IProcessor, ProcB>("proc_b").AsSingle();
scene.Register(c => new ProcessorAggregator(c.ResolveAll<IProcessor>().ToArray()))
.AsSingle()
.NonLazy();
ΠΠΎΠΆΠ½ΠΎ Π·Π°ΠΌΠ΅Π½ΠΈΡΡ ΠΏΡΠΈΠ²ΡΠ·ΠΊΡ (ΡΠ΄ΠΎΠ±Π½ΠΎ Π΄Π»Ρ ΠΌΠΎΠΊΠΎΠ² Π² ΡΠ΅ΡΡΠΎΠ²ΠΎΠΉ ΡΡΠ΅Π½Π΅):
scene.RegisterType<IReplaceSample, ReplaceA>().AsSingle();
scene.Replace<IReplaceSample>(c => new ReplaceB()).AsSingle().NonLazy();
Π£ΡΠΈΠ»ΠΈΡΡ DiUnity
β Π΄Π»Ρ ΡΡΠ΅ΠΏΠ»Π΅Π½ΠΈΡ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ° ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ²:
// ΠΠΎΠ²ΡΠΉ ΠΏΡΡΡΠΎΠΉ GO Ρ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠΌ
scene.BindNewGo<IFoo, FooMono>("FooGo", tag: "foo_go");
// ΠΠ½ΡΡΠ°Π½Ρ ΠΈΠ· ΠΏΡΠ΅ΡΠ°Π±Π° (UI ΠΈΠ»ΠΈ ΠΎΠ±ΡΡΠ½ΡΠΉ)
scene.BindPrefab<IFoo, FooMono>(widgetPrefab, parent, isUI: true, tag: "foo_widget");
// Π’ΠΎΠ»ΡΠΊΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ (Self) Π±Π΅Π· ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ°:
scene.BindPrefabSelf<HUD>(hudPrefab, parent);
ΠΠ°ΠΆΠ½ΠΎ: Π΅ΡΠ»ΠΈ Π±ΠΈΠ½Π΄ΠΈΡΠ΅ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠΎΠ² ΠΎΠ΄Π½ΠΎΠ³ΠΎ
MonoBehaviour
, Π΄Π°Π²Π°ΠΉΡΠ΅ ΡΠ°Π·Π½ΡΠ΅ ΡΠ΅Π³ΠΈ, ΠΈΠ½Π°ΡΠ΅ Π±ΡΠ΄Π΅Ρ ΠΊΠΎΠ»Π»ΠΈΠ·ΠΈΡ ΠΊΠ»ΡΡΠ΅ΠΉ.
- ΠΡΠ»ΠΈ Ρ ΠΊΠ»Π°ΡΡΠ° ΠΎΠ΄ΠΈΠ½ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ β ΠΎΠ½ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ.
- ΠΡΠ»ΠΈ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡΠΎΠ² Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ β ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΏΠΎΠΌΠ΅ΡΠΈΡΡ Π½ΡΠΆΠ½ΡΠΉ
[InjectionConstructor]
. - ΠΠ»Ρ Π²ΡΠ±ΠΎΡΠ° ΠΏΠΎ ΡΠ΅Π³Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅
[Tag("...")]
Ρ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ°.
var nav = project.Resolve<IGameNavigation>();
var ok = scene.TryResolve<IFoo>(out var foo, tag: "foo_widget");
var has = scene.HasRegistration<IEnemySpawner>();
var all = scene.ResolveAll<IProcessor>(); // Π°Π³ΡΠ΅Π³ΠΈΡΡΠ΅Ρ ΡΠ΅ΡΠ΅Π· ΡΠ΅Π³ΠΈΡΡΡ/ΡΠΎΠ΄ΠΈΡΠ΅Π»Ρ
-
DiProvider.Project
β Ρ ΡΠ°Π½ΠΈΡ ΠΏΡΠΎΠ΅ΠΊΡΠ½ΡΠΉ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ (Π²Ρ ΡΠΎΠ·Π΄Π°ΡΡΠ΅ Π΅Π³ΠΎ ΡΠ°ΠΌΠΈ Π²Bootstrapper
/ProjectContext
). -
ΠΡΠΈ Π·Π°Π³ΡΡΠ·ΠΊΠ΅ ΡΡΠ΅Π½Ρ
SceneContext
Π²ΡΠ·ΡΠ²Π°Π΅ΡDiProvider.SceneContextBuilder(parent, sceneName, containerName)
β ΡΠΎΠ·Π΄Π°ΡΡΡΡ ΡΡΠ΅Π½ΠΎΠ²ΠΎΠΉ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ, ΠΊΡΡΠΈΡΡΠ΅ΡΡΡ ΠΏΠΎ handle ΡΡΠ΅Π½Ρ ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΡΠΎΠ΄ΠΈΡΠ΅Π»Π΅ΠΌ Project. -
ΠΠ°
SceneManager.sceneUnloaded
ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ ΡΡΠ΅Π½Ρ Dispose()-ΠΈΡΡΡ ΠΈ ΡΠ½ΠΈΠΌΠ°Π΅ΡΡΡ Ρ ΠΊΡΡΠ°. -
ΠΠΎΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠΎΠ²:
- Π°ΠΊΡΠΈΠ²Π½ΠΎΠΉ ΡΡΠ΅Π½Ρ:
DiProvider.GetCurrentSceneContainer()
- ΠΏΠΎ ΡΡΡΠ»ΠΊΠ΅ Π½Π° ΡΡΠ΅Π½Ρ:
scene.GetSceneContainer()
- ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ:
DiProvider.GetSceneContainerBySceneName("Gameplay")
- Π°ΠΊΡΠΈΠ²Π½ΠΎΠΉ ΡΡΠ΅Π½Ρ:
ΠΠΎΠΆΠ½ΠΎ ΡΠΎΠ±ΡΠ°ΡΡ ΡΡΠ΅Π½ΠΎΠ²ΠΎΠΉ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ Π²ΡΡΡΠ½ΡΡ (Π΅ΡΠ»ΠΈ ΡΡΡΠΎΠΈΡΠ΅ ΡΠ²ΠΎΡ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΠ΅ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ Π·Π°Π³ΡΡΠ·ΠΊΠΎΠΉ): Π²ΡΠ·ΠΎΠ²ΠΈΡΠ΅ DiProvider.SceneContextBuilder(projectContainer, sceneName)
Π² ΠΌΠΎΠΌΠ΅Π½Ρ, ΠΊΠΎΠ³Π΄Π° ΡΡΠ΅Π½Π° ΡΠΆΠ΅ Π²Π°Π»ΠΈΠ΄Π½Π° (ΠΎΠ±ΡΡΠ½ΠΎ ΠΏΠΎΡΠ»Π΅ LoadSceneAsync
ΠΈ ΠΏΠ΅ΡΠ΅Π΄ ΠΏΠ΅ΡΠ²ΡΠΌ ΠΊΠ°Π΄ΡΠΎΠΌ).
- ΠΠ½ΡΠΏΠ΅ΠΊΡΠΎΡ
SceneContext
Π² Play Mode ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°Π΅Ρ ΡΠ΅Π΅ΡΡΡ Π±ΠΈΠ½Π΄ΠΈΠ½Π³ΠΎΠ² ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ° ΡΡΠ΅Π½Ρ. - ΠΠ½ΡΠΏΠ΅ΠΊΡΠΎΡ ΠΈΠ½ΡΡΠ°Π»Π»Π΅ΡΠΎΠ² (
SceneInstallerSO
) ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅Ρ ΠΏΡΠ΅Π΄ΠΏΡΠΎΡΠΌΠΎΡΡ ΡΠ΅ΡΠ΅Π·PreviewHints()
. - ΠΠΊΠ½ΠΎ Tools β CuteDI β DI Debugger β Π±ΡΡΡΡΡΠΉ ΠΏΡΠΎΡΠΌΠΎΡΡ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ³ΠΎ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠΎΠ² (ΠΏΡΠΎΠ΅ΠΊΡ/ΡΡΠ΅Π½Π°/Prefab Stage), ΡΠΈΠ»ΡΡΡ ΠΏΠΎ ΡΠΈΠΏΡ/ΡΠ΅Π³Ρ.
Π ΡΡΠ΅Π½Π΅ Other
Π»Π΅ΠΆΠΈΡ AllBindingsInstaller
β Π΄Π΅ΠΌΠΎΠ½ΡΡΡΠ°ΡΠΈΡ:
RegisterType / RegisterInstance / Register(factory)
- ΡΠ΅Π³ΠΈ ΠΈ
[Tag]
ResolveAll<T>()
Replace<T>()
BindNewGo / BindPrefab / BindPrefabSelf
ΠΠ»ΡΡ Π² ΠΏΡΠΈΠΌΠ΅ΡΠ΅ SceneHintUI
(Π±ΠΎΠ»ΡΡΠΈΠ΅ ΠΏΠΎΠ΄ΡΠΊΠ°Π·ΠΊΠΈ Π½Π° ΡΠΊΡΠ°Π½Π΅) Ρ ΠΊΠ»Π°Π²ΠΈΡΠ°ΠΌΠΈ:
[1]
β MainMenu[2]
β Gameplay[3]
β Other
- ΠΠ»ΡΡ ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΠΈ β
(tag, serviceType)
. ΠΠ»Ρ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΉ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ ΡΠ΅Π³ΠΈ. BindOnGo
Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΠΎΠ»ΡΡΠ°ΡΡ ΡΡΠ΅Π½ΠΎΠ²ΡΠΉ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ. ΠΠ»Ρ Π°ΡΡΠ΅ΡΠΎΠ² ΠΈ ΠΏΡΠ΅ΡΠ°Π±ΠΎΠ² ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅BindPrefab*
.- ΠΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ ΡΡΠ΅Π½Ρ ΡΠ΄Π°Π»ΡΠ΅ΡΡΡ ΠΏΡΠΈ Π²ΡΠ³ΡΡΠ·ΠΊΠ΅ ΡΡΠ΅Π½Ρ (
Dispose()
); ΠΏΡΠΎΠ΅ΠΊΡΠ½ΡΠΉ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ ΠΆΠΈΠ²ΡΡ Π΄ΠΎ ΠΊΠΎΠ½ΡΠ° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. - Π€ΡΠ΅ΠΉΠΌΠ²ΠΎΡΠΊ Π½Π΅ ΠΏΠΎΡΠΎΠΊΠΎΠ±Π΅Π·ΠΎΠΏΠ°ΡΠ΅Π½; ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ Π² ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΌ ΠΏΠΎΡΠΎΠΊΠ΅ Unity.
MIT. ΠΠΎΠ΄ΡΠΎΠ±Π½ΠΎΡΡΠΈ β Π² LICENSE
.