1
This commit is contained in:
174
Assets/Artists/Scripts/YangdunCreateFactory.cs
Normal file
174
Assets/Artists/Scripts/YangdunCreateFactory.cs
Normal file
@@ -0,0 +1,174 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Animancer;
|
||||
using BITKit;
|
||||
using BITKit.Entities;
|
||||
using BITKit.GameSocket;
|
||||
using BITKit.WorldNode;
|
||||
using Cinemachine;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Lightbug.CharacterControllerPro.Core;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Net.Project.B.Health;
|
||||
using Net.Project.B.Interaction;
|
||||
using Net.Project.B.Inventory;
|
||||
using Net.Project.B.Weapon;
|
||||
using NodeCanvas.Framework;
|
||||
using Project.B.Animation;
|
||||
using Project.B.CharacterController;
|
||||
using Project.B.Entities;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
using Object = UnityEngine.Object;
|
||||
namespace Net.Like.Xue.Tokyo
|
||||
{
|
||||
public class YangdunCreateFactory : IPlayerFactory
|
||||
{
|
||||
private readonly ILogger<PlayerFactory> _logger;
|
||||
private readonly IServiceCollection _serviceCollection;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IWorldNodeService _worldNodeService;
|
||||
private const string PlayerPath = "Player_Base";
|
||||
private readonly List<(IEntity entity,GameObject go)> _entities = new();
|
||||
private readonly IHealthService _healthService;
|
||||
private GameObject _playerPrefab;
|
||||
private readonly InputActionGroup _inputActionGroup=new();
|
||||
|
||||
private UniTaskCompletionSource<WorldInfoPlayerStart> _waitPlayerStart=new();
|
||||
|
||||
public YangdunCreateFactory(IServiceProvider serviceProvider, IServiceCollection serviceCollection, IWorldNodeService worldNodeService, ILogger<PlayerFactory> logger, IHealthService healthService)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
_serviceCollection = serviceCollection;
|
||||
_worldNodeService = worldNodeService;
|
||||
_logger = logger;
|
||||
_healthService = healthService;
|
||||
|
||||
_worldNodeService.OnNodeRegistered += OnNodeRegistered;
|
||||
|
||||
_healthService.OnHealthChanged+=OnHealthChanged;
|
||||
}
|
||||
|
||||
private void OnNodeRegistered(IWorldNode obj)
|
||||
{
|
||||
if(obj is not WorldInfoPlayerStart infoPlayerStart)return;
|
||||
_waitPlayerStart.TrySetResult(infoPlayerStart);
|
||||
}
|
||||
|
||||
public async UniTask<IEntity> CreateAsync(string addressablePath)
|
||||
{
|
||||
await UniTask.SwitchToMainThread();
|
||||
if (_playerPrefab is not null)
|
||||
{
|
||||
return await Create(addressablePath);
|
||||
}
|
||||
var asyncHandle = YooAssets.LoadAssetAsync<GameObject>(PlayerPath);
|
||||
await asyncHandle;
|
||||
_playerPrefab = asyncHandle.AssetObject as GameObject;
|
||||
|
||||
return await Create(addressablePath);
|
||||
}
|
||||
|
||||
public event Func<string, IEntity,UniTask> OnEntityCreate;
|
||||
public event Func<string, IEntity,UniTask> OnEntityCreated;
|
||||
|
||||
private async UniTask<IEntity> Create(string addressablePath = null)
|
||||
{
|
||||
var entity = new Entity();
|
||||
|
||||
var startNode = await _waitPlayerStart.Task;
|
||||
var startTransform = startNode.WorldObject.As<GameObject>().transform;
|
||||
|
||||
_waitPlayerStart = new();
|
||||
|
||||
var go = Object.Instantiate(_playerPrefab,startTransform.position,startTransform.rotation);
|
||||
|
||||
entity.ServiceCollection.Add(_serviceCollection);
|
||||
|
||||
go.GetCancellationTokenOnDestroy().Register(entity.Dispose);
|
||||
|
||||
entity.ServiceCollection.AddSingleton<IEntity>(entity);
|
||||
|
||||
entity.ServiceCollection.AddSingleton(go);
|
||||
entity.ServiceCollection.AddSingleton(go.transform);
|
||||
|
||||
entity.ServiceCollection.AddSingleton(go.GetComponent<IBlackboard>());
|
||||
|
||||
entity.ServiceCollection.AddSingleton(go.GetComponent<CharacterActor>());
|
||||
entity.ServiceCollection.AddSingleton(go.GetComponentInChildren<CinemachineVirtualCameraBase>());
|
||||
entity.ServiceCollection.AddSingleton<IAnimancerComponent>(go.GetComponent<AnimancerComponent>());
|
||||
|
||||
entity.ServiceCollection.AddSingleton<IPlayerCharacterController, PlayerCharacterController>();
|
||||
entity.ServiceCollection.AddSingleton<ICharacterController>(x=>x.GetRequiredService<IPlayerCharacterController>().CharacterController);
|
||||
|
||||
entity.ServiceCollection.AddSingleton(_inputActionGroup);
|
||||
|
||||
|
||||
entity.ServiceCollection.AddSingleton<ICharacterStateWalk, CharacterWalkState>();
|
||||
entity.ServiceCollection.AddSingleton<ICharacterStateIdle, CharacterIdleState>();
|
||||
entity.ServiceCollection.AddSingleton<ICharacterStateCrouched, CharacterCrouchedState>();
|
||||
entity.ServiceCollection.AddSingleton<ICharacterStateRun, CharacterRunState>();
|
||||
entity.ServiceCollection.AddSingleton<ICharacterSprint, CharacterSprintState>();
|
||||
entity.ServiceCollection.AddSingleton<ICharacterStateStepUp, CharacterStepUpState>();
|
||||
entity.ServiceCollection.AddSingleton<ICharacterKnocked, CharacterKnockedState>();
|
||||
|
||||
entity.ServiceCollection.AddSingleton<PlayerCameraController>();
|
||||
entity.ServiceCollection.AddSingleton<PlayerModelController>();
|
||||
|
||||
entity.ServiceCollection.AddSingleton<PlayerAnimancerController>();
|
||||
|
||||
entity.ServiceCollection.AddSingleton(_serviceProvider.GetRequiredService<IWorldInteractionService>());
|
||||
entity.ServiceCollection.AddSingleton<PlayerInteractionController>();
|
||||
|
||||
|
||||
await OnEntityCreate.UniTaskFunc(addressablePath,entity);
|
||||
|
||||
entity.ServiceProvider.GetRequiredService<ICharacterStateWalk>();
|
||||
|
||||
entity.ServiceProvider.GetRequiredService<PlayerInteractionController>();
|
||||
|
||||
var characterController = entity.ServiceProvider.GetRequiredService<ICharacterController>();
|
||||
|
||||
characterController.TransitionState<ICharacterStateWalk>();
|
||||
|
||||
entity.ServiceProvider.GetRequiredService<PlayerAnimancerController>();
|
||||
|
||||
entity.ServiceProvider.GetRequiredService<PlayerCameraController>();
|
||||
|
||||
entity.ServiceProvider.GetRequiredService<PlayerModelController>();
|
||||
|
||||
|
||||
await OnEntityCreated.UniTaskFunc(addressablePath,entity);
|
||||
|
||||
_entities.Add(new ValueTuple<IEntity, GameObject>(entity,go));
|
||||
|
||||
_logger.LogInformation($"Player Created. {entity.Id}");
|
||||
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
public async void Dispose()
|
||||
{
|
||||
await UniTask.SwitchToMainThread();
|
||||
foreach (var (entity, go) in _entities)
|
||||
{
|
||||
if (entity is IDisposable disposable)
|
||||
{
|
||||
disposable.Dispose();
|
||||
}
|
||||
if (go)
|
||||
Object.Destroy(go);
|
||||
}
|
||||
_healthService.OnHealthChanged-=OnHealthChanged;
|
||||
}
|
||||
private void OnHealthChanged(int arg1, int arg2, int arg3, object arg4)
|
||||
{
|
||||
_inputActionGroup.allowInput.SetDisableElements(this,arg3<0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user