Merge branch 'develop' into 情绪分支测试
This commit is contained in:
@@ -73,6 +73,11 @@ namespace AibisDream
|
||||
_dialogueRunner.StartDialogue("Start");
|
||||
}
|
||||
|
||||
public string GetCurLocalizedTableName()
|
||||
{
|
||||
return _lineProvider.GetStringTableName();
|
||||
}
|
||||
|
||||
public void StopDialog()
|
||||
{
|
||||
_dialogueRunner.Stop();
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace AibisDream
|
||||
private void HandleLineOutput(LocalizedLine dialogueLine, Action onDialogueLineFinished)
|
||||
{
|
||||
DialogCanvasManager.Instance.ShowLine(dialogueLine.TextWithoutCharacterName.Text,
|
||||
dialogueLine.GetCharacterVo(), onDialogueLineFinished, dialogueLine.IsAutoSkipLine());
|
||||
dialogueLine.GetCharacterVo(), onDialogueLineFinished, dialogueLine.TextID, dialogueLine.IsAutoSkipLine());
|
||||
}
|
||||
|
||||
public override void RunOptions(DialogueOption[] dialogueOptions, Action<int> onOptionSelected)
|
||||
|
||||
@@ -66,5 +66,10 @@ namespace AibisDream
|
||||
// 加载
|
||||
_localizationTable = new LocalizationTable(tableName);
|
||||
}
|
||||
|
||||
public string GetStringTableName()
|
||||
{
|
||||
return _localizationTable.TableName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ public class PhysicCable : MonoBehaviour
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
physicLine = transform.GetChild(0).GetComponent<PhysicLineSegment>();
|
||||
physicLine = transform.GetComponent<PhysicLineSegment>();
|
||||
}
|
||||
|
||||
public void Init(Vector3 endPos)
|
||||
|
||||
@@ -389,7 +389,10 @@ namespace AibisDream.FixSystem
|
||||
}
|
||||
// 切换相机
|
||||
yield return CameraKit.Instance.SwitchCamera(CameraEnum.Expression);
|
||||
expressionManager.OpenView();
|
||||
yield return UIManager.Instance.GetPanel<PlayToolPanel>().FadeInAsync(0.5f);
|
||||
//expressionManager.OpenView();
|
||||
yield return CameraKit.Instance.SwitchCamera(CameraEnum.ExpressionDeep);
|
||||
yield return UIManager.Instance.GetPanel<PlayToolPanel>().FadeOutAsync(0.5f);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace AibisDream.FixSystem
|
||||
|
||||
public float rotateDuration = 0.5f;
|
||||
public float typeSpeed = 0.05f;
|
||||
public int maxTextLine;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -26,9 +27,12 @@ namespace AibisDream.FixSystem
|
||||
[SerializeField] private TMP_Text text;
|
||||
[SerializeField] private SpriteRenderer screenImage;
|
||||
private Material _imageMaterial;
|
||||
private Action _nextStep;
|
||||
|
||||
private TextGenerator _generator;
|
||||
private TextGenerationSettings _generationSettings;
|
||||
|
||||
private IUnRegister _plugOutRmv;
|
||||
private Action _nextStep;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -42,6 +46,18 @@ namespace AibisDream.FixSystem
|
||||
{
|
||||
_textScreen = transform.Find("旋转屏幕");
|
||||
_imageMaterial = screenImage.material;
|
||||
|
||||
_generator = new TextGenerator();
|
||||
_generationSettings = new TextGenerationSettings
|
||||
{
|
||||
font = text.font.sourceFontFile,
|
||||
fontSize = Mathf.RoundToInt(text.fontSize),
|
||||
lineSpacing = text.lineSpacing,
|
||||
horizontalOverflow = HorizontalWrapMode.Wrap,
|
||||
verticalOverflow = VerticalWrapMode.Truncate,
|
||||
generationExtents = new Vector2(text.rectTransform.rect.width, Mathf.Infinity),
|
||||
resizeTextForBestFit = false
|
||||
};
|
||||
}
|
||||
|
||||
private void Register()
|
||||
@@ -76,18 +92,43 @@ namespace AibisDream.FixSystem
|
||||
{
|
||||
text.text += "\n";
|
||||
}
|
||||
// 先估算新增行数
|
||||
var targetLineNum = EstimateLineNum(targetText);
|
||||
// 截断超出屏幕的部分
|
||||
var oldText = "";
|
||||
if (targetLineNum + text.textInfo.lineCount > maxTextLine)
|
||||
{
|
||||
var cutLineNum = targetLineNum + text.textInfo.lineCount - maxTextLine;
|
||||
if (cutLineNum <= text.textInfo.lineCount)
|
||||
{
|
||||
var lastCharIndex = text.textInfo.lineInfo[cutLineNum - 1].lastCharacterIndex;
|
||||
oldText = text.text[lastCharIndex..];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
oldText = text.text;
|
||||
}
|
||||
|
||||
var oldText = text.text;
|
||||
var targetLength = text.text.Length + targetText.Length;
|
||||
|
||||
var targetLength = oldText.Length + targetText.Length;
|
||||
|
||||
// 逐个字符添加
|
||||
yield return DOTween.To(() => text.text.Length, x => UpdateText(x, targetText, oldText), targetLength,
|
||||
yield return DOTween.To(() => oldText.Length, x => UpdateText(x, targetText, oldText), targetLength,
|
||||
targetText.Length * typeSpeed).WaitForCompletion();
|
||||
EnumEventSystem.Global.Send(DialogEventEnum.LineShown);
|
||||
yield return new WaitForSeconds(0.5f);
|
||||
EnumEventSystem.Global.Send(DialogEventEnum.LineEnd);
|
||||
_nextStep.Invoke();
|
||||
}
|
||||
|
||||
private int EstimateLineNum(string str)
|
||||
{
|
||||
var height = _generator.GetPreferredHeight(str, _generationSettings);
|
||||
var lineHeight = text.fontSize * 1.2f; // 简单估算行高
|
||||
|
||||
return Mathf.CeilToInt(height / lineHeight);
|
||||
}
|
||||
|
||||
private void UpdateText(int currentLength, string nextText, string oldText)
|
||||
{
|
||||
@@ -170,7 +211,7 @@ namespace AibisDream.FixSystem
|
||||
|
||||
#region 对话框功能实现
|
||||
|
||||
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, bool isAutoSkip = false)
|
||||
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, string lineId ,bool isAutoSkip = false)
|
||||
{
|
||||
ShowTitle(character.GetActorName());
|
||||
StartCoroutine(ShowText(dialogLine));
|
||||
|
||||
@@ -272,5 +272,6 @@ namespace AibisDream.Framework
|
||||
Engine,
|
||||
Gear,
|
||||
EyeDeep,
|
||||
ExpressionDeep,
|
||||
}
|
||||
}
|
||||
@@ -29,17 +29,17 @@ namespace AibisDream.Framework
|
||||
|
||||
public class LocalizationTable
|
||||
{
|
||||
private readonly string _tableName;
|
||||
public string TableName { get; }
|
||||
|
||||
private StringTable _stringTable;
|
||||
|
||||
public LocalizationTable(string tableName)
|
||||
{
|
||||
_tableName = tableName;
|
||||
_stringTable = LocalizationSettings.StringDatabase.GetTable(_tableName);
|
||||
TableName = tableName;
|
||||
_stringTable = LocalizationSettings.StringDatabase.GetTable(TableName);
|
||||
LocalizationSettings.SelectedLocaleChanged += OnLocaleChanged;
|
||||
|
||||
Debug.Log($"表格{_tableName}已加载");
|
||||
Debug.Log($"表格{TableName}已加载");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
@@ -50,7 +50,7 @@ namespace AibisDream.Framework
|
||||
|
||||
private void OnLocaleChanged(Locale locale)
|
||||
{
|
||||
_stringTable = LocalizationSettings.StringDatabase.GetTable(_tableName);
|
||||
_stringTable = LocalizationSettings.StringDatabase.GetTable(TableName);
|
||||
}
|
||||
|
||||
public StringTableEntry this[string key] => _stringTable[key];
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace AibisDream.Framework
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!sprite) return "";
|
||||
|
||||
|
||||
// 先读Psd的路径
|
||||
string psdPath = AssetDatabase.GetAssetPath(sprite);
|
||||
var psdResPath = GetResourcePath(psdPath);
|
||||
@@ -28,13 +28,12 @@ namespace AibisDream.Framework
|
||||
|
||||
// 提取文件名(不包括扩展名)
|
||||
var purePath = psdResPath.Substring(0, lastDotIndex);
|
||||
|
||||
|
||||
// 添加后缀
|
||||
return purePath + "/" + sprite.name;
|
||||
#else
|
||||
return null;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
private static string GetResourcePath(string absolutePath)
|
||||
@@ -42,15 +41,7 @@ namespace AibisDream.Framework
|
||||
const string resourcesFolderName = "Resources/";
|
||||
int index = absolutePath.IndexOf(resourcesFolderName, StringComparison.Ordinal);
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
// 获取 "Resources/" 之后的部分
|
||||
return absolutePath.Substring(index + resourcesFolderName.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
return absolutePath;
|
||||
}
|
||||
return index >= 0 ? absolutePath[(index + resourcesFolderName.Length)..] : absolutePath;
|
||||
}
|
||||
|
||||
public static Sprite LoadSpriteFromPsd(string path)
|
||||
@@ -58,7 +49,7 @@ namespace AibisDream.Framework
|
||||
int lastIndex = path.LastIndexOf('/');
|
||||
string spriteName = path.Substring(lastIndex + 1);
|
||||
string resPath = path.Substring(0, lastIndex);
|
||||
|
||||
|
||||
// 加载
|
||||
var sprites = Resources.LoadAll<Sprite>(resPath);
|
||||
|
||||
@@ -72,39 +63,14 @@ namespace AibisDream.Framework
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static T LoadAddressableSync<T>(string key)
|
||||
|
||||
public static T LoadAssetSync<T>(string key) where T : UnityEngine.Object
|
||||
{
|
||||
T result = default;
|
||||
var operation = Addressables.LoadAssetAsync<T>(key);
|
||||
|
||||
// 运行协程等待加载完成
|
||||
GameManager.Instance.StartCoroutine(LoadCoroutine(operation, loadedObject => result = loadedObject));
|
||||
|
||||
// 等待协程完成(阻塞主线程)
|
||||
while (!operation.IsDone)
|
||||
{
|
||||
// 主动让出一帧
|
||||
System.Threading.Thread.Sleep(1);
|
||||
}
|
||||
operation.WaitForCompletion();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static IEnumerator LoadCoroutine<T>(AsyncOperationHandle<T> operation, Action<T> onComplete)
|
||||
{
|
||||
yield return operation;
|
||||
|
||||
if (operation.Status == AsyncOperationStatus.Succeeded)
|
||||
{
|
||||
onComplete?.Invoke(operation.Result);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Failed to load addressable");
|
||||
}
|
||||
|
||||
Addressables.Release(operation);
|
||||
return operation.Result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
using UnityEngine;
|
||||
using DG.Tweening;
|
||||
using System;
|
||||
|
||||
namespace AibisDream
|
||||
{
|
||||
[RequireComponent(typeof(LineRenderer))]
|
||||
public class ExpressionCable : MonoBehaviour
|
||||
{
|
||||
private Transform _start;
|
||||
private Transform _end;
|
||||
private LineRenderer _lineRenderer;
|
||||
private Vector3[] _points;
|
||||
private ExpressionCableSystem _cableSystem;
|
||||
|
||||
[SerializeField]
|
||||
private CableConfig config = CableConfig.GeneDefaultConfig();
|
||||
|
||||
public void Initialize(Transform start, Transform end)
|
||||
{
|
||||
_start = start;
|
||||
_end = end;
|
||||
_lineRenderer = GetComponent<LineRenderer>();
|
||||
_lineRenderer.positionCount = config.resolution;
|
||||
InitPoints();
|
||||
}
|
||||
|
||||
private void InitPoints()
|
||||
{
|
||||
_points = new Vector3[config.resolution];
|
||||
for (int i = 0; i < config.resolution; i++)
|
||||
{
|
||||
float t = i / (float)(config.resolution - 1);
|
||||
_points[i] = Vector3.Lerp(_start.position, _end.position, t);
|
||||
}
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
DrawLine();
|
||||
}
|
||||
|
||||
void DrawLine()
|
||||
{
|
||||
var points = UpdateRope();
|
||||
for (int i = 0; i < config.resolution; i++)
|
||||
{
|
||||
_lineRenderer.SetPosition(i, points[i] + Vector3.forward * -.3f);
|
||||
}
|
||||
}
|
||||
|
||||
Vector3[] UpdateRope()
|
||||
{
|
||||
float t = Mathf.InverseLerp(config.dstMin, config.dstMax, (_start.position - _end.position).magnitude);
|
||||
float F = Mathf.Lerp(config.forceMin, config.forceMax, t);
|
||||
_points[0] = _start.position;
|
||||
_points[^1] = _end.position;
|
||||
for (int ik = 0; ik < config.k; ik++)
|
||||
{
|
||||
for (int i = 1; i < _points.Length - 1; i++)
|
||||
{
|
||||
Vector3 offsetPrev = _points[i - 1] - _points[i];
|
||||
Vector3 offsetNext = _points[i + 1] - _points[i];
|
||||
Vector3 velocity = offsetPrev.normalized * (offsetPrev.magnitude * F) +
|
||||
offsetNext.normalized * (offsetNext.magnitude * F);
|
||||
_points[i] += velocity * Time.deltaTime / config.k;
|
||||
}
|
||||
|
||||
for (int i = 1; i < _points.Length - 1; i++)
|
||||
{
|
||||
_points[i] += Vector3.down * (9.8f * Time.deltaTime) / config.k;
|
||||
}
|
||||
}
|
||||
|
||||
return _points;
|
||||
}
|
||||
|
||||
public void SetEndPos(Transform endPos)
|
||||
{
|
||||
_end = endPos;
|
||||
}
|
||||
|
||||
public void UpdateEndPosition(Vector3 position)
|
||||
{
|
||||
if (_end != null)
|
||||
{
|
||||
_end.position = position;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct CableConfig
|
||||
{
|
||||
public int resolution;
|
||||
public float dstMin;
|
||||
public float dstMax;
|
||||
public float forceMin;
|
||||
public float forceMax;
|
||||
public int k;
|
||||
|
||||
public static CableConfig GeneDefaultConfig()
|
||||
{
|
||||
return new CableConfig
|
||||
{
|
||||
resolution = 10,
|
||||
dstMin = 0.1f,
|
||||
dstMax = 1.0f,
|
||||
forceMin = 0.1f,
|
||||
forceMax = 150f,
|
||||
k = 10
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9c72154e06027eb4698fc7da159c2d6e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,83 @@
|
||||
using UnityEngine;
|
||||
using AibisDream.FixSystem;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AibisDream
|
||||
{
|
||||
public class ExpressionCableSystem : MonoBehaviour
|
||||
{
|
||||
[Header("电源子模块")]
|
||||
public ExpressionPowerSource powerSource;
|
||||
|
||||
private ExpressionManager _expressionManager;
|
||||
private ExpressionSubSystem[] _expressionSubSystems;
|
||||
private const float MAX_DISTANCE = 1f; // 最大检测距离
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// 自动查找所有子物体中的表达子模块
|
||||
_expressionSubSystems = GetComponentsInChildren<ExpressionSubSystem>();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_expressionManager = transform.parent.GetComponent<ExpressionManager>();
|
||||
InitializeSystem();
|
||||
}
|
||||
|
||||
private void InitializeSystem()
|
||||
{
|
||||
// 初始化表达子模块
|
||||
foreach (var subSystem in _expressionSubSystems)
|
||||
{
|
||||
subSystem.Initialize(this);
|
||||
}
|
||||
}
|
||||
|
||||
// 当插头插入插槽时调用
|
||||
public void OnPlugInserted(int subSystemIndex, int socketIndex)
|
||||
{
|
||||
_expressionManager.AdjustValue(subSystemIndex, 1);
|
||||
}
|
||||
|
||||
// 当插头拔出插槽时调用
|
||||
public void OnPlugRemoved(int subSystemIndex, int socketIndex)
|
||||
{
|
||||
_expressionManager.AdjustValue(subSystemIndex, -1);
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
powerSource.Reset();
|
||||
foreach (var subSystem in _expressionSubSystems)
|
||||
{
|
||||
subSystem.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryFindClosestSocket(Vector3 sourcePos, out ISocket targetSocket)
|
||||
{
|
||||
targetSocket = null;
|
||||
float minDistance = MAX_DISTANCE;
|
||||
|
||||
// 遍历所有子模块
|
||||
foreach (var subSystem in _expressionSubSystems)
|
||||
{
|
||||
// 遍历子模块中的所有插槽
|
||||
foreach (var socket in subSystem.GetSockets())
|
||||
{
|
||||
if (!socket.IsAvailable()) continue;
|
||||
|
||||
float distance = Vector3.Distance(sourcePos, socket.GetSocketPos());
|
||||
if (distance < minDistance)
|
||||
{
|
||||
minDistance = distance;
|
||||
targetSocket = socket;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return targetSocket != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6b20aec8808a25c4b9607bbe72858b7a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -14,7 +14,6 @@ namespace AibisDream
|
||||
public class ExpressionManager : MonoBehaviour
|
||||
{
|
||||
public GameObject expressView;
|
||||
public Slider[] sliders; // A, P, R, E, T
|
||||
public TMP_Text totalPointsText;
|
||||
public int totalPoints = 10;
|
||||
|
||||
@@ -31,35 +30,24 @@ namespace AibisDream
|
||||
private DriverDatabase db = new DriverDatabase();
|
||||
private List<GameObject> currentResultButtons = new List<GameObject>();
|
||||
|
||||
|
||||
void Start()
|
||||
{
|
||||
CloseView();
|
||||
//CloseView();
|
||||
FixSystemCenter.SystemDic.Register(this);
|
||||
|
||||
var virtualCam = transform.Find("Expression Camera").GetComponent<ICinemachineCamera>();
|
||||
var virtualCam2 = transform.Find("Expression Deep Camera").GetComponent<ICinemachineCamera>();
|
||||
CameraKit.Instance.RegisterCamera(CameraEnum.Expression, virtualCam);
|
||||
CameraKit.Instance.RegisterCamera(CameraEnum.ExpressionDeep, virtualCam2);
|
||||
|
||||
db.LoadFromCSV(Path.Combine(Application.streamingAssetsPath, "drivers.csv"));
|
||||
|
||||
for (int i = 0; i < sliders.Length; i++)
|
||||
{
|
||||
int index = i;
|
||||
Transform plus = sliders[i].transform.Find("Plus");
|
||||
if (plus != null && plus.TryGetComponent(out Button plusBtn))
|
||||
plusBtn.onClick.AddListener(() => AdjustValue(index, 1));
|
||||
Transform minus = sliders[i].transform.Find("Minus");
|
||||
if (minus != null && minus.TryGetComponent(out Button minusBtn))
|
||||
minusBtn.onClick.AddListener(() => AdjustValue(index, -1));
|
||||
}
|
||||
|
||||
matchButton.onClick.AddListener(MatchDriver);
|
||||
applyAndTestButton.onClick.AddListener(ApplyAndTestDriver);
|
||||
|
||||
UpdateUI();
|
||||
}
|
||||
|
||||
|
||||
public void OpenView()
|
||||
{
|
||||
expressView.SetActive(true);
|
||||
@@ -70,7 +58,7 @@ namespace AibisDream
|
||||
expressView.SetActive(false);
|
||||
}
|
||||
|
||||
void AdjustValue(int index, int delta)
|
||||
public void AdjustValue(int index, int delta)
|
||||
{
|
||||
if (delta > 0 && totalPoints <= 0) return;
|
||||
if (delta < 0 && valuesCurrent[index] <= 0) return;
|
||||
@@ -84,13 +72,6 @@ namespace AibisDream
|
||||
|
||||
void UpdateUI()
|
||||
{
|
||||
for (int i = 0; i < sliders.Length; i++)
|
||||
{
|
||||
sliders[i].value = valuesCurrent[i];
|
||||
Transform valueTextTransform = sliders[i].transform.Find("Value");
|
||||
if (valueTextTransform != null && valueTextTransform.TryGetComponent(out TMP_Text valueText))
|
||||
valueText.text = valuesCurrent[i].ToString();
|
||||
}
|
||||
totalPointsText.text = $"剩余点数: {totalPoints}";
|
||||
}
|
||||
|
||||
@@ -132,7 +113,6 @@ namespace AibisDream
|
||||
currentDriver = driver;
|
||||
driverSlotText.text = $"Driver: {driver.Name}";
|
||||
logOutput.text = $"已选中驱动:{driver.Name},请点击应用并测试以运行。";
|
||||
// 保留面板,不关闭 matchResultsPanel
|
||||
}
|
||||
|
||||
void ApplyAndTestDriver()
|
||||
@@ -166,4 +146,4 @@ namespace AibisDream
|
||||
currentUser=userName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
using UnityEngine;
|
||||
using AibisDream.FixSystem;
|
||||
using UnityEngine.EventSystems;
|
||||
using AibisDream.Framework;
|
||||
using AibisDream.Kit;
|
||||
using AibisDream.Utility;
|
||||
using DG.Tweening;
|
||||
|
||||
namespace AibisDream
|
||||
{
|
||||
[RequireComponent(typeof(EventTriggerEx))]
|
||||
public class ExpressionPlug : MonoBehaviour, IInteraction
|
||||
{
|
||||
private static readonly int ShineFade = Shader.PropertyToID("_ShineFade");
|
||||
|
||||
private Vector3 _startPos;
|
||||
private readonly Vector3 _pickupOffset = new(0, 0, 0);
|
||||
private readonly Quaternion _pickupRotationOffset = Quaternion.Euler(0, 0, 150);
|
||||
private readonly Quaternion _initRotation = Quaternion.Euler(0, 0, 180);
|
||||
|
||||
private ExpressionCableSystem _cableSystem;
|
||||
private SpriteRenderer _sprite;
|
||||
private Transform _plugRootPos;
|
||||
private EventTriggerEx _trigger;
|
||||
private ISocket _currentSocket;
|
||||
private ExpressionCable _cable; // 对应的线缆
|
||||
|
||||
private bool _isDragging;
|
||||
private bool _isPhysicCableActive;
|
||||
|
||||
[Header("调试设置")]
|
||||
public float detectRadius = 1f; // 增加检测半径
|
||||
public LayerMask socketLayer; // 设置插槽层级
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
InitComponentRef();
|
||||
EventRegister();
|
||||
_startPos = transform.position;
|
||||
}
|
||||
|
||||
private void InitComponentRef()
|
||||
{
|
||||
_cableSystem = GetComponentInParent<ExpressionCableSystem>();
|
||||
_sprite = GetComponent<SpriteRenderer>();
|
||||
_plugRootPos = transform.GetChild(0);
|
||||
_trigger = GetComponent<EventTriggerEx>();
|
||||
}
|
||||
|
||||
private void EventRegister()
|
||||
{
|
||||
_trigger.Register(EventTriggerType.Drag, OnDrag);
|
||||
_trigger.Register(EventTriggerType.PointerDown, OnPointerDown);
|
||||
_trigger.Register(EventTriggerType.PointerUp, OnPointerUp);
|
||||
}
|
||||
|
||||
private void OnDrag(BaseEventData eventData)
|
||||
{
|
||||
if (!IsAvailable) return;
|
||||
if (!_isDragging) return;
|
||||
|
||||
if (eventData is PointerEventData pointerData)
|
||||
{
|
||||
transform.position = CommonUtil.GetMouseWorldPos(pointerData.position, transform);
|
||||
UpdateCable();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPointerDown(BaseEventData eventData)
|
||||
{
|
||||
if (!IsAvailable) return;
|
||||
|
||||
_isDragging = true;
|
||||
|
||||
if (_currentSocket != null)
|
||||
{
|
||||
PullUpSocket();
|
||||
}
|
||||
|
||||
AdjustPlugPos();
|
||||
_sprite.enabled = true;
|
||||
}
|
||||
|
||||
private void OnPointerUp(BaseEventData eventData)
|
||||
{
|
||||
_isDragging = false;
|
||||
|
||||
// 寻找最近的可用插槽
|
||||
if (_cableSystem.TryFindClosestSocket(transform.position, out var socket))
|
||||
{
|
||||
InsertSocket(socket);
|
||||
}
|
||||
else
|
||||
{
|
||||
ReturnToStartPosition();
|
||||
}
|
||||
}
|
||||
|
||||
private void InsertSocket(ISocket targetSocket)
|
||||
{
|
||||
// 修改插头位置
|
||||
transform.position = targetSocket.GetSocketPos();
|
||||
_cable.SetEndPos(transform);
|
||||
|
||||
// 处理插槽插入
|
||||
_currentSocket = targetSocket;
|
||||
targetSocket.PlugIn();
|
||||
_sprite.enabled = false;
|
||||
}
|
||||
|
||||
public void PullUpSocket()
|
||||
{
|
||||
// 修改线缆终点
|
||||
_cable.SetEndPos(_plugRootPos);
|
||||
|
||||
// 处理插槽拔出
|
||||
_currentSocket?.PlugOut();
|
||||
_sprite.enabled = true;
|
||||
_currentSocket = null;
|
||||
}
|
||||
|
||||
public void ReturnToStartPosition()
|
||||
{
|
||||
transform.DOMove(_startPos, 0.1f);
|
||||
transform.rotation = _initRotation;
|
||||
_cable.SetEndPos(_plugRootPos);
|
||||
}
|
||||
|
||||
private void AdjustPlugPos()
|
||||
{
|
||||
transform.position += _pickupOffset;
|
||||
transform.rotation = _pickupRotationOffset;
|
||||
}
|
||||
|
||||
public void SetCable(ExpressionCable cable)
|
||||
{
|
||||
_cable = cable;
|
||||
}
|
||||
|
||||
private void UpdateCable()
|
||||
{
|
||||
if (_cable != null)
|
||||
{
|
||||
_cable.UpdateEndPosition(_plugRootPos.position);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsActive => true;
|
||||
public bool IsAvailable => true;
|
||||
|
||||
public GameObject GetGameObject()
|
||||
{
|
||||
return gameObject;
|
||||
}
|
||||
|
||||
// 用于调试
|
||||
private void OnDrawGizmosSelected()
|
||||
{
|
||||
Gizmos.color = Color.yellow;
|
||||
Gizmos.DrawWireSphere(transform.position, detectRadius);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3e7a3d02c9c5f764fa1bc93f109a3447
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,45 @@
|
||||
using UnityEngine;
|
||||
using AibisDream.FixSystem;
|
||||
|
||||
namespace AibisDream
|
||||
{
|
||||
public class ExpressionPowerSource : MonoBehaviour
|
||||
{
|
||||
[Header("插头设置")]
|
||||
public Transform[] plugGroups; // 在编辑器中直接拖拽设置插头组
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// 初始化每个插头组
|
||||
foreach (var group in plugGroups)
|
||||
{
|
||||
var plug = group.GetComponentInChildren<ExpressionPlug>();
|
||||
var cable = group.GetComponentInChildren<ExpressionCable>();
|
||||
var rootPos = group.Find("CableRoot");
|
||||
|
||||
if (plug != null && cable != null && rootPos != null)
|
||||
{
|
||||
cable.Initialize(rootPos, plug.transform.GetChild(0));
|
||||
plug.SetCable(cable);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"插头组 {group.name} 缺少必要组件");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
// 重置所有插头
|
||||
foreach (var group in plugGroups)
|
||||
{
|
||||
var plug = group.GetComponentInChildren<ExpressionPlug>();
|
||||
if (plug != null)
|
||||
{
|
||||
plug.ReturnToStartPosition();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fda4de3e06bfb5044ac87fd4e5c9f5e0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,48 @@
|
||||
using UnityEngine;
|
||||
using AibisDream.FixSystem;
|
||||
|
||||
namespace AibisDream
|
||||
{
|
||||
public class ExpressionSocket : MonoBehaviour, ISocket
|
||||
{
|
||||
private int _subSystemIndex; // 所属表达子模块的索引
|
||||
private int _socketIndex; // 插槽在子模块中的索引
|
||||
private bool _isOccupied;
|
||||
private ExpressionCableSystem _cableSystem;
|
||||
|
||||
public void Initialize(int subSystemIndex, int socketIndex)
|
||||
{
|
||||
_subSystemIndex = subSystemIndex;
|
||||
_socketIndex = socketIndex;
|
||||
_cableSystem = GetComponentInParent<ExpressionCableSystem>();
|
||||
}
|
||||
|
||||
public void PlugIn()
|
||||
{
|
||||
if (!_isOccupied)
|
||||
{
|
||||
_isOccupied = true;
|
||||
_cableSystem.OnPlugInserted(_subSystemIndex, _socketIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public void PlugOut()
|
||||
{
|
||||
if (_isOccupied)
|
||||
{
|
||||
_isOccupied = false;
|
||||
_cableSystem.OnPlugRemoved(_subSystemIndex, _socketIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 GetSocketPos()
|
||||
{
|
||||
return transform.position;
|
||||
}
|
||||
|
||||
public bool IsAvailable()
|
||||
{
|
||||
return !_isOccupied;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 400d314e97bc045419d11ac25d78f61d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,47 @@
|
||||
using UnityEngine;
|
||||
using AibisDream.FixSystem;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AibisDream
|
||||
{
|
||||
public class ExpressionSubSystem : MonoBehaviour
|
||||
{
|
||||
[Header("子模块设置")]
|
||||
public string expressionName; // 表达名称
|
||||
public int subSystemIndex; // 子模块索引
|
||||
|
||||
private ExpressionCableSystem _cableSystem;
|
||||
private ExpressionSocket[] _sockets;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// 自动查找所有子物体中的插槽
|
||||
_sockets = GetComponentsInChildren<ExpressionSocket>();
|
||||
}
|
||||
|
||||
public void Initialize(ExpressionCableSystem cableSystem)
|
||||
{
|
||||
_cableSystem = cableSystem;
|
||||
|
||||
// 初始化所有插槽
|
||||
for (int i = 0; i < _sockets.Length; i++)
|
||||
{
|
||||
_sockets[i].Initialize(subSystemIndex, i);
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
// 重置所有插槽状态
|
||||
foreach (var socket in _sockets)
|
||||
{
|
||||
socket.PlugOut();
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<ExpressionSocket> GetSockets()
|
||||
{
|
||||
return _sockets;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a589bca4a2e605d4caf6b56c5d86610f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -36,7 +36,7 @@ public class TaskManager : MonoBehaviour
|
||||
}
|
||||
|
||||
|
||||
[YarnCommand("task_moveIn")]
|
||||
// [YarnCommand("task_moveIn")]
|
||||
public void Task_moveIn()
|
||||
{
|
||||
AudioManager.Instance.PlaySfx("event:/Scriptal/taskmanager");
|
||||
@@ -44,7 +44,7 @@ public class TaskManager : MonoBehaviour
|
||||
}
|
||||
|
||||
|
||||
[YarnCommand("task_moveOut")]
|
||||
// [YarnCommand("task_moveOut")]
|
||||
public void Task_moveOut()
|
||||
{
|
||||
AudioManager.Instance.PlaySfx("event:/Scriptal/taskmanager");
|
||||
@@ -81,7 +81,7 @@ public class TaskManager : MonoBehaviour
|
||||
UpdateTaskUI();
|
||||
}
|
||||
|
||||
[YarnCommand("complete_task")]
|
||||
// [YarnCommand("complete_task")]
|
||||
public void CompleteTask(string taskText)
|
||||
{
|
||||
TaskEntry task = FindTaskByText(tasks, taskText);
|
||||
@@ -96,7 +96,7 @@ public class TaskManager : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
[YarnCommand("clear_tasks")]
|
||||
// [YarnCommand("clear_tasks")]
|
||||
public void ClearTasks()
|
||||
{
|
||||
tasks.Clear(); // 清空任务列表
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace AibisDream
|
||||
_ => HideDialog());
|
||||
}
|
||||
|
||||
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, bool isAutoSkip = false)
|
||||
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, string lineId, bool isAutoSkip = false)
|
||||
{
|
||||
Debug.Log("CenterOption只显示选项");
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace AibisDream
|
||||
});
|
||||
}
|
||||
|
||||
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, bool isAutoSkip = false)
|
||||
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, string lineId, bool isAutoSkip = false)
|
||||
{
|
||||
// 把原有对话清掉
|
||||
ClearBox();
|
||||
|
||||
@@ -85,8 +85,9 @@ namespace AibisDream
|
||||
/// <param name="dialogLine">对话内容</param>
|
||||
/// <param name="character">角色内容</param>
|
||||
/// <param name="nextStep">下一步</param>
|
||||
/// <param name="lineId">行号</param>
|
||||
/// <param name="isAutoSkip">是否自动跳过,默认为false</param>
|
||||
public virtual void ShowLine(string dialogLine, CharacterVo character, Action nextStep, bool isAutoSkip = false)
|
||||
public virtual void ShowLine(string dialogLine, CharacterVo character, Action nextStep, string lineId, bool isAutoSkip = false)
|
||||
{
|
||||
gameObject.SetActive(true);
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace AibisDream
|
||||
_dialogViews.ForEach(item => item.HideDialog());
|
||||
}
|
||||
|
||||
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, bool isAutoSkip = false)
|
||||
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, string lineId, bool isAutoSkip = false)
|
||||
{
|
||||
gameObject.SetActive(true);
|
||||
// 根据角色信息气泡
|
||||
@@ -46,7 +46,7 @@ namespace AibisDream
|
||||
// 处理其他泡泡
|
||||
ProcessOtherBox();
|
||||
// 显示对话
|
||||
_currentView.ShowLine(dialogLine, character, nextStep, isAutoSkip);
|
||||
_currentView.ShowLine(dialogLine, character, nextStep, lineId, isAutoSkip);
|
||||
}
|
||||
|
||||
public void ShowOptions(DialogOption[] options)
|
||||
|
||||
@@ -22,7 +22,10 @@ namespace AibisDream
|
||||
public override void OnSingletonInit()
|
||||
{
|
||||
InitEvent();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// 默认对话框直接加载
|
||||
var box = transform.Find("Dialog Box").GetComponent<IDialogView>();
|
||||
RegisterDialogView(DialogViewType.OldBox, box);
|
||||
@@ -30,10 +33,8 @@ namespace AibisDream
|
||||
RegisterDialogView(DialogViewType.CenterText, centerText);
|
||||
var centerOption = transform.Find("Center Option").GetComponent<IDialogView>();
|
||||
RegisterDialogView(DialogViewType.CenterOption, centerOption);
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
RegisterDialogView(DialogViewType.Task, UIManager.Instance.GetPanel<TaskPanel>());
|
||||
|
||||
_curView = _dialogViewDict[DialogViewType.OldBox];
|
||||
}
|
||||
|
||||
@@ -93,7 +94,7 @@ namespace AibisDream
|
||||
|
||||
#region 对话框接口
|
||||
|
||||
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, bool isAutoSkip = false)
|
||||
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, string lineId, bool isAutoSkip = false)
|
||||
{
|
||||
// 根据DialogViewType确定在哪个对话框显示
|
||||
if (character.dialogViewType == DialogViewType.Default)
|
||||
@@ -105,7 +106,7 @@ namespace AibisDream
|
||||
|
||||
_lastShowView = _curView;
|
||||
// 没有指定对话框,就用当前激活的
|
||||
_curView.ShowLine(dialogLine, character, nextStep, isAutoSkip);
|
||||
_curView.ShowLine(dialogLine, character, nextStep, lineId, isAutoSkip);
|
||||
}
|
||||
else if (_dialogViewDict.TryGetValue(character.dialogViewType, out var view))
|
||||
{
|
||||
@@ -116,7 +117,7 @@ namespace AibisDream
|
||||
|
||||
_lastShowView = view;
|
||||
// 对于指定了对话框的,就在指定对话框显示
|
||||
view.ShowLine(dialogLine, character, nextStep, isAutoSkip);
|
||||
view.ShowLine(dialogLine, character, nextStep, lineId, isAutoSkip);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -208,6 +209,7 @@ namespace AibisDream
|
||||
OldBox,
|
||||
Screen,
|
||||
CenterText,
|
||||
CenterOption
|
||||
CenterOption,
|
||||
Task
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ namespace AibisDream
|
||||
{
|
||||
public interface IDialogView
|
||||
{
|
||||
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, bool isAutoSkip = false);
|
||||
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, string lineId ,bool isAutoSkip = false);
|
||||
|
||||
public void ShowOptions(DialogOption[] dialogueOptions);
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Localization.Components;
|
||||
|
||||
namespace AibisDream
|
||||
{
|
||||
[RequireComponent(typeof(TMP_Text))]
|
||||
[RequireComponent(typeof(LocalizeStringEvent))]
|
||||
public class LocalizedText : MonoBehaviour
|
||||
{
|
||||
private TMP_Text _text;
|
||||
private LocalizeStringEvent _localizeEvent;
|
||||
|
||||
private void OnUpdateString(string text)
|
||||
{
|
||||
var textArr = text.Split(":");
|
||||
_text.text = textArr.Length > 1 ? textArr[1].Trim() : text;
|
||||
}
|
||||
|
||||
public void SetLocalizedText(string table, string entry)
|
||||
{
|
||||
_text = GetComponent<TMP_Text>();
|
||||
_localizeEvent = GetComponent<LocalizeStringEvent>();
|
||||
|
||||
_localizeEvent.OnUpdateString.AddListener(OnUpdateString);
|
||||
|
||||
_localizeEvent.SetTable(table);
|
||||
_localizeEvent.SetEntry(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4c9c71a7e9c9455d955ff20b5db823a1
|
||||
timeCreated: 1746702086
|
||||
@@ -54,7 +54,7 @@ namespace AibisDream
|
||||
|
||||
#endregion
|
||||
|
||||
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, bool isAutoSkip = false)
|
||||
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, string lineId, bool isAutoSkip = false)
|
||||
{
|
||||
gameObject.SetActive(true);
|
||||
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using AibisDream.Framework;
|
||||
using AibisDream.Kit;
|
||||
using AibisDream.Utility;
|
||||
using DG.Tweening;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using Yarn.Unity;
|
||||
|
||||
namespace AibisDream
|
||||
{
|
||||
public class TaskPanel : MonoBehaviour, IUIPanel, IDialogView
|
||||
{
|
||||
private RectTransform _rectTransform;
|
||||
private Transform _taskListParent;
|
||||
private GameObject _taskItemPrefab;
|
||||
|
||||
private GameObject TaskItemPrefab
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_taskItemPrefab == null)
|
||||
{
|
||||
_taskItemPrefab = ResourceKit.LoadAssetSync<GameObject>(ConstRef.TaskItemName);
|
||||
}
|
||||
|
||||
return _taskItemPrefab;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Dictionary<string, LocalizedText> _taskDict = new();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_rectTransform = GetComponent<RectTransform>();
|
||||
_taskListParent = transform.Find("Record");
|
||||
EnumEventSystem.Global.Register(GameLoopEnum.GameQuit, ClearTasks);
|
||||
EnumEventSystem.Global.Register(EventEnum.NextYarn, ClearTasks);
|
||||
}
|
||||
|
||||
#region 诊疗单功能
|
||||
|
||||
public void CompleteTask(string lineId)
|
||||
{
|
||||
if (_taskDict.TryGetValue(lineId, out var taskItem))
|
||||
{
|
||||
var taskText = taskItem.GetComponent<TMP_Text>();
|
||||
taskText.fontStyle |= FontStyles.Strikethrough;
|
||||
taskText.color = Color.gray;
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearTasks()
|
||||
{
|
||||
foreach (var task in _taskDict)
|
||||
{
|
||||
Destroy(task.Value.gameObject);
|
||||
}
|
||||
_taskDict.Clear();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 对话框功能实现
|
||||
|
||||
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, string lineId, bool isAutoSkip = false)
|
||||
{
|
||||
var taskItem = Instantiate(TaskItemPrefab, _taskListParent);
|
||||
// 设置本地化数据
|
||||
var localize = taskItem.GetComponent<LocalizedText>();
|
||||
localize.SetLocalizedText(DialogController.Instance.GetCurLocalizedTableName(), lineId);
|
||||
_taskDict[lineId] = localize;
|
||||
|
||||
EnumEventSystem.Global.Send(DialogEventEnum.LineShown);
|
||||
EnumEventSystem.Global.Send(DialogEventEnum.LineEnd);
|
||||
nextStep.Invoke();
|
||||
}
|
||||
|
||||
public void ShowOptions(DialogOption[] dialogueOptions)
|
||||
{
|
||||
Debug.Log("Task 面板不能显示选项");
|
||||
}
|
||||
|
||||
public void HideDialog()
|
||||
{
|
||||
// HideDialog应该由其他函数控制
|
||||
}
|
||||
|
||||
public bool TrySkipLine(bool isForceSkip = false)
|
||||
{
|
||||
// 这里不能跳过对话
|
||||
return true;
|
||||
}
|
||||
|
||||
public void NextStep()
|
||||
{
|
||||
// 这里不能手动跳到下一行
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 打开和关闭
|
||||
|
||||
public bool IsOpen { get; private set;}
|
||||
|
||||
public void Show()
|
||||
{
|
||||
gameObject.SetActive(true);
|
||||
AudioManager.Instance.PlaySfx("event:/Scriptal/taskmanager");
|
||||
// 下移
|
||||
_rectTransform.DOAnchorPosY(-350, 1f).OnComplete(() =>
|
||||
{
|
||||
IsOpen = true;
|
||||
});
|
||||
}
|
||||
|
||||
public void Hide()
|
||||
{
|
||||
// 上移
|
||||
AudioManager.Instance.PlaySfx("event:/Scriptal/taskmanager");
|
||||
_rectTransform.DOAnchorPosY(0, 1f).OnComplete(() =>
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
IsOpen = false;
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public static class TaskYarnCommand
|
||||
{
|
||||
private static TaskPanel TaskPanel => UIManager.Instance.GetPanel<TaskPanel>();
|
||||
|
||||
[YarnCommand("complete_task")]
|
||||
public static void CompleteTask(string lineId)
|
||||
{
|
||||
TaskPanel.CompleteTask(lineId);
|
||||
}
|
||||
|
||||
[YarnCommand("clear_tasks")]
|
||||
public static void ClearTasks()
|
||||
{
|
||||
TaskPanel.ClearTasks();
|
||||
}
|
||||
|
||||
[YarnCommand("task_moveIn")]
|
||||
public static IEnumerator ShowTask()
|
||||
{
|
||||
UIManager.Instance.ShowPanel<TaskPanel>();
|
||||
yield return new WaitForSeconds(1);
|
||||
}
|
||||
|
||||
[YarnCommand("task_moveOut")]
|
||||
public static IEnumerator HideTask()
|
||||
{
|
||||
UIManager.Instance.HidePanel<TaskPanel>();
|
||||
yield return new WaitForSeconds(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 433304b79d7ad5344b1a0c3932187de2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -95,8 +95,14 @@ namespace AibisDream
|
||||
}
|
||||
|
||||
public T GetPanel<T>() where T : class, IUIPanel
|
||||
{
|
||||
return _panelPool.TryGetValue(typeof(T), out var ui) ? ui as T : null;
|
||||
{
|
||||
if (_panelPool.TryGetValue(typeof(T), out var panel))
|
||||
{
|
||||
return panel as T;
|
||||
}
|
||||
|
||||
Debug.Log($"没有找到{typeof(T)}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -193,7 +193,20 @@ namespace AibisDream.Utility
|
||||
while (currentIndex < line.Length)
|
||||
{
|
||||
var length = Math.Min(maxCharsPerLine, line.Length - currentIndex);
|
||||
result.Append(line.Substring(currentIndex, length));
|
||||
var substring = line.Substring(currentIndex, length);
|
||||
|
||||
// 检查是否需要调整长度以避免在单词中间断开
|
||||
if (currentIndex + length < line.Length && !char.IsWhiteSpace(line[currentIndex + length]) && !char.IsPunctuation(line[currentIndex + length]))
|
||||
{
|
||||
var lastSpace = substring.LastIndexOf(' ');
|
||||
if (lastSpace > 0)
|
||||
{
|
||||
length = lastSpace;
|
||||
substring = line.Substring(currentIndex, length);
|
||||
}
|
||||
}
|
||||
|
||||
result.Append(substring.TrimStart());
|
||||
currentIndex += length;
|
||||
|
||||
if (currentIndex < line.Length)
|
||||
|
||||
@@ -19,5 +19,7 @@ namespace AibisDream.Utility
|
||||
public const string UITextTable = "UIText";
|
||||
|
||||
#endregion
|
||||
|
||||
public const string TaskItemName = "Task Item";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user