This commit is contained in:
2024-12-12 01:07:26 +08:00
parent 2667419d98
commit 3fcff0598a
55 changed files with 1861 additions and 964 deletions
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 97a19921a1af4dd291a2e5fd307c02df
timeCreated: 1733904654
@@ -17,7 +17,6 @@ namespace AibisDream.FixSystem
public GameObject bodyModulePrefab;
public Transform bodyModuleGroup;
public OscilloscopeSystem oscilloscopeSystem;
#endregion
@@ -119,6 +118,14 @@ namespace AibisDream.FixSystem
curBodyModule?.ShowWave();
}
/// <summary>
/// 插头重新插入初始插孔
/// </summary>
public void ResetPlug()
{
CableSystem.ResetPlug();
}
#region
public override string[] GetDataKeyOptions()
@@ -64,6 +64,15 @@ namespace AibisDream.FixSystem
PlugRef.InitPlug(InitSocket);
}
public void ResetPlug()
{
// 已经在初始插孔里了,不用动
if (curSocket == InitSocket) return;
// 不在初始插孔里,就从当前插孔拔出来,插回初始插孔
PlugRef.PullUpSocket();
PlugRef.InsertSocket(InitSocket);
}
/// <summary>
/// 寻找最接近的Module
/// </summary>
@@ -9,6 +9,8 @@ namespace AibisDream.FixSystem
{
#region
private BodyModuleSystem _bodyModuleSystem;
private TMP_Text _screenText;
private WaveformLine _waveformLine;
private ScanLine _scanLine;
@@ -114,7 +116,7 @@ namespace AibisDream.FixSystem
/// </summary>
public void OnScanSuccess()
{
FixSystemCenter.SystemDic.Get<BodyModuleSystem>().HandleDeepIn();
_bodyModuleSystem.HandleDeepIn();
_ = CommonUtil.Delay(2000, StopWave);
}
@@ -47,7 +47,7 @@ namespace AibisDream.FixSystem
/// 插入某个socket
/// </summary>
/// <param name="targetSocket">目标socket</param>
private void InsertSocket(ISocket targetSocket)
public void InsertSocket(ISocket targetSocket)
{
// 修改插头位置
transform.position = targetSocket.GetSocketPos();
@@ -71,7 +71,7 @@ namespace AibisDream.FixSystem
/// <summary>
/// 从某个Socket拔出来
/// </summary>
private void PullUpSocket()
public void PullUpSocket()
{
// 修改线头位置
_cableSystem.CableRef.SetEndPos(_plugRootPos);
@@ -82,7 +82,6 @@ namespace AibisDream.FixSystem
// 触发事件
_cableSystem.BodyModuleSystem.plugOutEvent?.Invoke(_cableSystem.curSocket);
_cableSystem.curBodyModule = null;
_cableSystem.curSocket = null;
}
@@ -9,6 +9,7 @@ namespace AibisDream.FixSystem
#region
private LineRenderer _line;
private OscilloscopeSystem _oscilloscopeSystem;
#endregion
@@ -33,6 +34,8 @@ namespace AibisDream.FixSystem
private void InitComponentRefs()
{
_oscilloscopeSystem = GetComponentInParent<OscilloscopeSystem>();
_line = GetComponent<LineRenderer>();
_line.enabled = false;
_line.positionCount = 2;
@@ -41,7 +44,7 @@ namespace AibisDream.FixSystem
public IEnumerator ScanForError(float spikeX)
{
_line.enabled = true;
FixSystemCenter.SystemDic.Get<OscilloscopeSystem>().isScanning = true;
_oscilloscopeSystem.isScanning = true;
// 初始化扫描线
InitStartLine();
// 扫描线右移
@@ -68,7 +71,7 @@ namespace AibisDream.FixSystem
yield return null;
}
FixSystemCenter.SystemDic.Get<OscilloscopeSystem>().isScanning = false;
_oscilloscopeSystem.isScanning = false;
}
private void InitStartLine()
@@ -0,0 +1,44 @@
using UnityEngine;
namespace AibisDream
{
public class BottleSlot : MonoBehaviour
{
private CoolingMachineViewer _coolingMachine;
private void Awake()
{
InitComponentRefs();
}
private void InitComponentRefs()
{
_coolingMachine = GetComponentInParent<CoolingMachineViewer>();
}
private void OnTriggerEnter2D(Collider2D other)
{
if (_coolingMachine.isLocked) return;
if (other.gameObject.TryGetComponent<CoolingBottle>(out var bottle))
{
// 进入时只给吸附标记,松手才吸附
bottle.isSnapped = true;
}
}
private void OnTriggerExit2D(Collider2D other)
{
if (_coolingMachine.isLocked) return;
if (other.gameObject.TryGetComponent<CoolingBottle>(out var bottle))
{
// 离开时直接触发拔出逻辑,不等松手
bottle.isSnapped = false;
// 拔出
_coolingMachine.MoveOutBottle();
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bdcb57f53aa757b45a44803a2441d888
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,5 +1,4 @@
using System;
using AibisDream.Framework;
using AibisDream.Framework;
using DG.Tweening;
using UnityEngine;
@@ -7,41 +6,97 @@ namespace AibisDream
{
public class CoolingBottle : MonoBehaviour, IMoveable
{
private GameObject _mask;
public CoolingMachineViewer coolingMachine;
private Transform _mask;
private Rigidbody2D _rb;
private static readonly Vector3 UpPos = new(0, 1.56f, 0);
private static readonly Vector3 UpPos = new(0, 1.86f, 0);
private static readonly Vector3 DownPos = Vector3.zero;
public bool isSnapped;
public bool isInMachine;
public bool isLocked;
public bool isEmpty;
public bool IsBlock { get; }
private void Awake()
{
InitComponentRefs();
}
private void InitComponentRefs()
{
_rb = GetComponent<Rigidbody2D>();
_mask = transform.Find("Mask");
coolingMachine = FindObjectOfType<CoolingMachineViewer>();
_mask.localPosition = isEmpty ? DownPos : UpPos;
}
public void LiquidDown(float duration)
{
_mask.transform.DOMove(DownPos, duration).OnComplete(() => isEmpty = true);
var targetPos = transform.parent.TransformPoint(DownPos);
_mask.transform.DOMove(targetPos, duration).OnComplete(() => isEmpty = true);
}
public void LiquidUp(float duration)
{
_mask.transform.DOMove(UpPos, duration).OnComplete(() => isEmpty = false);
var targetPos = transform.parent.TransformPoint(UpPos);
_mask.transform.DOMove(targetPos, duration).OnComplete(() => isEmpty = false);
}
public void StartMove()
{
}
public void Move(Vector2 mousePos)
{
// 锁定后无法移动
if (isLocked) return;
_rb.MovePosition(mousePos);
}
public void StopMove()
{
// 松手时若是已吸附,就触发插入逻辑
if (isSnapped) coolingMachine.InsertBottle(this);
}
/// <summary>
/// 松手后吸附至某个位置
/// </summary>
/// <param name="snapPos">吸附点位</param>
public void Snap(Vector3 snapPos)
{
// 吸附至指定位置
transform.position = snapPos;
// 停用重力
_rb.gravityScale = 0;
// 瓶子进入机器
isInMachine = true;
}
/// <summary>
/// 离开指定位置就停止吸附
/// </summary>
public void Unsnap()
{
// 重新启用重力
_rb.gravityScale = 1;
// 瓶子不在机器中
isInMachine = false;
}
public void Lock()
{
isLocked = true;
}
public void Unlock()
{
isLocked = false;
}
}
}
@@ -1,17 +1,30 @@
using DG.Tweening;
using UnityEngine;
namespace AibisDream
{
public class CoolingMachineSystem : MonoBehaviour, ICoolingMachine
public class CoolingMachineViewer : MonoBehaviour, ICoolingMachine
{
public bool isMachineEmpty;
public GameObject bottleSlot;
[Header("引用")] public GameObject bottleSlot;
public CoolingBottle bottle;
public GameObject pumpHead;
public GameObject lockSwitch;
public GameObject pumpButton;
public LockSlider lockSlider;
public Transform pumpHead;
private SpriteButton _button;
[Header("参数")] public float pumpDuration = 3f;
public float resetDuration = 0.5f;
public float pumpHeadUpY;
public float pumpHeadDownY;
#region
[Header("状态")] public bool isMachineEmpty;
public bool isLocked;
public bool inLiquidChange;
#endregion
#region
public void LinkRobot()
@@ -25,30 +38,35 @@ namespace AibisDream
/// </summary>
public void PumpCooling()
{
// 泵头下降
inLiquidChange = true;
// 液面上升
// 完成后液体满了
isMachineEmpty = true;
bottle.LiquidUp(pumpDuration);
// 泵头下降
var sq = GenePumpHeadAnime();
sq.OnComplete(() =>
{
inLiquidChange = false;
isMachineEmpty = false;
});
}
public void UnlockBottle()
{
// 卡扣上移
// 瓶子外旋
// 机器空置
// 动画效果拉杆处理了
// 触发锁定逻辑
isMachineEmpty = false;
isLocked = false;
bottle?.Unlock();
lockSlider.DisableHook();
}
public void MoveOutBottle()
{
if (bottle == null) return;
// 瓶子置空
bottle.transform.parent = null;
// 停止吸附
bottle?.Unsnap();
}
public void InsertBottle(CoolingBottle newBottle)
@@ -56,25 +74,33 @@ namespace AibisDream
// 改变瓶子归属
newBottle.transform.parent = bottleSlot.transform;
bottle = newBottle;
// 插入瓶子
bottle.Snap(bottleSlot.transform.position);
}
public void LockBottle()
{
// 插槽回旋
// 卡扣下降
// 同步液体状态
isMachineEmpty = bottle.isEmpty;
// TODO 同步泵头状态
// 动画效果在拉杆的地方就处理了
// 触发锁定逻辑
isMachineEmpty = !bottle || bottle.isEmpty;
isLocked = true;
bottle?.Lock();
// 如果当前没有瓶子,就打开卡扣碰撞
if (!bottle) lockSlider.EnableHook();
}
public void InjectCool()
{
throw new System.NotImplementedException();
inLiquidChange = true;
// 泵头下降
var sq = GenePumpHeadAnime();
sq.OnComplete(() =>
{
inLiquidChange = false;
isMachineEmpty = true;
});
// 液面上升
bottle.LiquidDown(pumpDuration);
}
public void UnlinkRobot()
@@ -82,8 +108,44 @@ namespace AibisDream
throw new System.NotImplementedException();
}
public bool CanPump()
{
if (inLiquidChange)
{
Debug.Log("泵机正在工作");
return false;
}
if (!isLocked)
{
Debug.Log("卡扣尚未锁定");
return false;
}
if (!bottle)
{
Debug.Log("没有瓶子");
return false;
}
return true;
}
#endregion
private Sequence GenePumpHeadAnime()
{
var sequence = DOTween.Sequence();
// 下降动画
var pumpDownPos = new Vector3(pumpHead.position.x, pumpHeadDownY + transform.position.y,
pumpHead.position.z);
sequence.Append(pumpHead.DOMove(pumpDownPos, pumpDuration));
// 上升动画
var pumpUpPos = new Vector3(pumpHead.position.x, pumpHeadUpY + transform.position.y, pumpHead.position.z);
sequence.Append(pumpHead.DOMove(pumpUpPos, resetDuration));
return sequence;
}
}
/// <summary>
@@ -100,4 +162,4 @@ namespace AibisDream
void InjectCool();
void UnlinkRobot();
}
}
}
@@ -0,0 +1,91 @@
using AibisDream.Framework;
using UnityEngine;
namespace AibisDream
{
public class LockSlider : MonoBehaviour, IMoveable
{
private Transform _drawBar;
private Transform _hook;
private CoolingMachineViewer _coolingMachine;
private bool _isLocked;
private float Value
{
set
{
var sliderY = value * (offPos.position.y - onPos.position.y) + onPos.position.y;
transform.position = new Vector3(_drawBar.position.x, sliderY, _drawBar.position.z);
var hookY = value * (lockOffPos.position.y - lockOnPos.position.y) + lockOnPos.position.y;
_hook.position = new Vector3(_hook.position.x, hookY, _hook.position.z);
}
}
public Transform onPos;
public Transform offPos;
public Transform lockOnPos;
public Transform lockOffPos;
public bool IsBlock => _coolingMachine.inLiquidChange;
private void Awake()
{
_coolingMachine = GetComponentInParent<CoolingMachineViewer>();
_drawBar = transform;
_hook = transform.parent.Find("活动卡扣");
_isLocked = true;
}
public void StartMove()
{
}
public void Move(Vector2 mousePos)
{
var curY = Mathf.Clamp(mousePos.y, onPos.position.y, offPos.position.y);
Value = (curY - onPos.position.y) / (offPos.position.y - onPos.position.y);
}
public void StopMove()
{
var curValue = (_drawBar.position.y - onPos.position.y) / (offPos.position.y - onPos.position.y);
// 大于0.8或者小于0.2则切换状态,否则弹回去
_isLocked = curValue switch
{
// 移动停止时尝试吸附
>= 0.8f => false,
<= 0.2f => true,
_ => _isLocked
};
Value = _isLocked ? 0 : 1;
// 判定开闭锁
if (_isLocked)
{
_coolingMachine.LockBottle();
}
else
{
_coolingMachine.UnlockBottle();
}
}
/// <summary>
/// 打开卡扣碰撞
/// </summary>
public void EnableHook()
{
_hook.GetComponent<Collider2D>().enabled = true;
}
/// <summary>
/// 关闭卡扣碰撞
/// </summary>
public void DisableHook()
{
_hook.GetComponent<Collider2D>().enabled = false;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9f15b93b1e22b11459ca121bedee9ba7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,47 @@
using UnityEngine;
namespace AibisDream
{
public class PumpButton : MonoBehaviour
{
private SpriteButton _button;
private CoolingMachineViewer _coolingMachine;
private void Awake()
{
_coolingMachine = GetComponentInParent<CoolingMachineViewer>();
}
private void OnEnable()
{
_button = new SpriteButton(gameObject);
_button.OnButtonDown += OnButtonDown;
}
private void OnDisable()
{
_button.OnButtonDown -= OnButtonDown;
_button = null;
}
private void Update()
{
_button.CheckButtonClick();
}
private void OnButtonDown()
{
if (!_coolingMachine.CanPump()) return;
if (_coolingMachine.isMachineEmpty)
{
_coolingMachine.PumpCooling();
}
else
{
Debug.Log("in");
_coolingMachine.InjectCool();
}
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c1098201b6934115ac7c06afa1564dab
timeCreated: 1733580710
+41 -5
View File
@@ -1,21 +1,57 @@
using AibisDream.Framework;
using AibisDream.Kit;
using UnityEngine;
namespace AibisDream.FixSystem
{
public class FixSystemCenter : MonoBehaviour
public class FixSystemCenter : Singleton<FixSystemCenter>
{
public static IOCContainer SystemDic = new();
public FixState curState;
private void Awake()
public override void OnSingletonInit()
{
SystemDic ??= new IOCContainer();
InitTransitionDic();
// TODO 这个回头要改
curState = FixState.BodyModule;
}
private void OnDestroy()
#region
// 容纳System
public static IOCContainer SystemDic = new();
#endregion
#region
private static readonly StateDictionary<ITransitionCommand> TransitionDic = new();
private void InitTransitionDic()
{
SystemDic = null;
TransitionDic.Add(FixState.BodyModule, FixState.Engine, new BodyModuleToEngineCommand());
}
/// <summary>
/// 执行转场
/// </summary>
/// <param name="nextState">需要转换的状态</param>
public void TransToNextState(FixState nextState)
{
// 没存过的先打个日志报错
if (!TransitionDic.TryGetValue(curState, nextState, out var command))
{
Debug.Log($"源为{curState.ToString()}, 目标为{nextState.ToString()}, 转场命令不存在");
return;
}
// 存过的执行转场命令
StartCoroutine(command.Execute());
curState = nextState;
}
#endregion
}
}
@@ -1,5 +1,4 @@
using AibisDream.Framework;
using UnityEngine;
using UnityEngine;
using Yarn.Unity;
namespace AibisDream.FixSystem
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 51102ff352f0a80499cae251e2267fe4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,175 @@
using System;
using System.Collections;
using System.Collections.Generic;
using AibisDream.Framework;
using DG.Tweening;
using UnityEngine;
namespace AibisDream.FixSystem
{
public enum FixState
{
Clinic,
CoolingMachine,
BodyModule,
Memory,
VisualSense,
Engine,
Gear
}
public interface ITransitionCommand
{
IEnumerator Execute();
}
public struct BodyModuleToEngineCommand : ITransitionCommand
{
// 引擎相机设置
private static readonly Vector3 CameraPos = new(-2.5f, 2.13f, -10);
private const float OrthographicSize = 2.5f;
private const float Duration = 2f;
public IEnumerator Execute()
{
var bodyModuleSystem = FixSystemCenter.SystemDic.Get<BodyModuleSystem>();
var engineSystem = FixSystemCenter.SystemDic.Get<EngineSystem>();
// 插头回到初始插孔
bodyModuleSystem.ResetPlug();
// 相机聚焦到目标位
var cameraSq = CameraKit.Instance.TransCamera(CameraPos, OrthographicSize, Duration);
while (cameraSq.active && !cameraSq.IsComplete())
{
yield return null;
}
// 打开引擎盖子
var coverSq = engineSystem.OpenCover();
while (coverSq.active && !coverSq.IsComplete())
{
yield return null;
}
}
}
public struct EngineToBodyModuleCommand : ITransitionCommand
{
private const float Duration = 2f;
public IEnumerator Execute()
{
var engineSystem = FixSystemCenter.SystemDic.Get<EngineSystem>();
// 关闭引擎盖
var coverSq = engineSystem.CloseCover();
while (coverSq.active && !coverSq.IsComplete())
{
yield return null;
}
// 相机还原
var cameraSq = CameraKit.Instance.ReturnInitCamera(Duration);
while (cameraSq.active && !cameraSq.IsComplete())
{
yield return null;
}
}
}
public struct EngineToGearCommand : ITransitionCommand
{
private const float Duration = 2f;
private static readonly Vector3 CameraPos = new(-2.5f, 2.13f, -10);
public IEnumerator Execute()
{
var engineSystem = FixSystemCenter.SystemDic.Get<EngineSystem>();
var gearSystem = FixSystemCenter.SystemDic.Get<GearSystem>();
// 关闭一下引擎盖
var coverSq = engineSystem.CloseCover();
while (coverSq.active && !coverSq.IsComplete())
{
yield return null;
}
// 只需要移动一下相机就好了
var tween = CameraKit.Instance.TransCamera(CameraPos, Duration);
while (tween.active && !tween.IsComplete())
{
yield return null;
}
// 然后可以开启引擎盖
}
}
/// <summary>
/// 以两个Key为索引的Dic
/// </summary>
/// <typeparam name="T">Value类型</typeparam>
public class StateDictionary<T>
{
private readonly Dictionary<StateTransKey, T> _stateDic = new();
public T Get(FixState source, FixState target)
{
var key = new StateTransKey(source, target);
return _stateDic[key];
}
public void Add(FixState source, FixState target, T value)
{
var key = new StateTransKey(source, target);
_stateDic[key] = value;
}
public void Clear()
{
_stateDic.Clear();
}
public bool ContainsKey(FixState source, FixState target)
{
var key = new StateTransKey(source, target);
return _stateDic.ContainsKey(key);
}
public bool TryGetValue(FixState source, FixState target, out T value)
{
var key = new StateTransKey(source, target);
return _stateDic.TryGetValue(key, out value);
}
/// <summary>
/// 用于实现两个Key的Dictionary
/// </summary>
private class StateTransKey
{
private readonly FixState _sourceState;
private readonly FixState _targetState;
public StateTransKey(FixState sourceState, FixState targetState)
{
_sourceState = sourceState;
_targetState = targetState;
}
public override bool Equals(object obj)
{
// 类型不同肯定不相等
if (obj is not StateTransKey other) return false;
// 判断两个key相等
return _sourceState == other._sourceState && _targetState == other._targetState;
}
public override int GetHashCode()
{
return HashCode.Combine(_sourceState, _targetState);
}
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a69c67aba0d24b8994271ee886e11d3d
timeCreated: 1733712418