using System.Collections.Generic; using DG.Tweening; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; using Yarn.Unity; using AibisDream; public class ToolManager : MonoBehaviour { public static ToolManager Instance { get; private set; } public GameObject toolBox; // 工具盒的UI对象 private Tool currentTool; public List toolPrefabs; private Dictionary toolPrefabDictionary; public Canvas toolCanvas; private bool isBoxShow = false; public bool HasTool => currentTool != null; // 判断玩家是否已获得工具 private Module currentModule; // public Transform faceCanvas; private Vector3 originalCanvasPosition; // 原始面板位置 private bool isInRepiarMode=false; private void Awake() { // 确保 ToolManager 只有一个实例,并且这个实例是唯一的 if (Instance != null && Instance != this) { Destroy(gameObject); // 如果实例已经存在,销毁当前实例 } else { Instance = this; // 保持唯一实例 //DontDestroyOnLoad(gameObject); // 不销毁这个工具管理器 } } private void Start() { //originalCanvasPosition=faceCanvas.position; currentModule=null; toolBox.SetActive(false); // 初始隐藏工具盒 toolPrefabDictionary = new Dictionary(); foreach (GameObject toolPrefab in toolPrefabs) { Tool tool = toolPrefab.GetComponent(); if (tool != null) { toolPrefabDictionary[tool.gameObject.name] = toolPrefab; } } } public void TryStartRepairMode(Module module) { // 如果当前工具是螺丝刀,调用Module的EnterRepairMode方法 if (currentTool is Screwdriver&&module.isallowedRepair&&isInRepiarMode==false) { //module.StartRepairIfToolIsScrewdriver(currentTool); currentModule=module; //EnterRepairMode(); } else { Debug.Log("no tool or not allowed"); } } public void TryInstall(Module module) { Debug.Log("Tryinstall"); // 如果当前工具是螺丝刀,调用Module的EnterRepairMode方法 if (currentTool is Install&&isInRepiarMode==false&&module.isalloweInstall) { Debug.Log("install"); //module.StartRepairIfToolIsScrewdriver(currentTool); currentModule=module; module.Install(); //currentTool.StopFollowMouse(); Destroy(currentTool.gameObject); currentTool=null; //EnterRepairMode(); } else { Debug.Log("no tool or not allowed"); } } [YarnCommand("EnableReapir")] public void EnableRepair(string moduleName) { // 查找所有 Module 脚本组件 Module[] modules = FindObjectsOfType(); // 遍历模块,查找名称匹配的对象并设置 isAllowRepair 为 true foreach (Module module in modules) { if (module.gameObject.name == moduleName) { module.isallowedRepair = true; Debug.Log($"Repair enabled for module: {moduleName}"); } } } [YarnCommand("EnableInstall")] public void EnableInstall(string moduleName) { // 查找所有 Module 脚本组件 Module[] modules = FindObjectsOfType(); // 遍历模块,查找名称匹配的对象并设置 isAllowRepair 为 true foreach (Module module in modules) { if (module.gameObject.name == moduleName) { module.isalloweInstall=true; } } } [YarnCommand("SetReapirState")] public void SetReapirState(string moduleName,bool state) { // 查找所有 Module 脚本组件 Module[] modules = FindObjectsOfType(); // 遍历模块,查找名称匹配的对象并设置 isAllowRepair 为 true foreach (Module module in modules) { if (module.gameObject.name == moduleName) { module.SetReapirState(state); } } } [YarnCommand("SetInstall")] public void SetInstall(string moduleName,bool state) { // 查找所有 Module 脚本组件 Module[] modules = FindObjectsOfType(); // 遍历模块,查找名称匹配的对象并设置 isAllowRepair 为 true foreach (Module module in modules) { if (module.gameObject.name == moduleName) { module.SetInstallState(state); } } } [YarnCommand("RemovePlug")] public void RemovePlug() { Socket[] sockets = FindObjectsOfType(); // 找到场景中的所有Socket组件 foreach (Socket socket in sockets) { if(socket.plug!=null) { Plug plug=socket.plug; socket.RemovePlug(plug); // 移除Plug plug.ReturnToInit(); plug=null; return; } } } // public void EnterRepairMode() // { // isInRepiarMode=true; // //isRepairMode = true; // currentModule.RemoveAllPlugsFromSockets(); // // 使用 DOTween 对 Canvas 的位置和缩放进行平滑过渡 // faceCanvas.DOMove(currentModule.repairCanvasPosition, 1) // .SetEase(Ease.OutQuad) // 移动面板 // .OnComplete(() => currentModule.EnableScrewsInteraction(true)); // 动画完成后才启用交互 // faceCanvas.DOScale(currentModule.repairCanvasScale, 1) // .SetEase(Ease.OutQuad) // .OnComplete(() => DialogController.Instance.StartDialogNode("EnterRepairMode")); // 缩放面板 // } // [YarnCommand("ExitRepairMode")] // public void ExitRepairMode() // { // isInRepiarMode=false; // // 使用 DOTween 对 Canvas 的位置和缩放进行平滑过渡 // faceCanvas.DOMove(originalCanvasPosition, 1) // .SetEase(Ease.InQuad); // faceCanvas.DOScale(1f, 1) // .SetEase(Ease.InQuad); // 恢复面板缩放 // ShowToolBoxAfterTask(); // currentModule=null; // } [YarnCommand("ShowTool")] public void ShowTool(string toolName) { if (toolPrefabDictionary.TryGetValue(toolName, out GameObject toolPrefab)) { // 实例化工具 GameObject toolInstance = Instantiate(toolPrefab, toolBox.transform); currentTool = toolInstance.GetComponent(); toolBox.SetActive(true); isBoxShow = true; // 工具盒上移动画 toolBox.transform.DOMoveY(-4f, 0.5f).SetEase(Ease.OutBounce); // 添加点击事件以启动工具跟随鼠标 AddToolClickEvent(toolInstance); currentTool.GetComponent().blocksRaycasts=true; } else { Debug.LogWarning($"Tool '{toolName}' not found in tool manager."); } } private void AddToolClickEvent(GameObject toolInstance) { EventTrigger eventTrigger = toolInstance.GetComponent(); if (eventTrigger == null) { eventTrigger = toolInstance.AddComponent(); } // 清除之前可能存在的点击事件,避免重复添加 eventTrigger.triggers.Clear(); EventTrigger.Entry clickEntry = new EventTrigger.Entry { eventID = EventTriggerType.PointerClick }; // 点击事件:当点击工具时,使其开始跟随鼠标 clickEntry.callback.AddListener((data) => { currentTool.transform.SetParent(toolCanvas.transform); currentTool.StartFollowMouse(); currentTool.GetComponent().blocksRaycasts=false; currentTool.UseTool(); //RemoveToolClickEvent(eventTrigger); // 移除点击事件,防止再触发 HideTool(); }); eventTrigger.triggers.Add(clickEntry); } // 移除工具的点击事 // 显示工具盒并添加归还工具的点击事件 public void ShowToolBoxAfterTask() { toolBox.SetActive(true); isBoxShow = true; toolBox.transform.DOMoveY(-3.7f, 0.5f).SetEase(Ease.OutBounce); // 为工具盒添加一次性点击事件 AddToolBoxReturnEvent(); } private void AddToolBoxReturnEvent() { EventTrigger toolBoxTrigger = toolBox.GetComponent(); if (toolBoxTrigger == null) { toolBoxTrigger = toolBox.AddComponent(); } // 清除之前的事件,确保归还工具的事件仅触发一次 toolBoxTrigger.triggers.Clear(); EventTrigger.Entry boxClickEntry = new EventTrigger.Entry { eventID = EventTriggerType.PointerClick }; boxClickEntry.callback.AddListener((data) => { ReturnTool(); // 点击工具盒时归还工具 }); toolBoxTrigger.triggers.Add(boxClickEntry); } public void HideTool() { toolBox.transform.DOMoveY(-6.3f, 0.5f).SetEase(Ease.InBack).OnComplete(() => { toolBox.SetActive(false); isBoxShow = false; // 在工具盒的子物体中查找并删除工具对象 foreach (Transform child in toolBox.transform) { Tool tool = child.GetComponent(); if (tool != null) { Destroy(child.gameObject); // 删除工具对象 currentTool = null; // 清空当前工具的引用 } } // currentTool.ReturnTool(); // currentTool = null; }); } private void Update() { if (currentTool != null && currentTool.IsFollowingMouse) { //Vector2 imageSize = toolImage.rect.size; //Cursor.visible = false; Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); mousePos+=currentTool.offset; currentTool.transform.position = new Vector3(mousePos.x, mousePos.y, 0); } // if(Input.GetKeyDown(KeyCode.O)) // { // ShowTool("ScrewDriver"); // } // if(Input.GetKeyDown(KeyCode.P)) // { // ShowToolBoxAfterTask(); // } } public void ReturnTool() { if (currentTool != null) { Debug.Log("Returning tool and stopping follow mouse."); // 停止工具跟随鼠标 currentTool.StopFollowMouse(); // 将工具放回工具盒 currentTool.transform.SetParent(toolBox.transform); currentTool.transform.localPosition = Vector3.zero; currentTool.ReturnTool(); currentTool = null; // 重新添加点击事件,以便可以再次点击 //AddToolClickEvent(currentTool.gameObject); HideTool(); //Cursor.visible = true; } } }