第一次尝试使用 Zenject,但它没有在一个类中注入对象。
这是 [Inject] 不起作用的类:
using UnityEngine;
public class StaticDisappearing : PlatformModificator
{
[Inject] private PlatformDestroyer _platformDestroyer;
public StaticDisappearing(Platform platform) : base(platform)
{
}
public override void Init()
{
base.Init();
Platform.PlayerStepped += DestroyPlatform;
}
public override void Destroy()
{
base.Destroy();
Platform.PlayerStepped -= DestroyPlatform;
}
private void DestroyPlatform()
{
Debug.Log(_platformDestroyer); // out null
_platformDestroyer.DestroyPlatform(Platform); // null reference exception
}
}
这是安装程序:
using Zenject;
public class GameInstaller : MonoInstaller<GameInstaller>
{
public override void InstallBindings()
{
Container.Bind<PlatformSpawner>().AsSingle();
Container.Bind<PlatformDestroyer>().AsSingle();
}
}
这是工作代码:
using UnityEngine;
using Zenject;
public class Core : MonoBehaviour
{
[SerializeField] private Platform _platformPrefab;
[SerializeField] private Transform _platformParent;
private IPlatformFactory _platformFactory;
[Inject] private PlatformSpawner _platformSpawner;
[Inject] private PlatformDestroyer _platformDestroyer;
private void Start()
{
_platformFactory = new DefaultPlatformFactory(_platformPrefab, _platformParent);
for (int i = 0; i < 30; i++)
{
_platformSpawner.SpawnRandomPlatform(_platformFactory);
}
Debug.Log(_platformDestroyer);
}
private void Update()
{
_platformDestroyer.Update();
if (Input.GetKeyDown(KeyCode.Q))
{
_platformSpawner.SpawnRandomPlatform(_platformFactory);
}
}
}
平台生成器:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
public class PlatformSpawner
{
public event Action<Platform> PlatformSpawned;
private readonly ModifiedPlatformFactory _factory;
private Vector2 _previousPosition;
private const float YOffset = 5f;
public PlatformSpawner()
{
_factory = new ModifiedPlatformFactory();
}
public void SpawnRandomPlatform(IPlatformFactory platformFactory)
{
var platform = _factory.Spawn(GetRandomPlatformType(), platformFactory);
var randomXPosition = UnityEngine.Random.Range(CameraBounds.MinBounds.x, CameraBounds.MaxBounds.x);
if (_previousPosition == Vector2.zero)
{
platform.transform.position = new Vector2(randomXPosition, CameraBounds.MinBounds.y + 1f);
}
else
{
platform.transform.position = new Vector2(randomXPosition, _previousPosition.y + YOffset);
}
platform.Init();
_previousPosition = platform.transform.position;
PlatformSpawned?.Invoke(platform);
}
private PlatformType GetRandomPlatformType()
{
return (PlatformType)UnityEngine.Random.Range(0, Enum.GetValues(typeof(PlatformType)).Length);
}
}
平台毁灭者:
using System.Collections.Generic;
using Zenject;
public class PlatformDestroyer
{
public event Action<Platform> PlatformDestroyed;
private List<Platform> _spawnedPlatforms;
private IBorderTouchAwaiter _borderTouchAwaiter;
public PlatformDestroyer()
{
_spawnedPlatforms = new List<Platform>();
_borderTouchAwaiter = new LowerBorderTouchAwaiter();
}
[Inject]
public void Construct(PlatformSpawner spawner)
{
spawner.PlatformSpawned += AddPlatform;
}
private void AddPlatform(Platform platform)
{
_spawnedPlatforms.Add(platform);
_borderTouchAwaiter.BorderTouched += delegate { DestroyPlatform(platform); };
}
public void DestroyPlatform(Platform platform)
{
_spawnedPlatforms.Remove(platform);
_borderTouchAwaiter.BorderTouched -= delegate { DestroyPlatform(platform); };
platform.Destroy();
PlatformDestroyed?.Invoke(platform);
}
//inefficient, for tests only
public void Update()
{
foreach (var p in _spawnedPlatforms)
{
_borderTouchAwaiter.WaitTouch(p.transform.position);
}
}
}
任何注射方法都不起作用。试图提取接口并绑定它,在其他所有类中都可以正常工作,但在StaticDisappearing
.