feat(Edit): 现在玩家按E可以直接对可编辑物体进行编辑
This commit is contained in:
@@ -48,14 +48,14 @@ namespace Script.Gameplay.Facility
|
|||||||
{
|
{
|
||||||
// 逆时针旋转90度
|
// 逆时针旋转90度
|
||||||
transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles + new Vector3(0, -90, 0));
|
transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles + new Vector3(0, -90, 0));
|
||||||
Debug.Log("Open door");
|
// Debug.Log("Open door");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CloseDoor()
|
private void CloseDoor()
|
||||||
{
|
{
|
||||||
// 顺时针旋转90度
|
// 顺时针旋转90度
|
||||||
transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles + new Vector3(0, 90, 0));
|
transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles + new Vector3(0, 90, 0));
|
||||||
Debug.Log("Close door");
|
// Debug.Log("Close door");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@@ -2,21 +2,30 @@ using Core;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Script.Gameplay.Interface;
|
using Script.Gameplay.Interface;
|
||||||
using Script.Gameplay.Input;
|
using Script.Gameplay.Input;
|
||||||
|
using System;
|
||||||
|
using Script.Gameplay.Global;
|
||||||
|
|
||||||
namespace Script.Gameplay.Player
|
namespace Script.Gameplay.Player
|
||||||
{
|
{
|
||||||
public class PlayerEditController : MonoBehaviour
|
public class PlayerEditController : MonoBehaviour
|
||||||
{
|
{
|
||||||
[SerializeField] private FirstPersonRaycaster raycaster; // 新增:第一人称射线检测器
|
[SerializeField] private FirstPersonRaycaster raycaster; // 新增:第一人称射线检测器
|
||||||
|
public bool IsEnableEditing = true; // 是否启用编辑功能
|
||||||
|
private bool isEditing = false; // 当前是否处于编辑状态
|
||||||
|
public event Action<IEditable> OnBeginEditTarget;
|
||||||
|
public event Action<IEditable> OnEndEditTarget;
|
||||||
|
|
||||||
private IEditable currentTarget; // 射线命中的当前可编辑对象(用于按键交互)
|
private IEditable currentTarget; // 射线命中的当前可编辑对象(用于按键交互)
|
||||||
private IEditable previousGazedTarget; // 上一次注视的对象(用于注视进入/离开事件)
|
private IEditable previousGazedTarget; // 上一次注视的对象(用于注视进入/离开事件)
|
||||||
|
|
||||||
private InputManager inputManager;
|
private InputManager inputManager;
|
||||||
|
|
||||||
|
private TimePauseManager timePauseManager;
|
||||||
void Start()
|
void Start()
|
||||||
{
|
{
|
||||||
inputManager = InputManager.Instance;
|
inputManager = InputManager.Instance;
|
||||||
|
inputManager.Input.Player.Edit.performed += context => EditTarget();
|
||||||
|
timePauseManager = TimePauseManager.Instance;
|
||||||
if (raycaster == null)
|
if (raycaster == null)
|
||||||
raycaster = GetComponent<FirstPersonRaycaster>() ?? GetComponentInChildren<FirstPersonRaycaster>();
|
raycaster = GetComponent<FirstPersonRaycaster>() ?? GetComponentInChildren<FirstPersonRaycaster>();
|
||||||
if (raycaster == null)
|
if (raycaster == null)
|
||||||
@@ -24,7 +33,6 @@ namespace Script.Gameplay.Player
|
|||||||
if (raycaster == null)
|
if (raycaster == null)
|
||||||
Debug.LogWarning("FirstPersonRaycaster not found! Please assign or add it to the player.");
|
Debug.LogWarning("FirstPersonRaycaster not found! Please assign or add it to the player.");
|
||||||
ControllerLocator.Instance.Register(this);
|
ControllerLocator.Instance.Register(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update()
|
void Update()
|
||||||
@@ -62,6 +70,36 @@ namespace Script.Gameplay.Player
|
|||||||
return currentTarget;
|
return currentTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void EditTarget()
|
||||||
|
{
|
||||||
|
if (isEditing)
|
||||||
|
{
|
||||||
|
isEditing = false;
|
||||||
|
OnEndEditTarget?.Invoke(currentTarget);
|
||||||
|
inputManager.SetCursorState(false, CursorLockMode.Locked);
|
||||||
|
inputManager.SetInputForLook(true);
|
||||||
|
inputManager.SetInputForMove(true);
|
||||||
|
if (timePauseManager != null)
|
||||||
|
{
|
||||||
|
timePauseManager.SetPaused(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (currentTarget == null) return;
|
||||||
|
if (!IsEnableEditing) return;
|
||||||
|
isEditing = true;
|
||||||
|
OnBeginEditTarget?.Invoke(currentTarget);
|
||||||
|
inputManager.SetCursorState(true, CursorLockMode.Confined);
|
||||||
|
inputManager.SetInputForLook(false);
|
||||||
|
inputManager.SetInputForMove(false);
|
||||||
|
if (timePauseManager != null)
|
||||||
|
{
|
||||||
|
timePauseManager.SetPaused(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OnDrawGizmos()
|
void OnDrawGizmos()
|
||||||
{
|
{
|
||||||
// 交由 FirstPersonRaycaster 绘制射线
|
// 交由 FirstPersonRaycaster 绘制射线
|
||||||
|
@@ -9,7 +9,6 @@ namespace Script.Gameplay.Player
|
|||||||
public enum WatchMode
|
public enum WatchMode
|
||||||
{
|
{
|
||||||
Normal,
|
Normal,
|
||||||
Inside,
|
|
||||||
Outside
|
Outside
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,7 +20,7 @@ namespace Script.Gameplay.Player
|
|||||||
private InputManager inputManager;
|
private InputManager inputManager;
|
||||||
private TimePauseManager timePauseManager;
|
private TimePauseManager timePauseManager;
|
||||||
private PlayerInteractorController playerInteractorController;
|
private PlayerInteractorController playerInteractorController;
|
||||||
private PlayerConnectController _playerConnectController;
|
private PlayerConnectController playerConnectController;
|
||||||
private WatchMode previousMode = WatchMode.Normal;
|
private WatchMode previousMode = WatchMode.Normal;
|
||||||
private WatchMode currentMode = WatchMode.Normal;
|
private WatchMode currentMode = WatchMode.Normal;
|
||||||
|
|
||||||
@@ -45,12 +44,12 @@ namespace Script.Gameplay.Player
|
|||||||
inputManager = InputManager.Instance;
|
inputManager = InputManager.Instance;
|
||||||
timePauseManager = TimePauseManager.Instance;
|
timePauseManager = TimePauseManager.Instance;
|
||||||
playerInteractorController = GetComponent<PlayerInteractorController>();
|
playerInteractorController = GetComponent<PlayerInteractorController>();
|
||||||
_playerConnectController = GetComponent<PlayerConnectController>();
|
playerConnectController = GetComponent<PlayerConnectController>();
|
||||||
|
|
||||||
var input = inputManager.Input;
|
var input = inputManager.Input;
|
||||||
input.Player.SwitchWatchMode.performed += ctx =>
|
input.Player.SwitchWatchMode.performed += ctx =>
|
||||||
{
|
{
|
||||||
var modeTemp = (WatchMode)(((int)CurrentWatchMode + 1) % 3);
|
var modeTemp = (WatchMode)(((int)CurrentWatchMode + 1) % Enum.GetNames(typeof(WatchMode)).Length);
|
||||||
CurrentWatchMode = modeTemp;
|
CurrentWatchMode = modeTemp;
|
||||||
};
|
};
|
||||||
;
|
;
|
||||||
@@ -69,61 +68,31 @@ namespace Script.Gameplay.Player
|
|||||||
inputManager.SetCursorState(false, CursorLockMode.Locked);
|
inputManager.SetCursorState(false, CursorLockMode.Locked);
|
||||||
inputManager.SetInputForLook(true);
|
inputManager.SetInputForLook(true);
|
||||||
inputManager.SetInputForMove(true);
|
inputManager.SetInputForMove(true);
|
||||||
if (timePauseManager != null)
|
|
||||||
{
|
|
||||||
timePauseManager.SetPaused(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (playerInteractorController != null)
|
if (playerInteractorController != null)
|
||||||
{
|
{
|
||||||
playerInteractorController.SetPlayerInteractionEnabled(true);
|
playerInteractorController.SetPlayerInteractionEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_playerConnectController != null)
|
if (playerConnectController != null)
|
||||||
{
|
{
|
||||||
_playerConnectController.IsEnableConnecting = false;
|
playerConnectController.IsEnableConnecting = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
|
||||||
case WatchMode.Inside:
|
|
||||||
SetSeeLines(false);
|
|
||||||
inputManager.SetCursorState(true, CursorLockMode.Confined);
|
|
||||||
inputManager.SetInputForLook(false);
|
|
||||||
inputManager.SetInputForMove(false);
|
|
||||||
if (timePauseManager != null)
|
|
||||||
{
|
|
||||||
timePauseManager.SetPaused(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (playerInteractorController != null)
|
|
||||||
{
|
|
||||||
playerInteractorController.SetPlayerInteractionEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_playerConnectController != null)
|
|
||||||
{
|
|
||||||
_playerConnectController.IsEnableConnecting = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case WatchMode.Outside:
|
case WatchMode.Outside:
|
||||||
SetSeeLines(true);
|
SetSeeLines(true);
|
||||||
inputManager.SetCursorState(false, CursorLockMode.Locked);
|
inputManager.SetCursorState(false, CursorLockMode.Locked);
|
||||||
inputManager.SetInputForLook(true);
|
inputManager.SetInputForLook(true);
|
||||||
inputManager.SetInputForMove(true);
|
inputManager.SetInputForMove(true);
|
||||||
if (timePauseManager != null)
|
|
||||||
{
|
|
||||||
timePauseManager.SetPaused(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (playerInteractorController != null)
|
if (playerInteractorController != null)
|
||||||
{
|
{
|
||||||
playerInteractorController.SetPlayerInteractionEnabled(true);
|
playerInteractorController.SetPlayerInteractionEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_playerConnectController != null)
|
if (playerConnectController != null)
|
||||||
{
|
{
|
||||||
_playerConnectController.IsEnableConnecting = true;
|
playerConnectController.IsEnableConnecting = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@@ -1,10 +1,8 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Core;
|
using Core;
|
||||||
using Script.Gameplay.Interface;
|
using Script.Gameplay.Interface;
|
||||||
using Script.Gameplay.Player;
|
using Script.Gameplay.Player;
|
||||||
using Script.Gameplay.Facility;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Script.Gameplay.Input;
|
using Script.Gameplay.Input;
|
||||||
|
|
||||||
@@ -13,36 +11,28 @@ namespace UI
|
|||||||
// 用于显示和编辑 Facility 上的各个 IEditComponent 组件的 UI 面板
|
// 用于显示和编辑 Facility 上的各个 IEditComponent 组件的 UI 面板
|
||||||
public class PlayerEditViewer : UIBase
|
public class PlayerEditViewer : UIBase
|
||||||
{
|
{
|
||||||
private PlayerEditController controller;
|
|
||||||
private PlayerWatchModeController watchModeController;
|
|
||||||
private IEditable editable;
|
|
||||||
private List<IEditableComponent> components = new List<IEditableComponent>();
|
|
||||||
private List<EditableComponentViewer> componentViewers = new List<EditableComponentViewer>();
|
|
||||||
[SerializeField] private GameObject componentEditViewerPrefab;
|
[SerializeField] private GameObject componentEditViewerPrefab;
|
||||||
[SerializeField] private GameObject noEditableTargetPanel;
|
[SerializeField] private GameObject noEditableTargetPanel;
|
||||||
[SerializeField] private float panelRadius = 100f;
|
[SerializeField] private float panelRadius = 100f;
|
||||||
|
public List<EditableComponentViewer> componentViewers = new List<EditableComponentViewer>();
|
||||||
|
private PlayerEditController editController;
|
||||||
private InputManager inputManager;
|
private InputManager inputManager;
|
||||||
|
|
||||||
private void Awake()
|
|
||||||
|
protected override void Awake()
|
||||||
{
|
{
|
||||||
|
base.Awake();
|
||||||
inputManager = InputManager.Instance;
|
inputManager = InputManager.Instance;
|
||||||
ControllerLocator.Instance.TryGetWait<PlayerEditController>(GetPlayerEditControllerHandle);
|
ControllerLocator.Instance.TryGetWait<PlayerEditController>(OnGetPlayerEditController);
|
||||||
ControllerLocator.Instance.TryGetWait<PlayerWatchModeController>(GetPlayerWatchModeControllerHandle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Start()
|
public void OnBeginEdit(IEditable target)
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnEnterInsideWatchMode()
|
|
||||||
{
|
{
|
||||||
this.gameObject.SetActive(true);
|
this.gameObject.SetActive(true);
|
||||||
if (GetEditableFromController() != null)
|
if (target != null)
|
||||||
{
|
{
|
||||||
GetEditableComponentsFromEditable();
|
|
||||||
ClearComponentUI();
|
ClearComponentUI();
|
||||||
GenerateComponentUI();
|
GenerateComponentUI(GetEditableComponentsFromEditable(target));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -53,7 +43,7 @@ namespace UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnExitInsideWatchMode()
|
public void OnEndEdit(IEditable target)
|
||||||
{
|
{
|
||||||
this.gameObject.SetActive(false);
|
this.gameObject.SetActive(false);
|
||||||
|
|
||||||
@@ -65,50 +55,23 @@ namespace UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取 PlayerEditController 的回调
|
// 获取 PlayerEditController 的回调
|
||||||
private void GetPlayerEditControllerHandle(PlayerEditController editController)
|
private void OnGetPlayerEditController(PlayerEditController controller)
|
||||||
{
|
{
|
||||||
controller = editController;
|
this.editController = controller;
|
||||||
|
this.editController.OnBeginEditTarget += OnBeginEdit;
|
||||||
|
this.editController.OnEndEditTarget += OnEndEdit;
|
||||||
//Debug.Log("PlayerEditViewer obtained PlayerEditController.");
|
//Debug.Log("PlayerEditViewer obtained PlayerEditController.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取 PlayerWatchModeController 的回调
|
private List<IEditableComponent> GetEditableComponentsFromEditable(IEditable target)
|
||||||
private void GetPlayerWatchModeControllerHandle(PlayerWatchModeController watchModeCtrl)
|
|
||||||
{
|
{
|
||||||
watchModeController = watchModeCtrl;
|
if (target == null)
|
||||||
watchModeController.OnEnterWatchMode += (WatchMode mode) =>
|
|
||||||
{
|
{
|
||||||
if (mode == WatchMode.Inside)
|
Debug.Log($"editable is null in {nameof(PlayerEditViewer)}");
|
||||||
OnEnterInsideWatchMode();
|
|
||||||
};
|
|
||||||
watchModeController.OnExitWatchMode += (WatchMode mode) =>
|
|
||||||
{
|
|
||||||
if (mode == WatchMode.Inside)
|
|
||||||
OnExitInsideWatchMode();
|
|
||||||
};
|
|
||||||
|
|
||||||
//Debug.Log("PlayerEditViewer subscribed to WatchMode events.");
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEditable GetEditableFromController()
|
|
||||||
{
|
|
||||||
if (controller == null)
|
|
||||||
{
|
|
||||||
Debug.Log($"controller is null in {nameof(PlayerEditViewer)}");
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return editable = controller.GetCurrentTarget();
|
return target.GetEditableComponents()
|
||||||
}
|
|
||||||
|
|
||||||
private void GetEditableComponentsFromEditable()
|
|
||||||
{
|
|
||||||
if (editable == null)
|
|
||||||
{
|
|
||||||
Debug.Log($"editable is null in {nameof(PlayerEditViewer)}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
components = editable.GetEditableComponents()
|
|
||||||
.Where(c => c != null)
|
.Where(c => c != null)
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
@@ -128,7 +91,7 @@ namespace UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 根据 components 生成 UI, 根据拥有的 IEditComponent 的数量动态生成 UI 元素。布局为环绕着面板中心排列(自适应间隔)。
|
// 根据 components 生成 UI, 根据拥有的 IEditComponent 的数量动态生成 UI 元素。布局为环绕着面板中心排列(自适应间隔)。
|
||||||
private void GenerateComponentUI()
|
private void GenerateComponentUI(List<IEditableComponent> components)
|
||||||
{
|
{
|
||||||
if (components == null || components.Count == 0 || componentEditViewerPrefab == null) return;
|
if (components == null || components.Count == 0 || componentEditViewerPrefab == null) return;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user