180 lines
5.5 KiB
C#
180 lines
5.5 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using BITKit;
|
|
using BITKit.Entities;
|
|
using Cinemachine;
|
|
using Cysharp.Threading.Tasks;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using ParadoxNotion;
|
|
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
|
|
namespace Net.Project.B.Dialogue
|
|
{
|
|
public class UnityDialogueCameraController : MonoBehaviour
|
|
{
|
|
[SerializeField] private CinemachineVirtualCameraBase virtualCamera;
|
|
|
|
[SerializeField] private bool allowPlayerInput;
|
|
|
|
[SerializeField] private bool isFixedCameraPosition;
|
|
|
|
private readonly ValidHandle _allowCamera = new();
|
|
|
|
private readonly Dictionary<int, IDialogueData> _dialogues = new();
|
|
|
|
private CancellationTokenSource _dialogueCancel;
|
|
|
|
private CinemachineTargetGroup _targetGroup;
|
|
|
|
private readonly ConcurrentDictionary<int, Transform> _actors = new();
|
|
|
|
private async void Start()
|
|
{
|
|
virtualCamera.enabled = false;
|
|
|
|
if (isFixedCameraPosition)
|
|
{
|
|
var newGameObject = new
|
|
GameObject(nameof(CinemachineTargetGroup))
|
|
{
|
|
transform =
|
|
{
|
|
parent = transform.parent
|
|
}
|
|
};
|
|
_targetGroup =newGameObject.AddComponent<CinemachineTargetGroup>();
|
|
virtualCamera.LookAt = _targetGroup.transform;
|
|
}
|
|
|
|
try
|
|
{
|
|
await BITApp.WalkUntilInitialize.Task.AttachExternalCancellation(destroyCancellationToken);
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
}
|
|
|
|
var dialogueService = BITApp.ServiceProvider.GetRequiredService<IDialogueService>();
|
|
|
|
dialogueService.OnDialogueStart += OnDialogueStart;
|
|
dialogueService.OnDialogueEnd += OnDialogueEnd;
|
|
|
|
_allowCamera.AddListener(x=>virtualCamera.enabled=x);
|
|
|
|
if (allowPlayerInput is false)
|
|
{
|
|
_allowCamera.AddListener(x => { BITInputSystem.AllowInput.SetDisableElements(this, x); });
|
|
}
|
|
|
|
await destroyCancellationToken.WaitUntilCanceled();
|
|
|
|
dialogueService.OnDialogueStart -= OnDialogueStart;
|
|
dialogueService.OnDialogueEnd -= OnDialogueEnd;
|
|
}
|
|
|
|
private async void OnDialogueEnd(IDialogueData arg)
|
|
{
|
|
_allowCamera.AddElement(64);
|
|
|
|
_dialogueCancel?.Cancel();
|
|
|
|
_dialogueCancel = new CancellationTokenSource();
|
|
|
|
_dialogues.TryRemove(arg.Identity);
|
|
|
|
_allowCamera.RemoveElement(arg.Identity);
|
|
|
|
try
|
|
{
|
|
await UniTask.Delay(512, cancellationToken: _dialogueCancel.Token);
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
if (_dialogues.Count is not 0)
|
|
return;
|
|
}
|
|
|
|
_allowCamera.RemoveElement(64);
|
|
|
|
try
|
|
{
|
|
if (isFixedCameraPosition)
|
|
{
|
|
if (_actors.TryGetValue(arg.ActorIdentity, out var actor))
|
|
{
|
|
await UniTask.Delay(1000, cancellationToken: destroyCancellationToken);
|
|
if (actor)
|
|
{
|
|
_targetGroup.RemoveMember(actor);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch ( OperationCanceledException)
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
private UniTask OnDialogueStart(IDialogueData arg)
|
|
{
|
|
_allowCamera.AddElement(arg.Identity);
|
|
|
|
SetCameraLook(arg);
|
|
|
|
_dialogues.TryAdd(arg.Identity, arg);
|
|
|
|
return UniTask.CompletedTask;
|
|
}
|
|
|
|
private void SetCameraLook(IDialogueData arg)
|
|
{
|
|
var entitiesService = BITApp.ServiceProvider.GetRequiredService<IEntitiesService>();
|
|
|
|
if (_allowCamera.Allow)
|
|
{
|
|
if (_actors.TryGetValue(arg.ActorIdentity, out var actor))
|
|
{
|
|
if (isFixedCameraPosition)
|
|
{
|
|
_targetGroup.AddMember(actor,1,1);
|
|
}
|
|
else
|
|
{
|
|
virtualCamera.LookAt = actor;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (entitiesService.TryGetEntity(arg.ActorIdentity, out var entity) is false)
|
|
{
|
|
foreach (var (id,localPlayer) in entitiesService.QueryComponents<IdComponent,LocalPlayerComponent>())
|
|
{
|
|
entitiesService.TryGetEntity(id.Id, out entity);
|
|
}
|
|
}
|
|
if (entity.ServiceProvider.GetService<Transform>() is { } entityTransform)
|
|
{
|
|
if (isFixedCameraPosition)
|
|
{
|
|
_targetGroup.AddMember(entityTransform,1,1);
|
|
}
|
|
else
|
|
{
|
|
virtualCamera.LookAt = virtualCamera.Follow = entityTransform;
|
|
}
|
|
|
|
_actors.TryAdd(arg.ActorIdentity, entityTransform);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|