BITFALL/Assets/Artists/Scripts/Entities/Selector/EntityInteractive.cs

210 lines
6.6 KiB
C#
Raw Normal View History

2023-10-20 19:31:12 +08:00
using System;
2024-01-03 00:27:12 +08:00
using BITFALL.Hotkey;
2023-11-30 00:23:23 +08:00
using BITKit.PlayerCamera;
2023-10-20 19:31:12 +08:00
using BITKit.Selection;
2023-10-02 23:24:56 +08:00
using BITKit.Sensors;
using BITKit.UX;
2023-08-23 01:59:40 +08:00
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Interactions;
2023-08-27 02:58:19 +08:00
namespace BITKit.Entities.Player
2023-08-23 01:59:40 +08:00
{
2023-10-20 19:31:12 +08:00
[CustomType(typeof(ISelector))]
2024-01-03 00:27:12 +08:00
public class EntityInteractive : EntityPlayerBehavior,ISelector,IHotkeyProvider
2023-08-23 01:59:40 +08:00
{
[Header(Constant.Header.Settings)]
2023-10-02 23:24:56 +08:00
[SerializeReference, SubclassSelector] private ISensor sensor;
2023-08-23 01:59:40 +08:00
2023-11-30 00:23:23 +08:00
[Header(Constant.Header.Gameobjects)]
[SerializeField] private Transform sensorTransform;
2024-02-21 01:40:53 +08:00
[Header(Constant.Header.Input)]
[SerializeField] private InputActionReference interactiveAction;
2023-08-23 01:59:40 +08:00
[Header(Constant.Header.InternalVariables)]
private ISelectable selected;
private IntervalUpdate cd = new(0.08f);
2023-10-20 19:31:12 +08:00
[Inject]
private IHealth _health;
2023-11-30 00:23:23 +08:00
[Inject(true)] private IEntityMovement _movement;
[Inject(true)] IPlayerCameraService _cameraService;
[Inject(true)] private IUXPopup _popup;
2024-01-03 00:27:12 +08:00
[Inject(true)] private IHotkeyCollection _hotkeyCollection;
2024-02-21 01:40:53 +08:00
[Inject(true)] private InputActionGroup _inputActionGroup;
2023-11-30 00:23:23 +08:00
2023-10-20 19:31:12 +08:00
public override void OnStart()
{
_health.OnSetAlive += OnSetAlive;
2024-02-21 01:40:53 +08:00
_inputActionGroup.RegisterCallback(interactiveAction, Interactive);
2023-10-20 19:31:12 +08:00
}
private void OnSetAlive(bool obj)
{
TryDeSelected();
}
2023-08-23 01:59:40 +08:00
public override void OnUpdate(float deltaTime)
{
2023-11-30 00:23:23 +08:00
if (_cameraService is not null && _movement is not null)
{
if (_cameraService.IsCameraActivated)
{
sensorTransform.SetPositionAndRotation(_cameraService.CameraPosition, _cameraService.CameraRotation);
}
else
{
sensorTransform.position = _movement.Position + _movement.Rotation * _movement.ViewCenter;
sensorTransform.rotation = _movement.ViewRotation;
}
}
2023-10-20 19:31:12 +08:00
//if (sensor.Get().TryGetAny(x=>x.TryGetComponentAny<ISelectable>(out _),out var detected))
2023-11-15 23:54:54 +08:00
try
2023-08-23 01:59:40 +08:00
{
2023-11-15 23:54:54 +08:00
if (sensor.Get().TryGetAny(x=>x.GetComponentInParent<ISelectable>() is not null,out var detected))
2023-08-23 01:59:40 +08:00
{
2023-11-15 23:54:54 +08:00
if (detected.TryGetComponentAny<ISelectable>(out var _detected))
2023-08-23 01:59:40 +08:00
{
2023-11-15 23:54:54 +08:00
if (_detected == selected)
{
2023-08-23 01:59:40 +08:00
2023-11-15 23:54:54 +08:00
}
else
{
TryDeSelected();
Detected(_detected);
}
2023-08-23 01:59:40 +08:00
}
else
{
TryDeSelected();
}
}
else
{
TryDeSelected();
}
}
2023-11-15 23:54:54 +08:00
catch(MissingReferenceException e)
{}
catch (Exception e)
2023-08-23 01:59:40 +08:00
{
2023-11-15 23:54:54 +08:00
Console.WriteLine(e);
throw;
2023-08-23 01:59:40 +08:00
}
2024-01-03 00:27:12 +08:00
if (_hotkeyCollection is not null)
{
if (selected is MonoBehaviour mono && mono)
{
_hotkeyCollection.Register(this);
}
else
{
_hotkeyCollection.UnRegister(this);
}
}
2023-08-23 01:59:40 +08:00
}
private void TryDeSelected()
{
if (selected is null) return;
selected.SetSelectionState(SelectionState.None);
2023-10-20 19:31:12 +08:00
OnInactive?.Invoke(selected);
2023-08-23 01:59:40 +08:00
selected = null;
}
private void Detected(ISelectable detected)
{
selected = detected;
detected.SetSelectionState(SelectionState.Hover);
2023-10-20 19:31:12 +08:00
OnSelected?.Invoke(selected);
2023-08-23 01:59:40 +08:00
}
2023-10-20 19:31:12 +08:00
2023-08-23 01:59:40 +08:00
public void Interactive(InputAction.CallbackContext context)
{
2023-10-20 19:31:12 +08:00
if (context.interaction is not PressInteraction || !context.performed ) return;
if (cd.AllowUpdate is false) return;
2024-01-03 00:27:12 +08:00
InteractiveInternal();
}
private void InteractiveInternal()
{
2023-08-23 01:59:40 +08:00
var _selected = selected;
if (_selected is not MonoBehaviour monoBehaviour) return;
switch (monoBehaviour.TryGetComponent<IAction>(out var action),monoBehaviour.TryGetComponent<ICondition>(out var condition))
2023-08-23 01:59:40 +08:00
{
case (true,true):
if (condition.Allow)
{
action.Execute();
Activated();
}else
{
_popup?.Popup(condition.Reason);
}
break;
case (true,false):
action.Execute();
Activated();
break;
case (false,true):
if (condition.Allow)
{
Activated();
}
else
{
_popup?.Popup(condition.Reason);
}
break;
default:
Activated();
break;
2023-11-15 23:54:54 +08:00
}
2024-01-03 00:27:12 +08:00
return;
void Activated()
2023-11-15 23:54:54 +08:00
{
_selected.SetSelectionState(SelectionState.Active);
OnActive?.Invoke(_selected);
2023-08-23 01:59:40 +08:00
}
}
2023-10-20 19:31:12 +08:00
public bool TryGetCurrentSelectable(out ISelectable selectable)
{
selectable = selected;
2023-11-30 00:23:23 +08:00
return selected?.Transform;
2023-10-20 19:31:12 +08:00
}
public event Action<ISelectable> OnNone;
public event Action<ISelectable> OnHover;
public event Action<ISelectable> OnActive;
public event Action<ISelectable> OnInactive;
public event Action<ISelectable> OnFocus;
public event Action<ISelectable> OnSelected;
public event Action<ISelectable> OnEnabled;
public event Action<ISelectable> OnChecked;
public event Action<ISelectable> OnRoot;
2024-01-03 00:27:12 +08:00
public string Name => "互动";
public string Description => selected switch
{
not null when selected.Transform.TryGetComponent<IDescription>(out var description)=> description.Name,
not null=>"互动",
_ => "没有选中物体",
};
public object Data { get; set; }= null;
public bool Enabled => true;
public Action OnPerform => InteractiveInternal;
2023-08-23 01:59:40 +08:00
}
}