Files
2025TapTapGameJam/Assets/Script/Gameplay/Player/PlayerConnectController.cs

187 lines
6.4 KiB
C#
Raw Normal View History

using System.Linq;
using Core;
using UnityEngine;
using Script.Gameplay.Connect;
using Script.Gameplay.Interface;
using Script.Gameplay.Input;
using System;
using UnityEngine.InputSystem;
namespace Script.Gameplay.Player
{
public class PlayerConnectController : MonoBehaviour
{
private bool _isEnablePlayerConnecting = false;
public bool IsEnablePlayerConnecting
2025-10-21 13:07:48 +08:00
{
get => _isEnablePlayerConnecting;
2025-10-21 13:07:48 +08:00
set
{
_isEnablePlayerConnecting = value;
if (_isEnablePlayerConnecting == false)
2025-10-21 13:07:48 +08:00
{
// 重置当前目标
CurrentTarget = null;
previousGazedTarget = null;
outTarget = null;
inputTarget = null;
}
}
} // 是否启用连接功能
[SerializeField] private FirstPersonRaycaster raycaster; // 第一人称射线检测器
[SerializeField] private float maxConnectDistance = 10f; // 最大连接距离
private IConnectable previousTarget;
2025-10-21 13:07:48 +08:00
private IConnectable currentTarget;
public IConnectable CurrentTarget
{
get => currentTarget;
set
{
previousTarget = currentTarget;
currentTarget = value;
if (previousTarget != currentTarget)
2025-10-21 13:07:48 +08:00
{
if (currentTarget != null)
{
2025-10-26 22:13:15 +08:00
OnGazeEnterConnectable?.Invoke((currentTarget as MonoBehaviour)?.gameObject);
}
if (previousTarget != null)
{
2025-10-26 22:13:15 +08:00
OnGazeExitConnectable?.Invoke((previousTarget as MonoBehaviour)?.gameObject);
}
2025-10-21 13:07:48 +08:00
}
}
} // 当前注视的可连接对象
private IConnectable previousGazedTarget; // 上一次注视的 IConnectable用于触发进入/离开)
private InputManager inputManager;
private IConnectable outTarget;
private IConnectable inputTarget;
public event Action<IConnectable> OnSetPointA;
public event Action<IConnectable> OnSetPointB;
2025-10-26 22:13:15 +08:00
public event Action<GameObject> OnGazeEnterConnectable;
public event Action<GameObject> OnGazeExitConnectable;
void Start()
{
inputManager = InputManager.Instance;
inputManager.Input.Player.SetOutput.performed += OnSetOutputOnperformed;
inputManager.Input.Player.SetInput.performed += OnSetInputOnperformed;
inputManager.Input.Player.Connect.performed += OnConnectOnperformed;
inputManager.Input.Player.CutLine.performed += OnCutLineOnperformed;
if (raycaster == null)
raycaster = GetComponent<FirstPersonRaycaster>() ?? GetComponentInChildren<FirstPersonRaycaster>();
if (raycaster == null)
raycaster = FindObjectOfType<FirstPersonRaycaster>();
if (raycaster == null)
Debug.LogWarning("FirstPersonRaycaster not found! Please assign or add it to the player.");
ControllerLocator.Instance.Register(this);
}
private void OnCutLineOnperformed(InputAction.CallbackContext ctx)
{
CutConnectLine(CurrentTarget);
}
private void OnConnectOnperformed(InputAction.CallbackContext ctx)
{
CreateConnection();
}
private void OnSetInputOnperformed(InputAction.CallbackContext ctx)
{
SetPointB(CurrentTarget);
}
private void OnSetOutputOnperformed(InputAction.CallbackContext ctx)
{
SetPointA(CurrentTarget);
}
void Update()
{
DetectConnectable();
}
void DetectConnectable()
{
if (raycaster == null) return;
if(!IsEnablePlayerConnecting) return;
GameObject lookAtObj = raycaster.CurrentLookAtObject;
IConnectable hitConnectable = lookAtObj != null ? lookAtObj.GetComponent<IConnectable>() : null;
2025-10-21 13:07:48 +08:00
CurrentTarget = hitConnectable;
}
public void SetPointA(IConnectable target)
{
if (target == null) return;
if (!IsEnablePlayerConnecting) return;
if (!target.IsEnableConnect) return;
outTarget = target;
OnSetPointA?.Invoke(outTarget);
}
public void SetPointB(IConnectable target)
{
if (target == null) return;
if (!IsEnablePlayerConnecting) return;
if (!target.IsEnableConnect) return;
inputTarget = target;
OnSetPointB?.Invoke(inputTarget);
}
public void CutConnectLine(IConnectable target)
{
if (target == null) return;
if(!IsEnablePlayerConnecting) return;
ConnectionLineManager.Instance.CutTargetConnectionLines(target);
}
private void CreateConnection()
{
if(!IsEnablePlayerConnecting) return;
if (outTarget != null && inputTarget != null && outTarget != inputTarget)
{
//计算距离
float distance = Vector3.Distance(outTarget.GetPosition(), inputTarget.GetPosition());
if (distance > maxConnectDistance)
{
Debug.Log("Cannot create connection: targets are too far apart.");
return;
}
// 创建连接线
ConnectionLine connectionLine = ConnectionLineManager.Instance.GenerateConnectionLine(outTarget, inputTarget);
// 重置信号目标
outTarget = null;
inputTarget = null;
}
else
{
Debug.Log("Cannot create connection: invalid targets.");
}
}
private void OnDestroy()
{
ControllerLocator.Instance.Unregister(this);
inputManager.Input.Player.SetOutput.performed -= OnSetOutputOnperformed;
inputManager.Input.Player.SetInput.performed -= OnSetInputOnperformed;
inputManager.Input.Player.Connect.performed -= OnConnectOnperformed;
inputManager.Input.Player.CutLine.performed -= OnCutLineOnperformed;
}
void OnDrawGizmos()
{
// 射线可视化交由 FirstPersonRaycaster 处理
}
}
}