210 lines
6.6 KiB
C#
210 lines
6.6 KiB
C#
using System;
|
|
using BITFALL.Hotkey;
|
|
using BITKit.PlayerCamera;
|
|
using BITKit.Selection;
|
|
using BITKit.Sensors;
|
|
using BITKit.UX;
|
|
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
using UnityEngine.InputSystem.Interactions;
|
|
namespace BITKit.Entities.Player
|
|
{
|
|
[CustomType(typeof(ISelector))]
|
|
public class EntityInteractive : EntityPlayerBehavior,ISelector,IHotkeyProvider
|
|
{
|
|
[Header(Constant.Header.Settings)]
|
|
[SerializeReference, SubclassSelector] private ISensor sensor;
|
|
|
|
[Header(Constant.Header.Gameobjects)]
|
|
[SerializeField] private Transform sensorTransform;
|
|
|
|
[Header(Constant.Header.Input)]
|
|
[SerializeField] private InputActionReference interactiveAction;
|
|
|
|
[Header(Constant.Header.InternalVariables)]
|
|
private ISelectable selected;
|
|
private IntervalUpdate cd = new(0.08f);
|
|
[Inject]
|
|
private IHealth _health;
|
|
|
|
[Inject(true)] private IEntityMovement _movement;
|
|
|
|
[Inject(true)] IPlayerCameraService _cameraService;
|
|
|
|
[Inject(true)] private IUXPopup _popup;
|
|
|
|
[Inject(true)] private IHotkeyCollection _hotkeyCollection;
|
|
|
|
[Inject(true)] private InputActionGroup _inputActionGroup;
|
|
|
|
public override void OnStart()
|
|
{
|
|
_health.OnSetAlive += OnSetAlive;
|
|
_inputActionGroup.RegisterCallback(interactiveAction, Interactive);
|
|
}
|
|
|
|
private void OnSetAlive(bool obj)
|
|
{
|
|
TryDeSelected();
|
|
}
|
|
|
|
public override void OnUpdate(float deltaTime)
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
|
|
|
|
//if (sensor.Get().TryGetAny(x=>x.TryGetComponentAny<ISelectable>(out _),out var detected))
|
|
try
|
|
{
|
|
if (sensor.Get().TryGetAny(x=>x.GetComponentInParent<ISelectable>() is not null,out var detected))
|
|
{
|
|
if (detected.TryGetComponentAny<ISelectable>(out var _detected))
|
|
{
|
|
if (_detected == selected)
|
|
{
|
|
|
|
}
|
|
else
|
|
{
|
|
TryDeSelected();
|
|
|
|
Detected(_detected);
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TryDeSelected();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TryDeSelected();
|
|
}
|
|
}
|
|
catch(MissingReferenceException e)
|
|
{}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine(e);
|
|
throw;
|
|
}
|
|
if (_hotkeyCollection is not null)
|
|
{
|
|
if (selected is MonoBehaviour mono && mono)
|
|
{
|
|
_hotkeyCollection.Register(this);
|
|
}
|
|
else
|
|
{
|
|
_hotkeyCollection.UnRegister(this);
|
|
}
|
|
}
|
|
}
|
|
private void TryDeSelected()
|
|
{
|
|
if (selected is null) return;
|
|
selected.SetSelectionState(SelectionState.None);
|
|
OnInactive?.Invoke(selected);
|
|
selected = null;
|
|
}
|
|
private void Detected(ISelectable detected)
|
|
{
|
|
selected = detected;
|
|
detected.SetSelectionState(SelectionState.Hover);
|
|
OnSelected?.Invoke(selected);
|
|
}
|
|
|
|
public void Interactive(InputAction.CallbackContext context)
|
|
{
|
|
if (context.interaction is not PressInteraction || !context.performed ) return;
|
|
if (cd.AllowUpdate is false) return;
|
|
InteractiveInternal();
|
|
}
|
|
|
|
private void InteractiveInternal()
|
|
{
|
|
var _selected = selected;
|
|
if (_selected is not MonoBehaviour monoBehaviour) return;
|
|
|
|
switch (monoBehaviour.TryGetComponent<IAction>(out var action),monoBehaviour.TryGetComponent<ICondition>(out var condition))
|
|
{
|
|
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;
|
|
}
|
|
|
|
return;
|
|
void Activated()
|
|
{
|
|
_selected.SetSelectionState(SelectionState.Active);
|
|
OnActive?.Invoke(_selected);
|
|
}
|
|
}
|
|
|
|
public bool TryGetCurrentSelectable(out ISelectable selectable)
|
|
{
|
|
selectable = selected;
|
|
return selected?.Transform;
|
|
}
|
|
|
|
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;
|
|
|
|
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;
|
|
}
|
|
} |