屏幕问题

This commit is contained in:
2025-02-13 20:53:28 +08:00
parent 94e01a9baa
commit 496f538b9f
41 changed files with 507 additions and 265 deletions
@@ -12,4 +12,4 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 9e2a5ebb2c224910b14d053825d88b4a, type: 3}
m_Name: InstallationData
m_EditorClassIdentifier:
latestVersion: 2.1.1
latestVersion: 2.3.0
@@ -381,7 +381,7 @@ MonoBehaviour:
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 61.6
m_fontSize: 45.3
m_fontSizeBase: 53.61
m_fontWeight: 400
m_enableAutoSizing: 1
@@ -508,9 +508,12 @@ MonoBehaviour:
useTypeWriter: 1
startTypewriterMode: 3
hideAppearancesOnSkip: 0
hideDisappearancesOnSkip: 0
triggerEventsOnSkip: 0
resetTypingSpeedAtStartup: 1
disappearanceOrientation: 0
waitForFullAppearance: 0
waitForFullDisappearance: 0
onTextShowed:
m_PersistentCalls:
m_Calls: []
@@ -529,7 +532,7 @@ MonoBehaviour:
waitForNormalChars: 0.02
waitLong: 0.33333334
waitMiddle: 0.06666667
avoidMultiplePunctuactionWait: 0
avoidMultiplePunctuationWait: 0
waitForNewLines: 1
waitForLastCharacter: 1
useTypewriterWaitForDisappearances: 1
@@ -520,9 +520,12 @@ MonoBehaviour:
useTypeWriter: 1
startTypewriterMode: 3
hideAppearancesOnSkip: 0
hideDisappearancesOnSkip: 0
triggerEventsOnSkip: 0
resetTypingSpeedAtStartup: 1
disappearanceOrientation: 0
waitForFullAppearance: 0
waitForFullDisappearance: 0
onTextShowed:
m_PersistentCalls:
m_Calls: []
@@ -541,7 +544,7 @@ MonoBehaviour:
waitForNormalChars: 0.02
waitLong: 0.6
waitMiddle: 0.2
avoidMultiplePunctuactionWait: 0
avoidMultiplePunctuationWait: 0
waitForNewLines: 1
waitForLastCharacter: 1
useTypewriterWaitForDisappearances: 1
@@ -592,9 +592,12 @@ MonoBehaviour:
useTypeWriter: 1
startTypewriterMode: 3
hideAppearancesOnSkip: 0
hideDisappearancesOnSkip: 0
triggerEventsOnSkip: 0
resetTypingSpeedAtStartup: 1
disappearanceOrientation: 0
waitForFullAppearance: 0
waitForFullDisappearance: 0
onTextShowed:
m_PersistentCalls:
m_Calls: []
@@ -613,7 +616,7 @@ MonoBehaviour:
waitForNormalChars: 0.02
waitLong: 0.6
waitMiddle: 0.2
avoidMultiplePunctuactionWait: 0
avoidMultiplePunctuationWait: 0
waitForNewLines: 1
waitForLastCharacter: 1
useTypewriterWaitForDisappearances: 1
@@ -535,9 +535,12 @@ MonoBehaviour:
useTypeWriter: 1
startTypewriterMode: 3
hideAppearancesOnSkip: 0
hideDisappearancesOnSkip: 0
triggerEventsOnSkip: 0
resetTypingSpeedAtStartup: 1
disappearanceOrientation: 0
waitForFullAppearance: 0
waitForFullDisappearance: 0
onTextShowed:
m_PersistentCalls:
m_Calls: []
@@ -556,7 +559,7 @@ MonoBehaviour:
waitForNormalChars: 0.02
waitLong: 0.6
waitMiddle: 0.2
avoidMultiplePunctuactionWait: 0
avoidMultiplePunctuationWait: 0
waitForNewLines: 1
waitForLastCharacter: 1
useTypewriterWaitForDisappearances: 1
@@ -461,7 +461,7 @@ MeshRenderer:
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_SortingOrder: 49
m_AdditionalVertexStreams: {fileID: 0}
--- !u!114 &376784913
MonoBehaviour:
@@ -478,9 +478,12 @@ MonoBehaviour:
useTypeWriter: 1
startTypewriterMode: 3
hideAppearancesOnSkip: 0
hideDisappearancesOnSkip: 0
triggerEventsOnSkip: 0
resetTypingSpeedAtStartup: 1
disappearanceOrientation: 0
waitForFullAppearance: 0
waitForFullDisappearance: 0
onTextShowed:
m_PersistentCalls:
m_Calls: []
@@ -499,7 +502,7 @@ MonoBehaviour:
waitForNormalChars: 0.03
waitLong: 0.6
waitMiddle: 0.2
avoidMultiplePunctuactionWait: 1
avoidMultiplePunctuationWait: 1
waitForNewLines: 1
waitForLastCharacter: 0
useTypewriterWaitForDisappearances: 1
@@ -540,9 +540,12 @@ MonoBehaviour:
useTypeWriter: 1
startTypewriterMode: 3
hideAppearancesOnSkip: 0
hideDisappearancesOnSkip: 0
triggerEventsOnSkip: 0
resetTypingSpeedAtStartup: 1
disappearanceOrientation: 0
waitForFullAppearance: 0
waitForFullDisappearance: 0
onTextShowed:
m_PersistentCalls:
m_Calls: []
@@ -561,7 +564,7 @@ MonoBehaviour:
waitForNormalChars: 0.03
waitLong: 0.6
waitMiddle: 0.2
avoidMultiplePunctuactionWait: 0
avoidMultiplePunctuationWait: 0
waitForNewLines: 1
waitForLastCharacter: 1
useTypewriterWaitForDisappearances: 1
Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

After

Width:  |  Height:  |  Size: 131 B

