155 lines
5.5 KiB
C#
155 lines
5.5 KiB
C#
![]() |
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<Collider>(out var collider) is false)
|
||
|
{
|
||
|
var boxCollider = transform.gameObject.AddComponent<BoxCollider>();
|
||
|
|
||
|
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<Rigidbody>();
|
||
|
|
||
|
var collider = model.GetComponent<Collider>();
|
||
|
|
||
|
|
||
|
|
||
|
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);
|
||
|
}
|
||
|
}
|
||
|
}
|