using UnityEngine; using Yarn.Unity; using System; using System.Collections.Generic; using System.Collections; using AibisDream; using System.Linq; public class LineManager : MonoBehaviour { //public GameObject interactiveLineSegmentPrefab; public GameObject visualLineSegmentPrefab; public CustomCursor customCursor; // 自定义光标,你可以在 Inspector 中设置 private bool isScissorsMode; public bool IsScissorsMode { get { return isScissorsMode; } set { isScissorsMode = value; if (isScissorsMode) { SetScissorsCursor(); } else { ResetCursor(); } } } private Dictionary lineSegmentDictionary = new Dictionary(); public IEnumerable GetLineSegmentNames() { return lineSegmentDictionary.Keys; } private void SetScissorsCursor() { // 启用自定义光标 customCursor.gameObject.SetActive(true); } private void ResetCursor() { // 禁用自定义光标 customCursor.gameObject.SetActive(false); } private void Start() { // 查找场景中的所有 InteractiveLineSegment 并添加到字典中 InteractiveLineSegment[] lineSegments = FindObjectsOfType(); foreach (InteractiveLineSegment lineSegment in lineSegments) { lineSegmentDictionary.Add(lineSegment.name, lineSegment); } } public InteractiveLineSegment GetLineSegmentByName(string lineSegmentName) { if (lineSegmentDictionary.TryGetValue(lineSegmentName, out InteractiveLineSegment lineSegment)) { return lineSegment; } else { Debug.LogError("Invalid line segment name: " + lineSegmentName); return null; } } public string GetLineSegmentName(string input) { // 转换为小写并移除所有的下划线 string[] inputWords = input.ToLower().Split('_'); foreach (var lineSegmentName in lineSegmentDictionary.Keys) { // 转换为小写并移除所有的下划线 string[] lineSegmentWords = lineSegmentName.ToLower().Split('_'); // 检查是否包含相同的单词 if (inputWords.All(word => lineSegmentWords.Contains(word)) && lineSegmentWords.All(word => inputWords.Contains(word))) { return lineSegmentName; } } return null; } // Yarn 命令,设置线段的可剪断性 [YarnCommand("set_line_cuttable")] public void SetLineCuttable(string lineSegmentName, bool isCuttable) { string recognizedName = GetLineSegmentName(lineSegmentName); if (recognizedName != null) { InteractiveLineSegment lineSegment = GetLineSegmentByName(recognizedName); if (lineSegment != null) { lineSegment.IsCuttable = isCuttable; } } else { Debug.LogError("Invalid line segment name: " + lineSegmentName); } } // Yarn 命令,设置剪刀模式 [YarnCommand("set_scissors_mode")] public void SetScissorsMode(bool isEnabled) { IsScissorsMode = isEnabled; } public void CutLine(InteractiveLineSegment originalLineSegment, Vector3 splitPoint) { // 如果线段不可剪断,就直接返回,不进行剪断操作 if (!originalLineSegment.IsCuttable) { return; } // Create the first new line segment GameObject firstLineSegmentObject = Instantiate(visualLineSegmentPrefab, transform); VisualLineSegment firstLineSegment = firstLineSegmentObject.GetComponent(); firstLineSegment.Initialize(originalLineSegment.StartPoint, splitPoint); // Create the second new line segment GameObject secondLineSegmentObject = Instantiate(visualLineSegmentPrefab, transform); VisualLineSegment secondLineSegment = secondLineSegmentObject.GetComponent(); secondLineSegment.Initialize(originalLineSegment.EndPoint, splitPoint); // Immediately destroy the original line segment Destroy(originalLineSegment.gameObject); // Shrink and disappear the new line segments firstLineSegment.ShrinkAndDisappear(); secondLineSegment.ShrinkAndDisappear(); } public void BindOptionToLineSegment(string lineSegmentName, YarnOption option) { InteractiveLineSegment lineSegment = GetLineSegmentByName(lineSegmentName); if (lineSegment != null) { lineSegment.Option = option; } } private void Update() { if (Input.GetMouseButtonDown(0) && isScissorsMode) { // Convert the mouse position to a 2D ray Vector2 ray = Camera.main.ScreenToWorldPoint(Input.mousePosition); // Check if the ray hits a line segment RaycastHit2D hit = Physics2D.Raycast(ray, Vector2.zero); if (hit.collider != null) { Debug.Log("Raycast hit: " + hit.transform.name); InteractiveLineSegment originalLineSegment = hit.transform.GetComponent(); if (originalLineSegment != null) { Debug.Log("Line segment hit: " + originalLineSegment.name); CutLine(originalLineSegment,hit.point); // Check if Option is not null before selecting it if (originalLineSegment.Option != null) { originalLineSegment.Option.SelectOption(); } } else { //Debug.Log("Hit object is not a line segment"); } } } } }