@@ -139,6 +139,19 @@ TextureImporter:
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 1024
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 1024
Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 129 B

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 560a88da2bbc70140bed167f0ba7fe37
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: fb01be13d6e88ca488dda82150319bfc
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 117dcc671050f5247bd8743b91ecaab7
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -9,7 +9,7 @@ namespace Febucci.UI.Core.Editors
SerializedProperty waitForNormalChars;
SerializedProperty waitLong;
SerializedProperty waitMiddle;
SerializedProperty avoidMultiplePunctuactionWait;
SerializedProperty avoidMultiplePunctuationWait;
SerializedProperty waitForNewLines;
SerializedProperty waitForLastCharacter;
@@ -24,7 +24,7 @@ namespace Febucci.UI.Core.Editors
waitForNormalChars = serializedObject.FindProperty("waitForNormalChars");
waitLong = serializedObject.FindProperty("waitLong");
waitMiddle = serializedObject.FindProperty("waitMiddle");
avoidMultiplePunctuactionWait = serializedObject.FindProperty("avoidMultiplePunctuactionWait");
avoidMultiplePunctuationWait = serializedObject.FindProperty("avoidMultiplePunctuationWait");
waitForNewLines = serializedObject.FindProperty("waitForNewLines");
waitForLastCharacter = serializedObject.FindProperty("waitForLastCharacter");
useTypewriterWaitForDisappearances = new PropertyWithDifferentLabel(serializedObject, "useTypewriterWaitForDisappearances", "Use Typewriter Wait Times");
@@ -40,11 +40,12 @@ namespace Febucci.UI.Core.Editors
"waitLong",
"waitMiddle",
"avoidMultiplePunctuactionWait",
"avoidMultiplePunctuationWait",
"waitForNewLines",
"waitForLastCharacter",
"useTypewriterWaitForDisappearances",
"disappearanceSpeedMultiplier",
"disappearanceWaitTime"
"disappearanceWaitTime",
};
string[] baseProperties = base.GetPropertiesToExclude();
@@ -70,7 +71,7 @@ namespace Febucci.UI.Core.Editors
EditorGUILayout.PropertyField(waitLong);
EditorGUILayout.PropertyField(waitMiddle);
EditorGUILayout.PropertyField(avoidMultiplePunctuactionWait);
EditorGUILayout.PropertyField(avoidMultiplePunctuationWait);
EditorGUILayout.PropertyField(waitForNewLines);
EditorGUILayout.PropertyField(waitForLastCharacter);
}
@@ -6,7 +6,7 @@ namespace Febucci.UI.Core.Editors
[CustomEditor(typeof(TypewriterCore), true)]
class TypewriterCoreDrawer : Editor
{
SerializedProperty showLettersDinamically;
SerializedProperty useTypewriter;
SerializedProperty startTypewriterMode;
SerializedProperty hideAppearancesOnSkip;
SerializedProperty hideDisappearancesOnSkip;
@@ -20,6 +20,8 @@ namespace Febucci.UI.Core.Editors
SerializedProperty onMessage;
SerializedProperty resetTypingSpeedAtStartup;
SerializedProperty waitForFullAppearance;
SerializedProperty waitForFullDisappearance;
string[] propertiesToExclude = new string[0];
@@ -58,12 +60,14 @@ namespace Febucci.UI.Core.Editors
"onTextDisappeared",
"disappearanceOrientation",
"onMessage",
nameof(TypewriterCore.triggerShowedAfterEffectsEnd),
nameof(TypewriterCore.triggerDisappearedAfterEffectsEnd),
};
}
protected virtual void OnEnable()
{
showLettersDinamically = serializedObject.FindProperty("useTypeWriter");
useTypewriter = serializedObject.FindProperty("useTypeWriter");
startTypewriterMode = serializedObject.FindProperty("startTypewriterMode");
hideAppearancesOnSkip = serializedObject.FindProperty("hideAppearancesOnSkip");
hideDisappearancesOnSkip = serializedObject.FindProperty("hideDisappearancesOnSkip");
@@ -78,6 +82,8 @@ namespace Febucci.UI.Core.Editors
onMessage = serializedObject.FindProperty("onMessage");
resetTypingSpeedAtStartup = serializedObject.FindProperty("resetTypingSpeedAtStartup");
waitForFullAppearance = serializedObject.FindProperty(nameof(TypewriterCore.triggerShowedAfterEffectsEnd));
waitForFullDisappearance = serializedObject.FindProperty(nameof(TypewriterCore.triggerDisappearedAfterEffectsEnd));
propertiesToExclude = GetPropertiesToExclude();
}
@@ -100,7 +106,7 @@ namespace Febucci.UI.Core.Editors
EditorGUILayout.LabelField("Main Settings", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(showLettersDinamically);
EditorGUILayout.PropertyField(useTypewriter);
EditorGUI.indentLevel--;
}
@@ -113,7 +119,7 @@ namespace Febucci.UI.Core.Editors
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Typewriter", EditorStyles.boldLabel);
if (showLettersDinamically.boolValue)
if (useTypewriter.boolValue)
{
if (ButtonPlaymode("Start"))
{
@@ -128,7 +134,7 @@ namespace Febucci.UI.Core.Editors
EditorGUILayout.EndHorizontal();
}
if (showLettersDinamically.boolValue)
if (useTypewriter.boolValue)
{
EditorGUI.indentLevel++;
@@ -137,7 +143,7 @@ namespace Febucci.UI.Core.Editors
EditorGUILayout.PropertyField(resetTypingSpeedAtStartup);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Typewriter Skip", EditorStyles.boldLabel);
EditorGUILayout.LabelField("Typewriter Skip & Events", EditorStyles.boldLabel);
if (ButtonPlaymode("Skip"))
@@ -152,11 +158,13 @@ namespace Febucci.UI.Core.Editors
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(hideAppearancesOnSkip);
EditorGUILayout.PropertyField(triggerEventsOnSkip);
EditorGUILayout.PropertyField(waitForFullAppearance);
EditorGUI.indentLevel--;
EditorGUILayout.LabelField("Disappearing");
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(hideDisappearancesOnSkip);
EditorGUILayout.PropertyField(waitForFullDisappearance);
EditorGUI.indentLevel--;
EditorGUI.indentLevel--;
@@ -184,7 +192,7 @@ namespace Febucci.UI.Core.Editors
//GUI.enabled = showLettersDinamically.boolValue;
if (showLettersDinamically.boolValue)
if (useTypewriter.boolValue)
{
EditorGUI.indentLevel++;
@@ -207,6 +215,9 @@ namespace Febucci.UI.Core.Editors
EditorGUILayout.LabelField("Typewriter Wait", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
GUI.enabled = false;
if(!useTypewriter.boolValue) EditorGUILayout.LabelField("[!] 'Use Typewriter' option is disabled, so these settings might not apply", EditorStyles.wordWrappedMiniLabel);
GUI.enabled = true;
OnTypewriterSectionGUI();
EditorGUI.indentLevel--;
}
@@ -228,9 +239,11 @@ namespace Febucci.UI.Core.Editors
}
EditorGUILayout.EndHorizontal();
EditorGUI.indentLevel++;
GUI.enabled = false;
if(!useTypewriter.boolValue) EditorGUILayout.LabelField("[!] 'Use Typewriter' option is disabled, so these settings might not apply", EditorStyles.wordWrappedMiniLabel);
EditorGUILayout.LabelField("To start disappearances, please call the 'StartDisappearingText()' method. See the docs for more.", EditorStyles.wordWrappedMiniLabel);
GUI.enabled = true;
@@ -13,6 +13,7 @@ namespace Febucci.UI
SerializedProperty appearances;
SerializedProperty styles;
SerializedProperty actions;
SerializedProperty controlTags;
void OnEnable()
@@ -21,6 +22,7 @@ namespace Febucci.UI
appearances = serializedObject.FindProperty(nameof(TextAnimatorSettings.appearances));
styles = serializedObject.FindProperty(nameof(TextAnimatorSettings.defaultStyleSheet));
actions = serializedObject.FindProperty(nameof(TextAnimatorSettings.actions));
controlTags = serializedObject.FindProperty(nameof(TextAnimatorSettings.controlTags));
}
void DrawEffects()
@@ -61,6 +63,9 @@ namespace Febucci.UI
DrawStyles();
EditorGUILayout.Space();
EditorGUILayout.PropertyField(controlTags);
EditorGUILayout.Space();
extraSettings = EditorGUILayout.Foldout(extraSettings, "Extra Settings", EditorStyles.foldoutHeader);
if (extraSettings)
@@ -11,7 +11,7 @@ namespace Febucci.UI
{
public class TextAnimatorSetupWindow : EditorWindow
{
const string currentVersion = "2.1.1";
const string currentVersion = "2.3.0";
const string path_defaultInstallation = "Assets/Plugins/Febucci/Text Animator";
TextAnimatorInstallationData installationData;
Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 529 B

After

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 640 B

After

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 918 B

After

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 779 B

After

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 567 B

After

Width:  |  Height:  |  Size: 128 B

@@ -2,6 +2,7 @@
using Febucci.UI.Core.Parsing;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace Febucci.UI
{
@@ -93,10 +94,23 @@ namespace Febucci.UI
if (attachedInputField) attachedInputField.text = text; //renders input field
else tmpComponent.text = text; //<-- sets the text
// forces rebuilding the layout for text that is truncated etc., otherwise it keeps the
// old textInfo
switch (tmpComponent.overflowMode)
{
case TextOverflowModes.Overflow:
case TextOverflowModes.ScrollRect:
case TextOverflowModes.Masking:
break;
default:
LayoutRebuilder.ForceRebuildLayoutImmediate(tmpComponent.rectTransform);
break;
}
OnForceMeshUpdate();
textInfo = tmpComponent.GetTextInfo(tmpComponent.text);
#if UNITY_EDITOR
if (!Application.isPlaying)
{
@@ -182,6 +196,16 @@ namespace Febucci.UI
}
}
public override int GetRenderedCharactersCountInsidePage() => TMProComponent.overflowMode != TextOverflowModes.Overflow ? TMProComponent.firstOverflowCharacterIndex : base.GetRenderedCharactersCountInsidePage();
public override int GetFirstCharacterIndexInsidePage()
{
if(TMProComponent.pageToDisplay <= 1)
return 0;
return TMProComponent.textInfo.pageInfo[TMProComponent.pageToDisplay - 1].firstCharacterIndex;
}
protected override void PasteMeshToSource(CharacterData[] characters)
{
@@ -131,14 +131,16 @@ namespace Febucci.UI.Core
for (int i = 0; i < charactersCount; i++)
{
if (!characters[i].isVisible)
if (characters[i].isVisible)
{
if (characters[i].passedTime <= 0)
// not fully shown yet
if (characters[i].info.isRendered && characters[i].passedTime < characters[i].info.appearancesMaxDuration)
return false;
}
else
{
if (characters[i].info.isRendered && characters[i].passedTime < characters[i].info.appearancesMaxDuration)
// hidden
if (characters[i].passedTime <= 0)
return false;
}
}
@@ -154,7 +156,7 @@ namespace Febucci.UI.Core
/// <remarks>
/// You can use this to check if the disappearance effects are still running.
/// </remarks>
public bool anyLetterVisible //TODO test
public bool anyLetterVisible
{
get
{
@@ -337,6 +339,38 @@ namespace Febucci.UI.Core
get => disappearances;
set => disappearances = value;
}
Vector2Int[] typewriterDisabledRange;
/// <summary>
/// Holds any range where the typewriter should be skipped entirely and show the entire text.
/// Only takes effect if you're using a <see cref="TypewriterCore"/>
/// </summary>
/// <remarks><seealso cref="IsTypewriterEnabledAtIndex"/>
///P.S. this value is reset every time you set a new text, calculating the "notypewriter" tags in it
/// </remarks>
public Vector2Int[] TypewriterDisabledRange
{
get => typewriterDisabledRange;
set => typewriterDisabledRange = value;
}
/// <summary>
/// True if the typewriter should calculate a <see cref="CharacterData"/> appearance or disappearance time.
/// Calculated from <see cref="TypewriterDisabledRange"/>
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public bool IsTypewriterEnabledAtIndex(int index)
{
foreach (var range in typewriterDisabledRange)
{
if (index >= range.x && index < range.y) return false;
}
return true;
}
#endregion
#region Actions and Events
@@ -507,6 +541,7 @@ namespace Febucci.UI.Core
disappearances = new AnimationRegion[0];
actions = new ActionMarker[0];
events = new EventMarker[0];
typewriterDisabledRange = Array.Empty<Vector2Int>();
if(DatabaseActions) DatabaseActions.ForceBuildRefresh();
if(DatabaseAppearances) DatabaseAppearances.ForceBuildRefresh();
@@ -520,7 +555,21 @@ namespace Febucci.UI.Core
/// Contains TextAnimator's current time values.
/// </summary>
[HideInInspector] public TimeData time;
/// <summary>
/// Returns the first character index inside the page, in case the text has an overflow mode set up and the text is paginated.
/// </summary>
/// <example>
/// If each page has 5 characters, and we're on page 2, then this method would return 5 as the starting index of the text.
/// </example>
/// <returns></returns>
public virtual int GetFirstCharacterIndexInsidePage() => 0;
/// <summary>
/// Returns the number of characters that fit inside the page, in case the text has an overflow mode set up and the text is paginated. (otherwise simply returns the characters count)
/// </summary>
/// <returns></returns>
public virtual int GetRenderedCharactersCountInsidePage() => CharactersCount;
void UpdateUniformIntensity()
{
@@ -559,7 +608,7 @@ namespace Febucci.UI.Core
/// </summary>
[Tooltip("Controls how default tags should be applied.\n\"Fallback\" will apply the effects only to characters that don't have any.\n\"Constant\" will apply the default effects to all the characters, even if they already have other tags via text.")]
public DefaultTagsMode defaultTagsMode = DefaultTagsMode.Fallback;
#region Text
protected virtual TagParserBase[] GetExtraParsers(){ return Array.Empty<TagParserBase>(); }
@@ -835,6 +884,8 @@ namespace Febucci.UI.Core
ActionParser ruleActions = new ActionParser(settings.actions.openingSymbol, '/', settings.actions.closingSymbol, databaseActions);
EventParser ruleEvents = new EventParser('<', '/', '>');
var typewriterDisabled = new PlainTagParser(settings.controlTags.disableTypewriter, '<', '/', '>');
//TODO optimize
var parsers = new System.Collections.Generic.List<TagParserBase>()
{
@@ -842,7 +893,8 @@ namespace Febucci.UI.Core
ruleAppearance,
ruleDisappearance,
ruleActions,
ruleEvents
ruleEvents,
typewriterDisabled
};
foreach (var extraParser in GetExtraParsers())
@@ -870,6 +922,7 @@ namespace Febucci.UI.Core
disappearances = ruleDisappearance.results;
actions = ruleActions.results;
events = ruleEvents.results;
typewriterDisabledRange = typewriterDisabled.results;
//Adds fallback effects to characters that have no effect assigned
AddFallbackEffectsFor(ref behaviors, VisibilityMode.Persistent,databaseBehaviors, defaultBehaviorsTags);
@@ -1000,27 +1053,49 @@ namespace Febucci.UI.Core
/// </summary>
/// <param name="index">Character's index. See <see cref="CharactersCount"/> and the <see cref="Characters"/> array.</param>
/// <param name="isVisible">Controls if the character should be visible</param>
public void SetVisibilityChar(int index, bool isVisible)
/// <param name="canPlayEffects"></param>
public void SetVisibilityChar(int index, bool isVisible, bool canPlayEffects = true)
{
if(index<0 ||index>=charactersCount) return;
if (index < 0 || index >= charactersCount) return;
characters[index].isVisible = isVisible;
if (isVisible) latestCharacterShown = characters[index];
if (isVisible)
{
latestCharacterShown = characters[index];
}
else
{
// fixes a bug that prevents disappearances from firing in case the character has finished appearing (if any) but that wouldn't be enough time to show disappearances at all
// - limit edge case would be no appearance, so the char time would be something close to zero (deltaTime), disappearances 1sec or similar, thus disappearing instantly
if (characters[index].info.disappearancesMaxDuration > characters[index].passedTime && characters[index].passedTime >= characters[index].info.appearancesMaxDuration)
characters[index].passedTime = characters[index].info.disappearancesMaxDuration;
}
if (!canPlayEffects)
{
if (isVisible)
characters[index].passedTime = characters[index].info.appearancesMaxDuration;
else
characters[index].passedTime = 0;
}
}
//TODO TEST
/// <summary>
/// Sets a word visibility.
/// </summary>
/// <param name="index">Word's index. See <see cref="WordsCount"/> and the <see cref="Words"/> array.</param>
/// <param name="isVisible">Controls if the word should be visible</param>
public void SetVisibilityWord(int index, bool isVisible)
/// <param name="canPlayEffects"></param>
public void SetVisibilityWord(int index, bool isVisible, bool canPlayEffects = true)
{
if(index<0 || index >= wordsCount) return;
WordInfo word = words[index];
for (int i = Mathf.Max(word.firstCharacterIndex, 0); i <= word.lastCharacterIndex && i < charactersCount; i++)
{
SetVisibilityChar(i, isVisible);
SetVisibilityChar(i, isVisible, canPlayEffects);
}
}
@@ -1035,25 +1110,7 @@ namespace Febucci.UI.Core
{
for (int i = 0; i < charactersCount; i++)
{
SetVisibilityChar(i, isVisible);
}
if (!canPlayEffects)
{
if (isVisible)
{
for (int i = 0; i < charactersCount;i++)
{
characters[i].passedTime = characters[i].info.appearancesMaxDuration;
}
}
else
{
for (int i = 0; i < charactersCount;i++)
{
characters[i].passedTime = 0;
}
}
SetVisibilityChar(i, isVisible, canPlayEffects);
}
}
@@ -1,5 +1,6 @@
using Febucci.UI.Core;
using UnityEngine;
using UnityEngine.Serialization;
namespace Febucci.UI
{
@@ -16,7 +17,12 @@ namespace Febucci.UI
[SerializeField, Attributes.CharsDisplayTime, Tooltip("Wait time for normal letters")] public float waitForNormalChars = .03f;
[SerializeField, Attributes.CharsDisplayTime, Tooltip("Wait time for ! ? .")] public float waitLong = .6f;
[SerializeField, Attributes.CharsDisplayTime, Tooltip("Wait time for ; : ) - ,")] public float waitMiddle = .2f;
[SerializeField, Tooltip("-True: only the last punctuaction on a sequence waits for its category time.\n-False: each punctuaction will wait, regardless if it's in a sequence or not")] public bool avoidMultiplePunctuactionWait = false;
[System.Obsolete("Typo, please use 'avoidMultiplePunctuationWait' instead.")]
public bool avoidMultiplePunctuactionWait => avoidMultiplePunctuationWait;
[FormerlySerializedAs("avoidMultiplePunctuactionWait")]
[SerializeField, Tooltip("-True: only the last punctuation on a sequence waits for its category time.\n-False: each punctuation will wait, regardless if it's in a sequence or not")] public bool avoidMultiplePunctuationWait = false;
[SerializeField, Tooltip("True if you want the typewriter to wait for new line characters")] public bool waitForNewLines = true;
@@ -35,7 +41,7 @@ namespace Febucci.UI
return 0;
//avoids waiting for multiple times if there are puntuactions near each other
if (avoidMultiplePunctuactionWait && char.IsPunctuation(character)) //curr char is punctuation
if (avoidMultiplePunctuationWait && char.IsPunctuation(character)) //curr char is punctuation
{
//next char is punctuation too, so skips this one
if (charIndex < TextAnimator.CharactersCount - 1
@@ -115,6 +115,26 @@ namespace Febucci.UI.Core
#endregion
/// <summary>
/// <c>true</c> if you want to wait for every single character to animate before invoking <see cref="onTextShowed"/>.
/// Otherwise, you might have that event invoked even if the very last character(s) are animating.
/// </summary>
/// <remarks>
/// Usually users don't want to wait for the very last letter(s), similar to punctuation. That said, this option might come useful in cases like you have very slow letters.
/// </remarks>
[Tooltip("True if you want to wait for every single character appearance to finish before triggering 'onTextShowed'. Default to false, as effects are usually fast enough and make the letters visible, and users are able to read them instantly.")]
public bool triggerShowedAfterEffectsEnd = false;
/// <summary>
/// <c>true</c> if you want to wait for every single character to animate before invoking <see cref="onTextDisappeared"/>.
/// Otherwise, you might have that event invoked even if the very last character(s) are animating.
/// </summary>
/// <remarks>
/// Usually users don't want to wait for the very last letter(s), similar to punctuation. That said, this option might come useful in cases like you have very slow letters.
/// </remarks>
[Tooltip("True if you want to wait for every single character disappearance to finish before triggering 'onTextDisappeared'. Default to false, as effects are usually fast enough")]
public bool triggerDisappearedAfterEffectsEnd = false;
#endregion
#region Events
@@ -200,12 +220,32 @@ namespace Febucci.UI.Core
/// </remarks>
public void SkipTypewriter()
{
void SetVisibilityWithOverflow(bool visible)
{
var visibleCharactersInPage = TextAnimator.GetRenderedCharactersCountInsidePage();
if (visibleCharactersInPage > 0 && visibleCharactersInPage != TextAnimator.CharactersCount)
{
int firstCharacter = TextAnimator.GetFirstCharacterIndexInsidePage();
if(firstCharacter<0) firstCharacter = 0;
int lastCharacter = firstCharacter + visibleCharactersInPage;
for (int i = firstCharacter; i < lastCharacter; i++)
{
TextAnimator.SetVisibilityChar(i, visible, !hideAppearancesOnSkip);
}
}
else
{
TextAnimator.SetVisibilityEntireText(visible, !hideAppearancesOnSkip);
}
}
if (isShowingText)
{
StopAllCoroutines();
isShowingText = false;
TextAnimator.SetVisibilityEntireText(true, !hideAppearancesOnSkip);
SetVisibilityWithOverflow(true);
if (triggerEventsOnSkip)
{
@@ -221,7 +261,7 @@ namespace Febucci.UI.Core
isHidingText = false;
onTextDisappeared?.Invoke();
TextAnimator.SetVisibilityEntireText(false, !hideDisappearancesOnSkip);
SetVisibilityWithOverflow(false);
// No events on disappearance
@@ -261,6 +301,13 @@ namespace Febucci.UI.Core
if (restart)
{
TextAnimator.SetVisibilityEntireText(false, false);
}
// makes sure to reset actions etc. if no text is about to restart
// (might also happen if restart=false, but user called SetText and/or text finished and should restart
// calling this method)
if (TextAnimator.firstVisibleCharacter == 0)
{
latestActionTriggered = 0;
latestEventTriggered = 0;
}
@@ -270,6 +317,7 @@ namespace Febucci.UI.Core
showRoutine = StartCoroutine(ShowTextRoutine());
}
protected abstract float GetWaitAppearanceTimeOf(int charIndex);
Coroutine showRoutine;
@@ -290,7 +338,14 @@ namespace Febucci.UI.Core
bool actionsEnabled = settings && settings.actions.enabled;
// --- SHOWS TEXT LETTERS ---
for(int i=0;i<TextAnimator.CharactersCount;i++)
int visibleCharsInPage = TextAnimator.GetRenderedCharactersCountInsidePage();
if(visibleCharsInPage<=0) visibleCharsInPage = TextAnimator.CharactersCount;
int firstCharacter = TextAnimator.GetFirstCharacterIndexInsidePage();
if(firstCharacter<0) firstCharacter = 0;
int lastCharacter = firstCharacter + visibleCharsInPage;
for(int i=firstCharacter;i<TextAnimator.CharactersCount && i < lastCharacter; i++)
{
// -- actions --
if (actionsEnabled)
@@ -307,39 +362,42 @@ namespace Febucci.UI.Core
// -- events --
TriggerEventsUntil(i+1);
if(TextAnimator.Characters[i].isVisible) continue;
if (TextAnimator.Characters[i].isVisible) continue;
// -- shows letter --
TextAnimator.SetVisibilityChar(i, true);
onCharacterVisible?.Invoke(TextAnimator.latestCharacterShown.info.character);
// -- WAITS TIME -- (identical to HideTextRoutine, in order to skip frames correctly)
float timeToWait = GetWaitAppearanceTimeOf(i);
float deltaTime = GetDeltaTime(typingInfo);
if (timeToWait < 0) timeToWait = 0;
if (timeToWait < deltaTime) //waiting less time than a frame, we don't wait yet
{
typingInfo.timePassed += timeToWait;
if (typingInfo.timePassed >= deltaTime) //waits only if we "surpassed" a frame duration
{
yield return null;
//saves remaining time to next frame as already waited time
typingInfo.timePassed %= deltaTime;
}
}
else
{
//waits until enough time has passed
while (typingInfo.timePassed < timeToWait)
{
typingInfo.timePassed += deltaTime;
yield return null;
deltaTime = GetDeltaTime(typingInfo);
}
typingInfo.timePassed %= timeToWait; //saves remaining time to next frame
// -- WAITS TIME -- (identical to HideTextRoutine, in order to skip frames correctly)
if (_textAnimator.IsTypewriterEnabledAtIndex(i))
{
float timeToWait = GetWaitAppearanceTimeOf(i);
float deltaTime = GetDeltaTime(typingInfo);
if (timeToWait < 0) timeToWait = 0;
if (timeToWait < deltaTime) //waiting less time than a frame, we don't wait yet
{
typingInfo.timePassed += timeToWait;
if (typingInfo.timePassed >= deltaTime) //waits only if we "surpassed" a frame duration
{
yield return null;
//saves remaining time to next frame as already waited time
typingInfo.timePassed %= deltaTime;
}
}
else
{
//waits until enough time has passed
while (typingInfo.timePassed < timeToWait)
{
typingInfo.timePassed += deltaTime;
yield return null;
deltaTime = GetDeltaTime(typingInfo);
}
typingInfo.timePassed %= timeToWait; //saves remaining time to next frame
}
}
}
@@ -356,9 +414,15 @@ namespace Febucci.UI.Core
}
TriggerEventsUntil(int.MaxValue);
if (triggerShowedAfterEffectsEnd)
{
while (!_textAnimator.allLettersShown)
yield return null;
}
// --- CALLBACKS ---
onTextShowed?.Invoke();
isShowingText = false;
onTextShowed?.Invoke();
}
/// <summary>
@@ -444,20 +508,29 @@ namespace Febucci.UI.Core
// --- INITIALIZATION ---
TypingInfo typingInfo = new TypingInfo();
int visibleCharsInPage = TextAnimator.GetRenderedCharactersCountInsidePage();
if(visibleCharsInPage<=0) visibleCharsInPage = TextAnimator.CharactersCount;
int firstCharacter = TextAnimator.GetFirstCharacterIndexInsidePage();
if(firstCharacter<0) firstCharacter = 0;
int lastCharacter = firstCharacter + visibleCharsInPage;
// Chooses the order in which the letters will disappear
int[] indexes = new int[TextAnimator.CharactersCount];
switch (disappearanceOrientation)
{
default:
case DisappearanceOrientation.SameAsTypewriter: //disappears from the end
for (int i = 0; i < TextAnimator.CharactersCount; i++) indexes[i] = i;
for (int i = firstCharacter; i < TextAnimator.CharactersCount && i < lastCharacter; i++) indexes[i] = i;
break;
case DisappearanceOrientation.Inverted:
for (int i = 0; i < TextAnimator.CharactersCount; i++) indexes[i] = TextAnimator.CharactersCount - i - 1;
for (int i = firstCharacter; i < TextAnimator.CharactersCount && i < lastCharacter; i++) indexes[i] = visibleCharsInPage - i - 1;
break;
case DisappearanceOrientation.Random:
for (int i = 0; i < TextAnimator.CharactersCount; i++) indexes[i] = i;
for (int i = firstCharacter; i < TextAnimator.CharactersCount && i < lastCharacter; i++) indexes[i] = i;
indexes = ShuffleArray(indexes);
break;
}
@@ -465,7 +538,8 @@ namespace Febucci.UI.Core
// --- CALLBACKS ---
// --- HIDES TEXT ---
for (int i = 0; i < TextAnimator.CharactersCount; i++)
for (int i = 0; i < indexes.Length; i++)
{
int indexToHide = indexes[i];
if(!TextAnimator.Characters[indexToHide].isVisible) continue;
@@ -474,35 +548,44 @@ namespace Febucci.UI.Core
float timeToWait = GetWaitDisappearanceTimeOf(indexToHide);
// -- WAITS TIME -- (identical to ShowTextRoutine, in order to skip frames correctly)
float deltaTime = GetDeltaTime(typingInfo);
if (timeToWait < 0) timeToWait = 0;
if (timeToWait < deltaTime) //waiting less time than a frame, we don't wait yet
if (_textAnimator.IsTypewriterEnabledAtIndex(i))
{
typingInfo.timePassed += timeToWait;
if (typingInfo.timePassed >= deltaTime) //waits only if we "surpassed" a frame duration
float deltaTime = GetDeltaTime(typingInfo);
if (timeToWait < 0) timeToWait = 0;
if (timeToWait < deltaTime) //waiting less time than a frame, we don't wait yet
{
yield return null;
//saves remaining time to next frame as already waited time
typingInfo.timePassed %= deltaTime;
typingInfo.timePassed += timeToWait;
if (typingInfo.timePassed >= deltaTime) //waits only if we "surpassed" a frame duration
{
yield return null;
//saves remaining time to next frame as already waited time
typingInfo.timePassed %= deltaTime;
}
}
}
else
{
//waits until enough time has passed
while (typingInfo.timePassed < timeToWait)
else
{
typingInfo.timePassed += deltaTime;
yield return null;
deltaTime = GetDeltaTime(typingInfo);
}
//waits until enough time has passed
while (typingInfo.timePassed < timeToWait)
{
typingInfo.timePassed += deltaTime;
yield return null;
deltaTime = GetDeltaTime(typingInfo);
}
typingInfo.timePassed %= timeToWait; //saves remaining time to next frame
typingInfo.timePassed %= timeToWait; //saves remaining time to next frame
}
}
}
if (triggerDisappearedAfterEffectsEnd)
{
while (_textAnimator.anyLetterVisible)
yield return null;
}
// --- CALLBACKS ---
onTextDisappeared?.Invoke();
isHidingText = false;
onTextDisappeared?.Invoke();
}
#endregion
@@ -45,7 +45,6 @@ namespace Febucci.UI.Core.Parsing
System.Array.Resize(ref _results, _results.Length + 1);
_results[_results.Length - 1] = textEvent;
return true;
}
}
@@ -0,0 +1,53 @@
using System;
using System.Text;
using UnityEngine;
namespace Febucci.UI.Core.Parsing
{
public sealed class PlainTagParser : TagParserBase
{
readonly string tag;
public PlainTagParser(string tag, char startSymbol, char closingSymbol, char endSymbol) : base(startSymbol, closingSymbol,
endSymbol)
{
this.tag = tag;
results = Array.Empty<Vector2Int>();
}
bool hasOpened;
public Vector2Int[] results;
//--- METHODS ---
public override bool TryProcessingTag(string textInsideBrackets, int tagLength, ref int realTextIndex,
StringBuilder finalTextBuilder, int internalOrder)
{
textInsideBrackets = textInsideBrackets.ToLower();
if (tagLength <= 1) return false;
if (textInsideBrackets[0] == closingSymbol) // closes
{
if (!textInsideBrackets.Substring(1, tagLength - 1).Equals(tag)) return false;
if (results.Length > 0 && hasOpened)
{
results[results.Length - 1].y = realTextIndex;
hasOpened = true;
return true;
}
}
else
{
if (!textInsideBrackets.Equals(tag)) return false;
hasOpened = true;
var newTag = new Vector2Int(realTextIndex, int.MaxValue);
Array.Resize(ref results, results.Length+1);
results[results.Length-1] = newTag;
return true;
}
return false;
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0ee9f3c38e8247a098339a7b62918ece
timeCreated: 1729157278
@@ -101,5 +101,18 @@ namespace Febucci.UI
public Category<ActionDatabase> actions = new Category<ActionDatabase>('<', '>');
public StyleSheetScriptable defaultStyleSheet;
[System.Serializable]
public struct ControlTags
{
public string disableTypewriter;
public ControlTags(string disableTypewriter)
{
this.disableTypewriter = disableTypewriter;
}
}
public ControlTags controlTags = new ControlTags("notype");
}
}
@@ -38,15 +38,16 @@ namespace Febucci.UI.Styles
foreach (var style in styles)
{
if (string.IsNullOrEmpty(style.styleTag)) continue;
var tag = style.styleTag.ToLowerInvariant();
if (string.IsNullOrEmpty(tag)) continue;
if (dictionary.ContainsKey(style.styleTag))
if (dictionary.ContainsKey(tag))
{
Debug.LogError($"[TextAnimator] StyleSheetScriptable: duplicated style tag '{style.styleTag}", this);
Debug.LogError($"[TextAnimator] StyleSheetScriptable: duplicated style tag '{tag}", this);
continue;
}
dictionary.Add(style.styleTag, style);
dictionary.Add(tag, style);
}
}
@@ -56,7 +57,7 @@ namespace Febucci.UI.Styles
BuildOnce();
}
public bool TryGetStyle(string tag, out Style result)
public virtual bool TryGetStyle(string tag, out Style result)
{
BuildOnce();
return dictionary.TryGetValue(tag, out result);
+5 -3
View File
@@ -3,7 +3,6 @@ tags:
---
<<load_scene ExpressFixScene>>
<<switch_fix_system_to BodyModule>>
aaa: <notype>不答应</notype>这也行
===
title: LungPlugIn
@@ -13,13 +12,16 @@ tags:
<<open_screen>>
LungModule: 肺部模块已连接
LungModule: 等待下一步指令
-> 分析
LungModule: 等待下一步指令
LungModule: 等待下一步指令
普通对话
->分析
<<hide_dialog>>
<<clear_screen>>
Analysing: A部分正常
Analysing: B部分异常
Analysing: C部分分析中
<<close_screen>>
-> 返回
->返回
<<close_screen>>
===
+1 -77
View File
@@ -5320,7 +5320,7 @@ MonoBehaviour:
rotateDuration: 0.5
title: {fileID: 2144726594}
text: {fileID: 1506508221}
textTypewriter: {fileID: 1506508223}
textTypewriter: {fileID: 0}
screenImage: {fileID: 518267368}
--- !u!1 &1279241653
GameObject:
@@ -5615,8 +5615,6 @@ GameObject:
- component: {fileID: 1506508220}
- component: {fileID: 1506508222}
- component: {fileID: 1506508221}
- component: {fileID: 1506508224}
- component: {fileID: 1506508223}
m_Layer: 0
m_Name: Text
m_TagString: Untagged
@@ -5777,80 +5775,6 @@ MeshRenderer:
m_SortingLayer: 10
m_SortingOrder: 102
m_AdditionalVertexStreams: {fileID: 0}
--- !u!114 &1506508223
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1506508219}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 57a6945b90dcd0c4b81619c0d8b5c283, type: 3}
m_Name:
m_EditorClassIdentifier:
useTypeWriter: 1
startTypewriterMode: 2
hideAppearancesOnSkip: 0
hideDisappearancesOnSkip: 0
triggerEventsOnSkip: 0
resetTypingSpeedAtStartup: 1
disappearanceOrientation: 0
onTextShowed:
m_PersistentCalls:
m_Calls: []
onTypewriterStart:
m_PersistentCalls:
m_Calls: []
onTextDisappeared:
m_PersistentCalls:
m_Calls: []
onCharacterVisible:
m_PersistentCalls:
m_Calls: []
onMessage:
m_PersistentCalls:
m_Calls: []
waitForNormalChars: 0.02
waitLong: 0.6
waitMiddle: 0.2
avoidMultiplePunctuactionWait: 0
waitForNewLines: 1
waitForLastCharacter: 1
useTypewriterWaitForDisappearances: 1
disappearanceWaitTime: 0.015
disappearanceSpeedMultiplier: 1
--- !u!114 &1506508224
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1506508219}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e8ace8ced0e81c847968cdca0aeda757, type: 3}
m_Name:
m_EditorClassIdentifier:
typewriterStartsAutomatically: 0
animationLoop: 0
timeScale: 0
_text:
useDynamicScaling: 1
referenceFontSize: 10
isResettingTimeOnNewText: 1
useDefaultDatabases: 1
databaseBehaviors: {fileID: 11400000, guid: ab7e07cba198f4345b19d351e6a3034f, type: 2}
databaseAppearances: {fileID: 11400000, guid: 71ecf6147756deb4ca20570628f94f96, type: 2}
useDefaultStyleSheet: 1
styleSheet: {fileID: 0}
databaseActions: {fileID: 11400000, guid: de78232a60d74f6459e57e5606304209, type: 2}
defaultAppearancesTags:
- fade
defaultDisappearancesTags:
- fade
defaultBehaviorsTags: []
defaultTagsMode: 0
--- !u!1001 &1538548679
PrefabInstance:
m_ObjectHideFlags: 0
+8 -25
View File
@@ -10268,6 +10268,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 429e0ca7a1096a1478e50195b88539b8, type: 3}
m_Name:
m_EditorClassIdentifier:
objWidth: 700
objHeight: 550
--- !u!1 &1009826576
GameObject:
m_ObjectHideFlags: 0
@@ -12738,10 +12740,6 @@ PrefabInstance:
propertyPath: m_Name
value: Dialog Box
objectReference: {fileID: 0}
- target: {fileID: 6059188073131988442, guid: e2211373480d40243a377721316dd8f7, type: 3}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
- target: {fileID: 7131956091114956203, guid: e2211373480d40243a377721316dd8f7, type: 3}
propertyPath: m_Pivot.x
value: 0.5
@@ -19630,14 +19628,13 @@ GameObject:
- component: {fileID: 2038437602}
- component: {fileID: 2038437604}
- component: {fileID: 2038437603}
- component: {fileID: 2038437605}
m_Layer: 5
m_Name: Obj
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
m_IsActive: 0
--- !u!224 &2038437602
RectTransform:
m_ObjectHideFlags: 0
@@ -19645,17 +19642,17 @@ RectTransform:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2038437601}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 773911910}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 1}
m_AnchorMax: {x: 0.5, y: 1}
m_AnchoredPosition: {x: 0, y: -367}
m_SizeDelta: {x: 600, y: 600}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 0, y: 100}
m_SizeDelta: {x: 700, y: 550}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &2038437603
MonoBehaviour:
@@ -19695,20 +19692,6 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2038437601}
m_CullTransparentMesh: 1
--- !u!114 &2038437605
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2038437601}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 2
m_VerticalFit: 2
--- !u!1 &2065230354
GameObject:
m_ObjectHideFlags: 0
@@ -3,7 +3,6 @@ using System.Collections;
using AibisDream.Framework;
using AibisDream.Kit;
using DG.Tweening;
using Febucci.UI;
using TMPro;
using UnityEngine;
@@ -16,6 +15,7 @@ namespace AibisDream.FixSystem
#region
public float rotateDuration = 0.5f;
public float typeSpeed = 0.05f;
#endregion
@@ -24,7 +24,6 @@ namespace AibisDream.FixSystem
private Transform _textScreen;
[SerializeField] private TMP_Text title;
[SerializeField] private TMP_Text text;
[SerializeField] private TypewriterByCharacter textTypewriter;
[SerializeField] private SpriteRenderer screenImage;
private Material _imageMaterial;
@@ -49,8 +48,6 @@ namespace AibisDream.FixSystem
{
FixSystemCenter.SystemDic.Register(this);
DialogCanvasManager.Instance.RegisterDialogView(DialogViewType.Screen, this);
textTypewriter.onTextShowed.AddListener(() => StartCoroutine(AutoNextStep()));
}
private void OnDestroy()
@@ -72,19 +69,28 @@ namespace AibisDream.FixSystem
title.text = targetTitle;
}
public void ShowText(string targetText)
public IEnumerator ShowText(string targetText)
{
// 获取旧文字
// 先换行
if (!string.IsNullOrEmpty(text.text))
{
text.text += "\n";
}
var oldText = text.text;
// if (!string.IsNullOrWhiteSpace(oldText))
// {
// // 去掉notype标签,并且加上新的
// var rawOldText = oldText.Replace("<notype>", "").Replace("</notype>", "");
// oldText = "<notype> " + rawOldText + " </notype>";
// }
// 显示文字
textTypewriter.ShowText(oldText + targetText);
var targetLength = text.text.Length + targetText.Length;
// 逐个字符添加
yield return DOTween.To(() => text.text.Length, x => UpdateText(x, targetText, oldText), targetLength,
targetText.Length * typeSpeed).WaitForCompletion();
yield return new WaitForSeconds(0.5f);
_nextStep.Invoke();
}
private void UpdateText(int currentLength, string nextText, string oldText)
{
var appendLength = currentLength - oldText.Length;
text.text = oldText + nextText[..appendLength];
}
public Tween ShowImage(Sprite sprite)
@@ -133,7 +139,7 @@ namespace AibisDream.FixSystem
// 右侧加载图片
var tween = ShowImage(sprite);
yield return tween.WaitForCompletion();
// 左侧打开副屏
OpenTextScreen();
yield return new WaitForSeconds(rotateDuration + 0.2f);
@@ -151,7 +157,7 @@ namespace AibisDream.FixSystem
// 左侧回收屏幕
CloseTextScreen();
yield return new WaitForSeconds(rotateDuration + 0.2f);
EnumEventSystem.Global.Send(EventEnum.CloseScreen);
}
@@ -163,8 +169,7 @@ namespace AibisDream.FixSystem
bool isAutoSkip = false)
{
ShowTitle(character.GetActorName());
ShowText(dialogLine);
StartCoroutine(ShowText(dialogLine));
// 每行自动跳过
_nextStep = nextStep;
}
@@ -190,13 +195,6 @@ namespace AibisDream.FixSystem
// 这里不能手动跳到下一行
}
private IEnumerator AutoNextStep()
{
yield return new WaitForSeconds(0.2f);
_nextStep?.Invoke();
_nextStep = null;
}
#endregion
}
@@ -212,7 +210,7 @@ namespace AibisDream.FixSystem
void ShowTitle(string title);
// 显示正文
void ShowText(string text);
IEnumerator ShowText(string text);
// 显示图片
Tween ShowImage(Sprite sprite);
-9
View File
@@ -10,15 +10,6 @@ namespace AibisDream
{
// 初始化选择按钮
choiceButtonPrefab = choiceButton;
// 注册Viewer
DialogCanvasManager.Instance.RegisterDialogView(DialogViewType.OldBox, this);
gameObject.SetActive(false);
}
protected override void OnDialogViewerDestroy()
{
DialogCanvasManager.Instance.UnregisterDialogView(DialogViewType.OldBox);
}
}
}
@@ -27,6 +27,10 @@ namespace AibisDream
{
InitQuickTalkButton();
InitEvent();
// 默认对话框直接加载
var box = transform.Find("Dialog Box").GetComponent<IDialogView>();
RegisterDialogView(DialogViewType.OldBox, box);
}
private void Start()
+36 -6
View File
@@ -1,5 +1,6 @@
using System.Collections;
using AibisDream.Kit;
using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;
@@ -11,6 +12,14 @@ namespace AibisDream
private const string BlackImage = "Fade Image";
private const string NewsImage = "News";
private const string ObjPanel = "Show Obj";
#region ShowObj参数
[Header("Obj尺寸参数")]
public float objWidth;
public float objHeight;
#endregion
#region
@@ -18,7 +27,7 @@ namespace AibisDream
private FadeImage _blackImage;
private FadeImage _news;
private GameObject _objPanel;
private FadeImage _objImage;
private Image _objImage;
#endregion
@@ -99,8 +108,28 @@ namespace AibisDream
public IEnumerator ShowObj(string picName)
{
_objPanel.gameObject.SetActive(true);
_objImage.SwitchImage($"Art/Obj/{picName}");
return _objImage.FadeInSync(1);
// 切换图片
var newSprite = Resources.Load<Sprite>($"Art/Obj/{picName}");
// 获取图片的长宽比
var imageAspect = (float)newSprite.texture.width / newSprite.texture.height;
// 计算新的尺寸
if (imageAspect > 1) // 宽图
{
var newHeight = objWidth / imageAspect;
_objImage.rectTransform.sizeDelta = new Vector2(objWidth, newHeight);
}
else // 高图
{
var newWidth = objHeight * imageAspect;
_objImage.rectTransform.sizeDelta = new Vector2(newWidth, objHeight);
}
// 淡入
_objImage.sprite = newSprite;
_objImage.gameObject.SetActive(true);
yield return _objImage.DOBlendableColor(Color.white, 1).WaitForCompletion();
}
/// <summary>
@@ -109,7 +138,9 @@ namespace AibisDream
/// <returns>协程</returns>
public IEnumerator HideObj()
{
yield return _objImage.FadeOutSync(1);
_objImage.gameObject.SetActive(true);
yield return _objImage.DOBlendableColor(Color.clear, 1).WaitForCompletion();
_objImage.gameObject.SetActive(false);
_objPanel.SetActive(false);
}
@@ -125,8 +156,7 @@ namespace AibisDream
_news = new FadeImage(rawNews);
_objPanel = transform.Find(ObjPanel).gameObject;
var rawObj = _objPanel.transform.GetChild(0).GetComponent<Image>();
_objImage = new FadeImage(rawObj);
_objImage = _objPanel.transform.GetChild(0).GetComponent<Image>();
}
}
}