Files
aibis-dream/Assets/Scripts/FixSystemNew/BodyModule/BodyModule.cs
T
2025-05-16 16:58:45 +08:00

190 lines
5.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using AibisDream.Framework;
using AibisDream.Kit;
using AibisDream.Utility;
using DG.Tweening;
using Newtonsoft.Json;
using UnityEngine;
namespace AibisDream.FixSystem
{
public class BodyModule : MonoBehaviour, ISocket
{
#region 组件引用
private const string SocketObjName = "Socket";
public Transform socketPos;
private BodyModuleSystem _bodyModuleSystem;
private Material _highlightMaterial;
private Material _alarmMaterial;
private Material _originalMaterial; // 原材质
private SpriteRenderer _targetSpriteRenderer; // 目标的 SpriteRenderer
private CutLine _cutLine;
#endregion
// 模块基本数据
[SerializeField] public BodyModuleData data;
private float clickRadius = 0.05f;
public bool available = true;
private bool _cutting;
private void Awake()
{
// 获取组件索引
InitReference();
}
private void InitReference()
{
socketPos = transform.Find(SocketObjName);
_bodyModuleSystem = transform.parent.parent.GetComponent<BodyModuleSystem>();
_targetSpriteRenderer = transform.Find("Module Pic").GetComponent<SpriteRenderer>();
_originalMaterial = _targetSpriteRenderer.GetComponent<SpriteRenderer>().material;
_highlightMaterial = Resources.Load<Material>("Materials/HighlightMaterial");
_alarmMaterial = Resources.Load<Material>("Materials/AlarmMaterial");
}
private void Update()
{
if (_cutting && Input.GetMouseButton(0))
{
OnCut();
}
}
#region 插槽功能
public bool IsAvailable()
{
return available;
}
public void SetSocketAvailable(bool isAvailable)
{
available = isAvailable;
}
public void PlugIn()
{
if (DialogController.Instance)
// 然后触发Yarn节点
DialogController.Instance.StartDialogNode(_bodyModuleSystem.inHotErr ? "系统发热" : data.PlugInNodeName);
}
public void PlugOut()
{
}
public Vector3 GetSocketPos()
{
return socketPos.position;
}
#endregion
#region 高亮提示和隐藏
public void Highlight(bool enable)
{
if (_targetSpriteRenderer != null && _highlightMaterial != null &&
_targetSpriteRenderer.material != _alarmMaterial)
{
_targetSpriteRenderer.material = enable ? _highlightMaterial : _originalMaterial;
}
}
public void Alarm(bool enable)
{
if (_targetSpriteRenderer != null && _alarmMaterial != null)
{
_targetSpriteRenderer.material = enable ? _alarmMaterial : _originalMaterial;
}
}
#endregion
#region 切割相关
public void EnableCut()
{
// 打开或获取CutLine
ShowCutLine();
_cutLine.OnCuttingDown += OnCuttingDown;
_cutting = true;
EnumEventSystem.Global.Send(EventEnum.CutStart);
}
private void OnCut()
{
Vector2 mousePos = CommonUtil.GetMouseWorldPos(Input.mousePosition);
_cutLine.DetectLineClick(mousePos, clickRadius);
}
private void OnCuttingDown()
{
_cutLine.OnCuttingDown -= OnCuttingDown;
_cutting = false;
// 模块脱落
_cutLine.HideLine();
_bodyModuleSystem.RemoveModule(this);
ActionKit.Sequence()
.Delay(0.8f)
.DOTween(() => transform.DOMoveY(ConstRef.TweenEndY,
(transform.position.y - ConstRef.TweenEndY) / (ConstRef.FallSpeed * 0.6f))
.SetEase(Ease.InQuad))
.Callback(() => DialogController.Instance?.StartDialogNode($"{data.moduleName}CutDown"))
.Callback(() => EnumEventSystem.Global.Send(EventEnum.CutEnd))
.Start(this, () => Destroy(gameObject));
}
private void ShowCutLine()
{
// 切割线不存在,就新建一个
if (!_cutLine)
{
var prefab = ResourceKit.LoadAssetSync<GameObject>(ConstRef.CutLinePrefabName);
var cutLineObj = Instantiate(prefab, transform);
_cutLine = cutLineObj.GetComponent<CutLine>();
}
// 对切割线进行初始化
var shapePoints = new List<Vector2>();
_targetSpriteRenderer.sprite.GetPhysicsShape(0, shapePoints);
if (shapePoints.Count <= 0)
{
Debug.LogWarning($"{name} has no shape");
return;
}
// 本地坐标转世界坐标
var shapePointsV3 = shapePoints
.Select(item => _targetSpriteRenderer.transform.TransformPoint(item))
.ToList();
_cutLine.Init(shapePointsV3, clickRadius);
}
#endregion
}
[Serializable]
public struct BodyModuleData
{
public const string PlugInNodeTemplate = "{0}PlugIn";
// ID
public string moduleName;
// 只读
[JsonIgnore] public string PlugInNodeName => string.Format(PlugInNodeTemplate, moduleName);
}
}