Files
aibis-dream/Assets/Scripts/FixSystem/Tools/ToolManager.cs
T
bottlefish b950a868ee 缺一些东西,但是基本通了
缺task
UF内部表现不对
擦除记忆不是手动的(或许可接受)
工具和鼠标相关的屏蔽
2024-11-13 18:51:13 +08:00

346 lines
11 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 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<Module>();
// 遍历模块,查找名称匹配的对象并设置 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<Module>();
// 遍历模块,查找名称匹配的对象并设置 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<Module>();
// 遍历模块,查找名称匹配的对象并设置 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<Module>();
// 遍历模块,查找名称匹配的对象并设置 isAllowRepair 为 true
foreach (Module module in modules)
{
if (module.gameObject.name == moduleName)
{
module.SetInstallState(state);
}
}
}
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;
}
}
}