202 lines
6.0 KiB
C#
202 lines
6.0 KiB
C#
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<string, InteractiveLineSegment> lineSegmentDictionary = new Dictionary<string, InteractiveLineSegment>();
|
|
|
|
public IEnumerable<string> 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<InteractiveLineSegment>();
|
|
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<VisualLineSegment>();
|
|
firstLineSegment.Initialize(originalLineSegment.StartPoint, splitPoint);
|
|
|
|
// Create the second new line segment
|
|
GameObject secondLineSegmentObject = Instantiate(visualLineSegmentPrefab, transform);
|
|
VisualLineSegment secondLineSegment = secondLineSegmentObject.GetComponent<VisualLineSegment>();
|
|
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<InteractiveLineSegment>();
|
|
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");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|