using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Threading; using BITKit; using BITKit.Entities; using BITKit.Tween; using Cysharp.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Net.Project.B.Interaction; using Project.B.Entities; using Project.B.Map; using Unity.Mathematics; using UnityEngine; using Object = UnityEngine.Object; namespace Net.Project.B.WorldNode { public class ScriptableHelicopterEvacuate : ScriptableEvacuate { [SerializeField] private Transform mark; [SerializeField] private Transform helicopter; public override async void Initialize(IEntity entity) { entity.ServiceProvider.QueryComponents(out Transform transform); if (entity.ServiceProvider.QueryComponents(out IWorldInteractable interactable) is false) { BITApp.ServiceProvider.QueryComponents(out IEntitiesService entitiesService); entitiesService.UnRegister(entity); var newEntity = new Entity() { Id = entity.Id, CancellationToken = entity.CancellationToken, }; newEntity.ServiceCollection.Add(entity.ServiceCollection); interactable = new WorldInteractable(); newEntity.ServiceCollection.AddSingleton(interactable); if (transform.TryGetComponent(out var collider) is false) { var boxCollider = transform.gameObject.AddComponent(); boxCollider.center = new Vector3(0, 0.5f, 0); collider = boxCollider; collider.isTrigger = true; newEntity.ServiceCollection.AddSingleton(collider); } await UniTask.NextFrame(); entitiesService.Register(newEntity); return; } var position = transform.position; foreach (var raycastHit in Physics .RaycastAll(position+Vector3.up, Vector3.down, 8,~0,QueryTriggerInteraction.Ignore) .OrderBy(x=>Vector3.Distance(position,x.point)) ) { if(raycastHit.transform == transform)continue; position = raycastHit.point; break; } transform.position = position; Instantiate(mark, position, transform.rotation, transform); } public override async UniTask Invoke(IEntity entity,CancellationToken cancellationToken) { BITApp.ServiceProvider.QueryComponents(out IEntitiesService entitiesService,out IPlayerFactory playerFactory,out IGameMapService gameMapService); entity.ServiceProvider.QueryComponents(out Transform transform,out UnityEvacuateNode evacuateNode); if (evacuateNode.EvacuateType is not HelicopterEvacuate helicopterEvacuate) { Debug.LogError("EvacuateType is not HelicopterEvacuate"); return; } var position = transform.position; var op =Object.InstantiateAsync(helicopter); await op; var model = op.Result[0]; var rigidbody = model.GetComponent(); var collider = model.GetComponent(); var upPosition = position + Vector3.up * 16; var startPosition = upPosition - Vector3.forward * 64 + Vector3.up * 8; var farPosition = upPosition + Vector3.forward * 32 + Vector3.up * 8; model.position = upPosition; try { await BITween.MoveToForward(rigidbody.MovePosition, startPosition, upPosition, 8,Vector3.MoveTowards,cancellationToken); await BITween.MoveToForward(rigidbody.MovePosition, upPosition, position, 3,Vector3.MoveTowards,cancellationToken); await UniTask.Delay(TimeSpan.FromSeconds(helicopterEvacuate.time),cancellationToken:cancellationToken); await BITween.MoveToForward(x=>rigidbody.velocity=x-rigidbody.position, position, upPosition, 3,Vector3.MoveTowards,cancellationToken); await BITween.MoveToForward(x=>rigidbody.velocity=x-rigidbody.position, upPosition, farPosition, 8,Vector3.MoveTowards,cancellationToken); Destroy(model.gameObject); var isPlayer = false; // ReSharper disable once Unity.PreferNonAllocApi foreach (var x in Physics.OverlapBox(collider.bounds.center, collider.bounds.extents)) { if (playerFactory.Entities.ContainsKey(x.gameObject.GetInstanceID())) { isPlayer = true; } Destroy(x.gameObject); } await UniTask.Delay(TimeSpan.FromSeconds(3),cancellationToken:cancellationToken); if (isPlayer) { await gameMapService.StopMapAsync(); } } catch (OperationCanceledException) { return; } Destroy(this); } } }