157 lines
5.4 KiB
C#
157 lines
5.4 KiB
C#
using System.Linq;
|
||
using Core;
|
||
using UnityEngine;
|
||
using Script.Gameplay.Connect;
|
||
using Script.Gameplay.Interface;
|
||
using Script.Gameplay.Input;
|
||
using System;
|
||
|
||
namespace Script.Gameplay.Player
|
||
{
|
||
public class PlayerConnectController : MonoBehaviour
|
||
{
|
||
private bool _isEnablePlayerConnecting = false;
|
||
public bool IsEnablePlayerConnecting
|
||
{
|
||
get => _isEnablePlayerConnecting;
|
||
set
|
||
{
|
||
_isEnablePlayerConnecting = value;
|
||
if (_isEnablePlayerConnecting == false)
|
||
{
|
||
// 重置当前目标
|
||
CurrentTarget = null;
|
||
previousGazedTarget = null;
|
||
outTarget = null;
|
||
inputTarget = null;
|
||
}
|
||
}
|
||
} // 是否启用连接功能
|
||
[SerializeField] private FirstPersonRaycaster raycaster; // 第一人称射线检测器
|
||
[SerializeField] private float maxConnectDistance = 10f; // 最大连接距离
|
||
|
||
private IConnectable currentTarget;
|
||
public IConnectable CurrentTarget
|
||
{
|
||
get => currentTarget;
|
||
set
|
||
{
|
||
if (value != null)
|
||
{
|
||
currentTarget = value;
|
||
OnGazeEnter?.Invoke(currentTarget.GetGameObject());
|
||
}
|
||
else
|
||
{
|
||
OnGazeExit?.Invoke(null);
|
||
}
|
||
}
|
||
} // 当前注视的可连接对象
|
||
|
||
private IConnectable previousGazedTarget; // 上一次注视的 IConnectable(用于触发进入/离开)
|
||
private InputManager inputManager;
|
||
|
||
private IConnectable outTarget;
|
||
private IConnectable inputTarget;
|
||
public event Action<IConnectable> OnSetPointA;
|
||
public event Action<IConnectable> OnSetPointB;
|
||
public event Action<GameObject> OnGazeEnter;
|
||
public event Action<GameObject> OnGazeExit;
|
||
|
||
void Start()
|
||
{
|
||
inputManager = InputManager.Instance;
|
||
inputManager.Input.Player.SetOutput.performed += ctx => SetPointA(CurrentTarget);
|
||
inputManager.Input.Player.SetInput.performed += ctx => SetPointB(CurrentTarget);
|
||
inputManager.Input.Player.Connect.performed += ctx => CreateConnection();
|
||
inputManager.Input.Player.CutLine.performed += ctx => CutConnectLine(CurrentTarget);
|
||
|
||
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);
|
||
}
|
||
|
||
void Update()
|
||
{
|
||
DetectConnectable();
|
||
}
|
||
|
||
void DetectConnectable()
|
||
{
|
||
if (raycaster == null) return;
|
||
if(!IsEnablePlayerConnecting) return;
|
||
|
||
GameObject lookAtObj = raycaster.CurrentLookAtObject;
|
||
IConnectable hitConnectable = lookAtObj != null ? lookAtObj.GetComponent<IConnectable>() : null;
|
||
|
||
// 注视对象变化时触发进入/离开(使用接口方法)
|
||
// if (hitConnectable != previousGazedTarget)
|
||
// {
|
||
// previousGazedTarget = hitConnectable;
|
||
// }
|
||
|
||
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.");
|
||
}
|
||
}
|
||
|
||
void OnDrawGizmos()
|
||
{
|
||
// 射线可视化交由 FirstPersonRaycaster 处理
|
||
}
|
||
}
|
||
} |