feat(Connect): 完成连线基本玩法,
This commit is contained in:
121
Assets/Script/Gameplay/Player/PlayerConnectController.cs
Normal file
121
Assets/Script/Gameplay/Player/PlayerConnectController.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
using System.Linq;
|
||||
using Core;
|
||||
using UnityEngine;
|
||||
using Script.Gameplay.Connect;
|
||||
using Script.Gameplay.Input;
|
||||
using System;
|
||||
|
||||
namespace Gameplay.Player
|
||||
{
|
||||
public class PlayerConnectController : MonoBehaviour
|
||||
{
|
||||
public bool IsEnableConnecting = true; // 是否启用连接功能
|
||||
[SerializeField] private FirstPersonRaycaster raycaster; // 第一人称射线检测器
|
||||
|
||||
private IConnectable currentTarget; // 当前注视的可连接对象
|
||||
private IConnectable previousGazedTarget; // 上一次注视的 IConnectable(用于触发进入/离开)
|
||||
private InputManager inputManager;
|
||||
|
||||
private IConnectable outTarget;
|
||||
private IConnectable inputTarget;
|
||||
public event Action<IConnectable> OnSetOutputTarget;
|
||||
public event Action<IConnectable> OnSetInputTarget;
|
||||
|
||||
void Start()
|
||||
{
|
||||
inputManager = InputManager.Instance;
|
||||
inputManager.Input.Player.SetOutput.performed += ctx => SetOutTarget(currentTarget);
|
||||
inputManager.Input.Player.SetInput.performed += ctx => SetInputTarget(currentTarget);
|
||||
inputManager.Input.Player.Connect.performed += ctx => CreateConnection();
|
||||
|
||||
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;
|
||||
|
||||
GameObject lookAtObj = raycaster.CurrentLookAtObject;
|
||||
IConnectable hitConnectable = lookAtObj != null ? lookAtObj.GetComponent<IConnectable>() : null;
|
||||
|
||||
// 注视对象变化时触发进入/离开(使用接口方法)
|
||||
if (hitConnectable != previousGazedTarget)
|
||||
{
|
||||
if (previousGazedTarget != null)
|
||||
{
|
||||
previousGazedTarget.OnGazeExit();
|
||||
}
|
||||
|
||||
if (hitConnectable != null)
|
||||
{
|
||||
hitConnectable.OnGazeEnter();
|
||||
}
|
||||
|
||||
previousGazedTarget = hitConnectable;
|
||||
}
|
||||
|
||||
currentTarget = hitConnectable;
|
||||
}
|
||||
|
||||
|
||||
public IConnectable GetCurrentTarget()
|
||||
{
|
||||
return currentTarget;
|
||||
}
|
||||
|
||||
public void SetOutTarget(IConnectable target)
|
||||
{
|
||||
if (target == null) return;
|
||||
if(!IsEnableConnecting) return;
|
||||
if (!target.IsConnectedOutput)
|
||||
{
|
||||
outTarget = target;
|
||||
OnSetOutputTarget?.Invoke(outTarget);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetInputTarget(IConnectable target)
|
||||
{
|
||||
if (target == null) return;
|
||||
if(!IsEnableConnecting) return;
|
||||
if (!target.IsConnectedInput)
|
||||
{
|
||||
inputTarget = currentTarget;
|
||||
OnSetInputTarget?.Invoke(inputTarget);
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateConnection()
|
||||
{
|
||||
if(!IsEnableConnecting) return;
|
||||
if (outTarget != null && inputTarget != null && outTarget != inputTarget)
|
||||
{
|
||||
ConnectionLine connectionLine = ConnectionLineManager.Instance.GenerateConnectionLine(outTarget, inputTarget);
|
||||
// 重置信号目标
|
||||
outTarget = null;
|
||||
inputTarget = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("Cannot create connection: invalid targets.");
|
||||
}
|
||||
}
|
||||
|
||||
void OnDrawGizmos()
|
||||
{
|
||||
// 射线可视化交由 FirstPersonRaycaster 处理
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5981311fef324f939be05186f7936173
|
||||
timeCreated: 1760838186
|
@@ -0,0 +1,9 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Gameplay.Player
|
||||
{
|
||||
public class PlayerConnectionLineController : MonoBehaviour
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e152f6521db343f3aac46c7c448491bc
|
||||
timeCreated: 1760841639
|
@@ -16,29 +16,26 @@ namespace Gameplay.Player
|
||||
public class PlayerWatchModeController : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Camera cam;
|
||||
public event Action OnEnterInsideWatchMode;
|
||||
public event Action OnExitInsideWatchMode;
|
||||
public event Action<WatchMode> OnEnterWatchMode;
|
||||
public event Action<WatchMode> OnExitWatchMode;
|
||||
private InputManager inputManager;
|
||||
private TimePauseManager timePauseManager;
|
||||
private WatchMode currentMode = WatchMode.Normal;
|
||||
private PlayerInteractorController playerInteractorController;
|
||||
private PlayerConnectController _playerConnectController;
|
||||
private WatchMode previousMode = WatchMode.Normal;
|
||||
private WatchMode currentMode = WatchMode.Normal;
|
||||
|
||||
public WatchMode CurrentWatchMode
|
||||
{
|
||||
get => currentMode;
|
||||
set
|
||||
{
|
||||
if (value != WatchMode.Inside)
|
||||
{
|
||||
OnExitInsideWatchMode?.Invoke();
|
||||
}
|
||||
|
||||
if (value == WatchMode.Inside)
|
||||
{
|
||||
OnEnterInsideWatchMode?.Invoke();
|
||||
}
|
||||
|
||||
previousMode = currentMode;
|
||||
currentMode = value;
|
||||
// 触发退出事件
|
||||
OnExitWatchMode?.Invoke(previousMode);
|
||||
OnEnterWatchMode?.Invoke(currentMode);
|
||||
|
||||
SwitchWatchMode(currentMode);
|
||||
}
|
||||
}
|
||||
@@ -48,6 +45,7 @@ namespace Gameplay.Player
|
||||
inputManager = InputManager.Instance;
|
||||
timePauseManager = TimePauseManager.Instance;
|
||||
playerInteractorController = GetComponent<PlayerInteractorController>();
|
||||
_playerConnectController = GetComponent<PlayerConnectController>();
|
||||
|
||||
var input = inputManager.Input;
|
||||
input.Player.SwitchWatchMode.performed += ctx =>
|
||||
@@ -80,6 +78,11 @@ namespace Gameplay.Player
|
||||
playerInteractorController.SetPlayerInteractionEnabled(true);
|
||||
}
|
||||
|
||||
if (_playerConnectController != null)
|
||||
{
|
||||
_playerConnectController.IsEnableConnecting = false;
|
||||
}
|
||||
|
||||
break;
|
||||
case WatchMode.Inside:
|
||||
SetSeeLines(false);
|
||||
@@ -95,6 +98,11 @@ namespace Gameplay.Player
|
||||
{
|
||||
playerInteractorController.SetPlayerInteractionEnabled(false);
|
||||
}
|
||||
|
||||
if (_playerConnectController != null)
|
||||
{
|
||||
_playerConnectController.IsEnableConnecting = false;
|
||||
}
|
||||
|
||||
break;
|
||||
case WatchMode.Outside:
|
||||
@@ -111,6 +119,11 @@ namespace Gameplay.Player
|
||||
{
|
||||
playerInteractorController.SetPlayerInteractionEnabled(true);
|
||||
}
|
||||
|
||||
if (_playerConnectController != null)
|
||||
{
|
||||
_playerConnectController.IsEnableConnecting = true;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
|
Reference in New Issue
Block a user