Files
aibis-dream/Assets/Scripts/FixSystem/Tools/ToolManager.cs
T
2024-11-13 03:19:55 +08:00

259 lines
7.9 KiB
C#

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<GameObject> toolPrefabs;
private Dictionary<string, GameObject> 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<string, GameObject>();
foreach (GameObject toolPrefab in toolPrefabs)
{
Tool tool = toolPrefab.GetComponent<Tool>();
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 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<Tool>();
toolBox.SetActive(true);
isBoxShow = true;
// 工具盒上移动画
toolBox.transform.DOMoveY(-4f, 0.5f).SetEase(Ease.OutBounce);
// 添加点击事件以启动工具跟随鼠标
AddToolClickEvent(toolInstance);
currentTool.GetComponent<CanvasGroup>().blocksRaycasts=true;
}
else
{
Debug.LogWarning($"Tool '{toolName}' not found in tool manager.");
}
}
private void AddToolClickEvent(GameObject toolInstance)
{
EventTrigger eventTrigger = toolInstance.GetComponent<EventTrigger>();
if (eventTrigger == null)
{
eventTrigger = toolInstance.AddComponent<EventTrigger>();
}
// 清除之前可能存在的点击事件,避免重复添加
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<CanvasGroup>().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<EventTrigger>();
if (toolBoxTrigger == null)
{
toolBoxTrigger = toolBox.AddComponent<EventTrigger>();
}
// 清除之前的事件,确保归还工具的事件仅触发一次
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<Tool>();
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;
}
}
}