模块和线的拆除以及重装
view的visual管理,重构了line的初始化方式,支持用yarn初始化
This commit is contained in:
@@ -44,14 +44,14 @@ public class Plug : MonoBehaviour, IDragHandler, IPointerDownHandler, IPointerUp
|
||||
{
|
||||
// Dialogue has started, disable plug interactions
|
||||
IsInDialogue = true;
|
||||
Debug.Log("in dialogue");
|
||||
//Debug.Log("in dialogue");
|
||||
}
|
||||
|
||||
void HandleDialogueComplete()
|
||||
{
|
||||
// Dialogue has completed, enable plug interactions
|
||||
IsInDialogue = false;
|
||||
Debug.Log("dialoguecompleted");
|
||||
//Debug.Log("dialoguecompleted");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ using System.Drawing;
|
||||
public class CrowBarSocket : MonoBehaviour, ISocket
|
||||
{
|
||||
// Start is called before the first frame update
|
||||
public bool IsAvailable { get; set; } = false;
|
||||
public bool IsAvailable { get; set; } = true;
|
||||
public Vector2 InsertionPoint => transform.position;
|
||||
public GameObject visual;
|
||||
|
||||
@@ -35,6 +35,10 @@ public class CrowBarSocket : MonoBehaviour, ISocket
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
public void EnableSocket()
|
||||
{
|
||||
gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
public Vector2 GetPosition()
|
||||
{
|
||||
|
||||
@@ -38,7 +38,6 @@ public class Crowbar : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragH
|
||||
private void Start()
|
||||
{
|
||||
crowbarOutPosition = transform.position;
|
||||
crowbarSockets = new List<CrowBarSocket>(FindObjectsOfType<CrowBarSocket>());
|
||||
|
||||
}
|
||||
private void Initialize()
|
||||
@@ -50,6 +49,7 @@ public class Crowbar : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragH
|
||||
crowbarSocket=null;
|
||||
crowbarCanvas.sortingLayerName = "Tool";
|
||||
crowbarCanvas.sortingOrder = 6;
|
||||
crowbarSockets = new List<CrowBarSocket>(FindObjectsOfType<CrowBarSocket>());
|
||||
}
|
||||
|
||||
[YarnCommand("CrowBarIn")]
|
||||
@@ -67,6 +67,7 @@ public class Crowbar : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragH
|
||||
|
||||
// });
|
||||
box.DOMove(crowbarOutPosition, 1f);
|
||||
transform.position=crowbarOutPosition;
|
||||
}
|
||||
|
||||
public void OnBeginDrag(PointerEventData eventData)
|
||||
@@ -87,15 +88,15 @@ public class Crowbar : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragH
|
||||
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
//Debug.Log("Draging");
|
||||
Debug.Log("Draging");
|
||||
if (IsInDialogue || isPryingCompleted) return;
|
||||
|
||||
if (isInserted)
|
||||
{
|
||||
Debug.Log("insert");
|
||||
Debug.Log("insert");
|
||||
float deltaY = lastMousePosition.y - Input.mousePosition.y;
|
||||
lastMousePosition = Input.mousePosition; // 更新 lastMousePosition
|
||||
Debug.Log("Progress :"+progress);
|
||||
//Debug.Log("Progress :"+progress);
|
||||
|
||||
progress += deltaY*0.3f * Time.deltaTime;
|
||||
progress = Mathf.Clamp01(progress); // 确保 progress 不会小于0
|
||||
@@ -104,7 +105,7 @@ public void OnDrag(PointerEventData eventData)
|
||||
float startAngle = crowbarSocket.visual.transform.eulerAngles.z;
|
||||
float endAngle = startAngle + 40f;
|
||||
float currentAngle = Mathf.Lerp(startAngle, endAngle, progress);
|
||||
Debug.Log("currentAngle :"+currentAngle);
|
||||
//Debug.Log("currentAngle :"+currentAngle);
|
||||
|
||||
|
||||
// 更新撬棍的旋转角度
|
||||
@@ -113,12 +114,13 @@ public void OnDrag(PointerEventData eventData)
|
||||
if (progress >= 1f)
|
||||
{
|
||||
crowbarSocket.Completed();
|
||||
crowbarSocket.EnableSocket();
|
||||
// 触发撬动完成的逻辑
|
||||
Debug.Log("Crowbar action completed.");
|
||||
isPryingCompleted = true;
|
||||
|
||||
// 定义目标位置
|
||||
Vector3 targetPosition = transform.position + new Vector3(-1, 1, 0) * 10f; // 你可能需要根据你的场景来调整这个偏移量
|
||||
Vector3 targetPosition = transform.position + new Vector3(-1, 1, 0) * 6f; // 你可能需要根据你的场景来调整这个偏移量
|
||||
|
||||
// 使用 DOTween 来移动 crowbar
|
||||
transform.DOMove(targetPosition, 1f);
|
||||
@@ -165,6 +167,10 @@ public void OnEndDrag(PointerEventData eventData)
|
||||
|
||||
foreach (var socket in crowbarSockets)
|
||||
{
|
||||
if(!socket.gameObject.activeInHierarchy)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
float distance = Vector3.Distance(transform.position, socket.transform.position);
|
||||
if (distance <= minDistance && socket.IsAvailable)
|
||||
{
|
||||
@@ -182,10 +188,11 @@ public void OnEndDrag(PointerEventData eventData)
|
||||
crowbarVisual.rotation = nearestSocket.visual.transform.rotation;
|
||||
isInserted = true;
|
||||
nearestSocket.RemovePlug();
|
||||
nearestSocket.DisableSocket();
|
||||
nearestSocket.DisableSocket();
|
||||
crowbarSocket=nearestSocket;
|
||||
crowbarCanvas.sortingLayerName = "UnderModule";
|
||||
crowbarCanvas.sortingOrder = 6;
|
||||
Debug.Log("crowbarsocket name"+crowbarSocket.name);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -212,6 +219,10 @@ public CrowBarSocket FindNearestSocket()
|
||||
|
||||
foreach (var socket in crowbarSockets)
|
||||
{
|
||||
if(!socket.gameObject.activeInHierarchy)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
float distance = Vector3.Distance(transform.position, socket.transform.position);
|
||||
if (distance <= minDistance && socket.IsAvailable)
|
||||
{
|
||||
|
||||
@@ -4,7 +4,6 @@ using AibisDream;
|
||||
|
||||
public class InteractiveLineSegment : VisualLineSegment
|
||||
{
|
||||
[SerializeField]
|
||||
private Transform startTransform;
|
||||
public Transform StartTransform
|
||||
{
|
||||
@@ -12,7 +11,6 @@ public class InteractiveLineSegment : VisualLineSegment
|
||||
set { startTransform = value; }
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private Transform endTransform;
|
||||
public Transform EndTransform
|
||||
{
|
||||
@@ -20,6 +18,8 @@ public class InteractiveLineSegment : VisualLineSegment
|
||||
set { endTransform = value; }
|
||||
}
|
||||
|
||||
private LineRenderer strokeLineRenderer; // 新的 LineRenderer 对象作为描边
|
||||
|
||||
private BoxCollider2D boxCollider;
|
||||
|
||||
private YarnOption _option;
|
||||
@@ -43,50 +43,70 @@ public class InteractiveLineSegment : VisualLineSegment
|
||||
|
||||
public void OnHover()
|
||||
{
|
||||
if (IsCuttable)
|
||||
{
|
||||
TurnGreen();
|
||||
}
|
||||
else
|
||||
{
|
||||
TurnRed();
|
||||
}
|
||||
strokeLineRenderer.enabled = true;
|
||||
// if (IsCuttable)
|
||||
// {
|
||||
// TurnGreen();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// TurnRed();
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
public void OnHoverExit()
|
||||
{
|
||||
TurnGrey();
|
||||
// TurnGrey();
|
||||
strokeLineRenderer.enabled = false;
|
||||
}
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
boxCollider = GetComponent<BoxCollider2D>();
|
||||
|
||||
}
|
||||
public void Start()
|
||||
{
|
||||
Initialize();
|
||||
InitializeStrokeLineRenderer();
|
||||
|
||||
}
|
||||
private LineRenderer CopyLineRenderer(LineRenderer source)
|
||||
{
|
||||
LineRenderer newLineRenderer = new GameObject("StrokeLine").AddComponent<LineRenderer>();
|
||||
|
||||
// Copy the properties from the source LineRenderer to the new one
|
||||
newLineRenderer.material = source.material;
|
||||
newLineRenderer.startColor = source.startColor;
|
||||
newLineRenderer.endColor = source.endColor;
|
||||
newLineRenderer.startWidth = source.startWidth;
|
||||
newLineRenderer.endWidth = source.endWidth;
|
||||
newLineRenderer.numCornerVertices = source.numCornerVertices;
|
||||
newLineRenderer.numCapVertices = source.numCapVertices;
|
||||
newLineRenderer.positionCount = source.positionCount;
|
||||
newLineRenderer.sortingLayerName = source.sortingLayerName;
|
||||
newLineRenderer.sortingOrder = source.sortingOrder-1;
|
||||
|
||||
// Set the parent of the new GameObject to the same as the source
|
||||
newLineRenderer.transform.parent = source.transform;
|
||||
|
||||
return newLineRenderer;
|
||||
}
|
||||
private void InitializeStrokeLineRenderer()
|
||||
{
|
||||
strokeLineRenderer = CopyLineRenderer(GetComponent<LineRenderer>());
|
||||
// 设置描边的 LineRenderer 的属性
|
||||
strokeLineRenderer.SetPosition(0, StartTransform.position);
|
||||
strokeLineRenderer.SetPosition(1, EndTransform.position);
|
||||
strokeLineRenderer.endColor = Color.white;
|
||||
strokeLineRenderer.startColor = Color.white;
|
||||
strokeLineRenderer.widthMultiplier = lineRenderer.widthMultiplier * 1.2f; // 假设描边的宽度是原线条宽度的 1.2 倍
|
||||
strokeLineRenderer.enabled = false; // 初始时禁用描边
|
||||
}
|
||||
|
||||
|
||||
public void TurnGreen()
|
||||
{
|
||||
lineRenderer.material.color = Color.green; // 改变 LineRenderer 的颜色
|
||||
}
|
||||
|
||||
public void TurnGrey()
|
||||
{
|
||||
lineRenderer.material.color = Color.grey; // 改变 LineRenderer 的颜色
|
||||
}
|
||||
public void TurnRed()
|
||||
{
|
||||
lineRenderer.material.color = Color.red; // 改变 LineRenderer 的颜色
|
||||
}
|
||||
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
TurnGrey();
|
||||
if (StartTransform == null || EndTransform == null)
|
||||
{
|
||||
Debug.LogError("StartTransform or EndTransform is not set.");
|
||||
|
||||
@@ -6,10 +6,21 @@ using System.Collections;
|
||||
using AibisDream;
|
||||
using System.Linq;
|
||||
using DG.Tweening;
|
||||
|
||||
[System.Serializable]
|
||||
public class LineSegmentInfo
|
||||
{
|
||||
public string Name;
|
||||
public Transform StartTransform;
|
||||
public Transform EndTransform;
|
||||
}
|
||||
public class LineManager : MonoBehaviour
|
||||
{
|
||||
//public GameObject interactiveLineSegmentPrefab;
|
||||
public InteractiveLineSegment interactiveLineSegmentPrefab; // InteractiveLineSegment 的预制体
|
||||
[SerializeField]
|
||||
private List<LineSegmentInfo> lineSegmentInfos; // 线段信息的列表
|
||||
|
||||
// 线段字典,用于快速查找
|
||||
|
||||
public GameObject physicLineSegmentPrefab;
|
||||
|
||||
public CustomCursor customCursor; // 自定义光标,你可以在 Inspector 中设置
|
||||
@@ -44,9 +55,20 @@ public class LineManager : MonoBehaviour
|
||||
}
|
||||
private InteractiveLineSegment currentLineSegment; // 当前要被剪断的线段
|
||||
|
||||
private const float LONG_PRESS_THRESHOLD = 3.0f; // 长按阈值,可以根据需要调整
|
||||
private const float LONG_PRESS_THRESHOLD = 0.01f; // 长按阈值,可以根据需要调整
|
||||
private float longPressTime = 0.0f; // 长按时间
|
||||
private float detectionRadius=0.4f;
|
||||
private float detectionRadius=0.25f;
|
||||
|
||||
private void SaveCutLine(string lineName)
|
||||
{
|
||||
PlayerPrefs.SetString(lineName, "cut");
|
||||
PlayerPrefs.Save();
|
||||
}
|
||||
|
||||
private bool IsLineCut(string lineName)
|
||||
{
|
||||
return PlayerPrefs.HasKey(lineName);
|
||||
}
|
||||
|
||||
public void CutLine(InteractiveLineSegment originalLineSegment, Vector3 splitPoint)
|
||||
{
|
||||
@@ -60,17 +82,41 @@ public void CutLine(InteractiveLineSegment originalLineSegment, Vector3 splitPoi
|
||||
GameObject firstLineSegmentObject = Instantiate(physicLineSegmentPrefab, transform);
|
||||
PhysicLineSegment firstLineSegment = firstLineSegmentObject.GetComponent<PhysicLineSegment>();
|
||||
firstLineSegment.Initialize(originalLineSegment.StartTransform.position, splitPoint);
|
||||
firstLineSegment.lineRenderer.startColor=originalLineSegment.lineRenderer.startColor;
|
||||
firstLineSegment.lineRenderer.endColor=originalLineSegment.lineRenderer.endColor;
|
||||
|
||||
// Create the second new line segment
|
||||
GameObject secondLineSegmentObject = Instantiate(physicLineSegmentPrefab, transform);
|
||||
PhysicLineSegment secondLineSegment = secondLineSegmentObject.GetComponent<PhysicLineSegment>();
|
||||
secondLineSegment.Initialize(originalLineSegment.EndTransform.position,splitPoint);
|
||||
originalLineSegment.Option.SelectOption();
|
||||
|
||||
secondLineSegment.lineRenderer.startColor=originalLineSegment.lineRenderer.startColor;
|
||||
secondLineSegment.lineRenderer.endColor=originalLineSegment.lineRenderer.endColor;
|
||||
// Immediately destroy the original line segment
|
||||
Destroy(originalLineSegment.gameObject);
|
||||
Debug.Log("线销毁了");
|
||||
SaveCutLine(originalLineSegment.name);
|
||||
|
||||
// Start the coroutine to destroy the new line segments after fade in and out
|
||||
StartCoroutine(DestroyNewSegmentsAfterFade(firstLineSegmentObject, secondLineSegmentObject,originalLineSegment));
|
||||
}
|
||||
|
||||
private IEnumerator DestroyNewSegmentsAfterFade(GameObject firstLineSegmentObject, GameObject secondLineSegmentObject,InteractiveLineSegment originalLineSegment)
|
||||
{
|
||||
// Assume FadeIn() is a method that starts the fade in animation and returns the duration of the animation
|
||||
float fadeDuration = 2f;
|
||||
DialogController.FadeIn(fadeDuration);
|
||||
// Wait for the fade in animation to finish
|
||||
// Destroy the new line segments
|
||||
yield return new WaitForSeconds(fadeDuration);
|
||||
Destroy(firstLineSegmentObject);
|
||||
Destroy(secondLineSegmentObject);
|
||||
// Assume FadeOut() is a method that starts the fade out animation and returns the duration of the animation
|
||||
DialogController.FadeOut(fadeDuration);
|
||||
yield return new WaitForSeconds(fadeDuration);
|
||||
originalLineSegment.Option.SelectOption();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void AddPhysicsComponents(GameObject lineSegmentObject)
|
||||
{
|
||||
@@ -117,6 +163,8 @@ private void LongPressLineSegment(InteractiveLineSegment lineSegment)
|
||||
longPressTime += Time.deltaTime;
|
||||
Vector3 midpoint = (lineSegment.StartPoint + lineSegment.EndPoint) / 2;
|
||||
|
||||
float distance = Vector3.Distance(midpoint, lineSegment.StartPoint);
|
||||
|
||||
// Make the scissors shake and the line segment turn red
|
||||
if (longPressTime < LONG_PRESS_THRESHOLD)
|
||||
{
|
||||
@@ -127,11 +175,29 @@ private void LongPressLineSegment(InteractiveLineSegment lineSegment)
|
||||
|
||||
// Move the scissors towards the midpoint
|
||||
//customCursor.transform.DOMove(midpoint, 0.1f);
|
||||
|
||||
float progress = longPressTime / LONG_PRESS_THRESHOLD;
|
||||
// Calculate the new position of the color gradient
|
||||
float newPosition = progress * distance;
|
||||
|
||||
// Create a new color gradient
|
||||
// Gradient gradient = new Gradient();
|
||||
|
||||
// // Set the color keys of the gradient
|
||||
// gradient.SetKeys(
|
||||
// new GradientColorKey[] { new GradientColorKey(Color.red, 0.0f), new GradientColorKey(lineSegment.GetComponent<LineRenderer>().startColor, newPosition) },
|
||||
// new GradientAlphaKey[] { new GradientAlphaKey(1.0f, 0.0f), new GradientAlphaKey(1.0f, newPosition) }
|
||||
// );
|
||||
|
||||
// // Set the color gradient of the LineRenderer
|
||||
// lineSegment.GetComponent<LineRenderer>().colorGradient = gradient;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Cut the line segment
|
||||
CutLine(lineSegment,midpoint);
|
||||
IsScissorsMode=false;
|
||||
Debug.Log("线剪断触发了");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +205,7 @@ private void ExitLineSegment()
|
||||
{
|
||||
if (currentLineSegment != null)
|
||||
{
|
||||
currentLineSegment.TurnGrey();
|
||||
currentLineSegment.OnHoverExit();
|
||||
}
|
||||
currentLineSegment = null;
|
||||
}
|
||||
@@ -195,16 +261,86 @@ private void ExitLineSegment()
|
||||
}
|
||||
|
||||
|
||||
[YarnCommand("reconnected_line")]
|
||||
public void Reconnected(string input)
|
||||
{
|
||||
// Use GetLineSegmentName method to find the recognized name
|
||||
string recognizedName = GetLineSegmentName(input);
|
||||
|
||||
if (recognizedName == null)
|
||||
{
|
||||
Debug.LogError("Invalid LineSegmentInfo name: " + input);
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the LineSegmentInfo with the recognized name
|
||||
LineSegmentInfo lineSegmentInfo = lineSegmentInfos.Find(info => info.Name == recognizedName);
|
||||
|
||||
if (lineSegmentInfo == null)
|
||||
{
|
||||
Debug.LogError("Invalid LineSegmentInfo name: " + recognizedName);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the line is already cut, skip it
|
||||
// if (!IsLineCut(lineSegmentInfo.Name))
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// Instantiate a new line segment with the given info
|
||||
InteractiveLineSegment newSegment = Instantiate(interactiveLineSegmentPrefab, transform);
|
||||
newSegment.StartTransform = lineSegmentInfo.StartTransform;
|
||||
newSegment.EndTransform = lineSegmentInfo.EndTransform;
|
||||
newSegment.Initialize();
|
||||
|
||||
// Add the new line segment to the dictionary
|
||||
//lineSegmentDictionary.Add(lineSegmentInfo.Name, newSegment);
|
||||
}
|
||||
[YarnCommand("delete_line")]
|
||||
public void DeleteLine(string input)
|
||||
{
|
||||
// Use GetLineSegmentName method to find the recognized name
|
||||
string recognizedName = GetLineSegmentName(input);
|
||||
|
||||
if (recognizedName == null)
|
||||
{
|
||||
Debug.LogError("Invalid LineSegmentInfo name: " + input);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lineSegmentDictionary.ContainsKey(recognizedName))
|
||||
{
|
||||
InteractiveLineSegment lineSegmentToRemove = lineSegmentDictionary[recognizedName];
|
||||
lineSegmentDictionary.Remove(recognizedName);
|
||||
|
||||
// Destroy the line segment GameObject
|
||||
Destroy(lineSegmentToRemove.gameObject);
|
||||
|
||||
Debug.Log("Line segment removed: " + recognizedName);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Line segment not found in dictionary: " + recognizedName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// 查找场景中的所有 InteractiveLineSegment 并添加到字典中
|
||||
InteractiveLineSegment[] lineSegments = FindObjectsOfType<InteractiveLineSegment>();
|
||||
foreach (InteractiveLineSegment lineSegment in lineSegments)
|
||||
{
|
||||
lineSegmentDictionary.Add(lineSegment.name, lineSegment);
|
||||
Debug.Log("Added " + lineSegment.name + " to lineSegmentDictionary");
|
||||
}
|
||||
foreach (LineSegmentInfo lineSegmentInfo in lineSegmentInfos)
|
||||
{
|
||||
if (IsLineCut(lineSegmentInfo.Name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
InteractiveLineSegment newSegment = Instantiate(interactiveLineSegmentPrefab, transform);
|
||||
newSegment.StartTransform = lineSegmentInfo.StartTransform;
|
||||
newSegment.EndTransform = lineSegmentInfo.EndTransform;
|
||||
newSegment.Initialize();
|
||||
lineSegmentDictionary.Add(lineSegmentInfo.Name, newSegment);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public InteractiveLineSegment GetLineSegmentByName(string lineSegmentName)
|
||||
|
||||
@@ -12,7 +12,8 @@ public class PhysicLineSegment : MonoBehaviour
|
||||
|
||||
private List<VerletParticle> particles = new List<VerletParticle>();
|
||||
private List<VerletStick> sticks = new List<VerletStick>();
|
||||
private LineRenderer lineRenderer;
|
||||
[HideInInspector]
|
||||
public LineRenderer lineRenderer;
|
||||
private int segmentCount;
|
||||
public float gravity = -9.8f;
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ public class VisualLineSegment : MonoBehaviour
|
||||
{
|
||||
public Vector3 StartPoint { get; private set; }
|
||||
public Vector3 EndPoint { get; private set; }
|
||||
|
||||
protected LineRenderer lineRenderer;
|
||||
[HideInInspector]
|
||||
public LineRenderer lineRenderer;
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
@@ -23,6 +23,7 @@ public class VisualLineSegment : MonoBehaviour
|
||||
lineRenderer.SetPosition(1, EndPoint);
|
||||
}
|
||||
|
||||
|
||||
// public void ShrinkAndDisappear()
|
||||
// {
|
||||
// // Shrink the line segment from the end to the start
|
||||
|
||||
Reference in New Issue
Block a user