Initial Commit

This commit is contained in:
2026-03-16 14:38:46 +02:00
commit b8f7327a21
2327 changed files with 253610 additions and 0 deletions
@@ -0,0 +1,19 @@
namespace Zenject.SpaceFighter
{
public class EnemyInstaller : Installer<EnemyInstaller>
{
public override void InstallBindings()
{
Container.Bind<EnemyTunables>().AsSingle();
Container.BindInterfacesAndSelfTo<EnemyStateManager>().AsSingle();
Container.Bind<EnemyStateIdle>().AsSingle();
Container.Bind<EnemyStateAttack>().AsSingle();
Container.Bind<EnemyStateFollow>().AsSingle();
Container.BindInterfacesAndSelfTo<EnemyDeathHandler>().AsSingle();
Container.BindInterfacesAndSelfTo<EnemyRotationHandler>().AsSingle();
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: ba7d60db0911cee42bd0cba6d4ed9b85
timeCreated: 1456415201
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,80 @@
using System;
using UnityEngine;
namespace Zenject.SpaceFighter
{
// Main installer for our game
public class GameInstaller : MonoInstaller
{
[Inject]
Settings _settings = null;
public override void InstallBindings()
{
Container.BindInterfacesAndSelfTo<EnemySpawner>().AsSingle();
Container.BindFactory<float, float, EnemyFacade, EnemyFacade.Factory>()
// We could just use FromMonoPoolableMemoryPool here instead, but
// for IL2CPP to work we need our pool class to be used explicitly here
.FromPoolableMemoryPool<float, float, EnemyFacade, EnemyFacadePool>(poolBinder => poolBinder
// Spawn 5 enemies right off the bat so that we don't incur spikes at runtime
.WithInitialSize(5)
.FromSubContainerResolve()
.ByNewPrefabInstaller<EnemyInstaller>(_settings.EnemyFacadePrefab)
// Place each enemy under an Enemies game object at the root of scene hierarchy
.UnderTransformGroup("Enemies"));
Container.BindFactory<float, float, BulletTypes, Bullet, Bullet.Factory>()
// We could just use FromMonoPoolableMemoryPool here instead, but
// for IL2CPP to work we need our pool class to be used explicitly here
.FromPoolableMemoryPool<float, float, BulletTypes, Bullet, BulletPool>(poolBinder => poolBinder
// Spawn 20 right off the bat so that we don't incur spikes at runtime
.WithInitialSize(20)
// Bullets are simple enough that we don't need to make a subcontainer for them
// The logic can all just be in one class
.FromComponentInNewPrefab(_settings.BulletPrefab)
.UnderTransformGroup("Bullets"));
Container.Bind<LevelBoundary>().AsSingle();
Container.BindFactory<Explosion, Explosion.Factory>()
// We could just use FromMonoPoolableMemoryPool here instead, but
// for IL2CPP to work we need our pool class to be used explicitly here
.FromPoolableMemoryPool<Explosion, ExplosionPool>(poolBinder => poolBinder
// Spawn 4 right off the bat so that we don't incur spikes at runtime
.WithInitialSize(4)
.FromComponentInNewPrefab(_settings.ExplosionPrefab)
.UnderTransformGroup("Explosions"));
Container.Bind<AudioPlayer>().AsSingle();
Container.BindInterfacesTo<GameRestartHandler>().AsSingle();
Container.Bind<EnemyRegistry>().AsSingle();
GameSignalsInstaller.Install(Container);
}
[Serializable]
public class Settings
{
public GameObject EnemyFacadePrefab;
public GameObject BulletPrefab;
public GameObject ExplosionPrefab;
}
// We could just use FromMonoPoolableMemoryPool above, but we have to use these instead
// for IL2CPP to work
class EnemyFacadePool : MonoPoolableMemoryPool<float, float, IMemoryPool, EnemyFacade>
{
}
class BulletPool : MonoPoolableMemoryPool<float, float, BulletTypes, IMemoryPool, Bullet>
{
}
class ExplosionPool : MonoPoolableMemoryPool<IMemoryPool, Explosion>
{
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: e432172e250876f4ab278b0d24d58673
timeCreated: 1456414615
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,71 @@
using System;
namespace Zenject.SpaceFighter
{
// We prefer to use ScriptableObjectInstaller for installers that contain game settings
// There's no reason why you couldn't use a MonoInstaller here instead, however
// using ScriptableObjectInstaller has advantages here that make it nice for settings:
//
// 1) You can change these values at runtime and have those changes persist across play
// sessions. If it was a MonoInstaller then any changes would be lost when you hit stop
// 2) You can easily create multiple ScriptableObject instances of this installer to test
// different customizations to settings. For example, you might have different instances
// for each difficulty mode of your game, such as "Easy", "Hard", etc.
// 3) If your settings are associated with a game object composition root, then using
// ScriptableObjectInstaller can be easier since there will only ever be one definitive
// instance for each setting. Otherwise, you'd have to change the settings for each game
// object composition root separately at runtime
//
// Uncomment if you want to add alternative game settings
//[CreateAssetMenu(menuName = "Space Fighter/Game Settings")]
public class GameSettingsInstaller : ScriptableObjectInstaller<GameSettingsInstaller>
{
public EnemySpawner.Settings EnemySpawner;
public GameRestartHandler.Settings GameRestartHandler;
public GameInstaller.Settings GameInstaller;
public PlayerSettings Player;
public EnemySettings Enemy;
[Serializable]
public class PlayerSettings
{
public PlayerMoveHandler.Settings PlayerMoveHandler;
public PlayerShootHandler.Settings PlayerShootHandler;
public PlayerDamageHandler.Settings PlayerCollisionHandler;
public PlayerHealthWatcher.Settings PlayerHealthWatcher;
}
[Serializable]
public class EnemySettings
{
public EnemyTunables DefaultSettings;
public EnemyStateIdle.Settings EnemyStateIdle;
public EnemyRotationHandler.Settings EnemyRotationHandler;
public EnemyStateFollow.Settings EnemyStateFollow;
public EnemyStateAttack.Settings EnemyStateAttack;
public EnemyDeathHandler.Settings EnemyHealthWatcher;
public EnemyCommonSettings EnemyCommonSettings;
}
public override void InstallBindings()
{
// Use IfNotBound to allow overriding for eg. from play mode tests
Container.BindInstance(EnemySpawner).IfNotBound();
Container.BindInstance(GameRestartHandler).IfNotBound();
Container.BindInstance(GameInstaller).IfNotBound();
Container.BindInstance(Player.PlayerMoveHandler).IfNotBound();
Container.BindInstance(Player.PlayerShootHandler).IfNotBound();
Container.BindInstance(Player.PlayerCollisionHandler).IfNotBound();
Container.BindInstance(Player.PlayerHealthWatcher).IfNotBound();
Container.BindInstance(Enemy.EnemyStateIdle).IfNotBound();
Container.BindInstance(Enemy.EnemyRotationHandler).IfNotBound();
Container.BindInstance(Enemy.EnemyStateFollow).IfNotBound();
Container.BindInstance(Enemy.EnemyStateAttack).IfNotBound();
Container.BindInstance(Enemy.EnemyHealthWatcher).IfNotBound();
Container.BindInstance(Enemy.EnemyCommonSettings).IfNotBound();
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 1db4d8ab51ca4ad48844c113bfbd80fa
timeCreated: 1461784513
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,29 @@
using UnityEngine;
namespace Zenject.SpaceFighter
{
// Include this just to ensure BindSignal with an object mapping works
public class PlayerDiedSignalObserver
{
public void OnPlayerDied()
{
Debug.Log("Fired PlayerDiedSignal");
}
}
public class GameSignalsInstaller : Installer<GameSignalsInstaller>
{
public override void InstallBindings()
{
SignalBusInstaller.Install(Container);
Container.DeclareSignal<EnemyKilledSignal>();
Container.DeclareSignal<PlayerDiedSignal>();
// Include these just to ensure BindSignal works
Container.BindSignal<PlayerDiedSignal>().ToMethod<PlayerDiedSignalObserver>(x => x.OnPlayerDied).FromNew();
Container.BindSignal<EnemyKilledSignal>().ToMethod(() => Debug.Log("Fired EnemyKilledSignal"));
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 23aa26bc747410a40ac441fedb64f05d
timeCreated: 1506513911
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,34 @@
using System;
using UnityEngine;
namespace Zenject.SpaceFighter
{
public class PlayerInstaller : MonoInstaller
{
[SerializeField]
Settings _settings = null;
public override void InstallBindings()
{
Container.Bind<Player>().AsSingle()
.WithArguments(_settings.Rigidbody, _settings.MeshRenderer);
Container.BindInterfacesTo<PlayerInputHandler>().AsSingle();
Container.BindInterfacesTo<PlayerMoveHandler>().AsSingle();
Container.BindInterfacesAndSelfTo<PlayerDamageHandler>().AsSingle();
Container.BindInterfacesTo<PlayerDirectionHandler>().AsSingle();
Container.BindInterfacesTo<PlayerShootHandler>().AsSingle();
Container.Bind<PlayerInputState>().AsSingle();
Container.BindInterfacesTo<PlayerHealthWatcher>().AsSingle();
}
[Serializable]
public class Settings
{
public Rigidbody Rigidbody;
public MeshRenderer MeshRenderer;
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: ff1b44a433bb75344a686526fba7452b
timeCreated: 1456415489
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: