25
Assets/RPGTALK/Scripts/Helpers/RPGTalkCharacter.cs
Normal file
25
Assets/RPGTALK/Scripts/Helpers/RPGTalkCharacter.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RPGTALK.Helper
|
||||
{
|
||||
|
||||
[System.Serializable]
|
||||
public class Expression
|
||||
{
|
||||
public string name;
|
||||
public Sprite photo;
|
||||
public string boolInAnimator;
|
||||
public AudioClip audio;
|
||||
}
|
||||
|
||||
[CreateAssetMenu(fileName = "New Character", menuName = "RPGTalk/Character", order = 12)]
|
||||
public class RPGTalkCharacter : ScriptableObject
|
||||
{
|
||||
public string dialoger;
|
||||
public Sprite photo;
|
||||
|
||||
public Expression[] expressions;
|
||||
}
|
||||
}
|
11
Assets/RPGTALK/Scripts/Helpers/RPGTalkCharacter.cs.meta
generated
Normal file
11
Assets/RPGTALK/Scripts/Helpers/RPGTalkCharacter.cs.meta
generated
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d46921e71e9f04ccb83ec685be24573c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
314
Assets/RPGTALK/Scripts/Helpers/RPGTalkHelper.cs
Normal file
314
Assets/RPGTALK/Scripts/Helpers/RPGTalkHelper.cs
Normal file
@@ -0,0 +1,314 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
#if RPGTalk_TMP
|
||||
using TMPro;
|
||||
#endif
|
||||
|
||||
namespace RPGTALK.Helper
|
||||
{
|
||||
[AddComponentMenu("Seize Studios/RPGTalk/Helper/RPGTalk Helper")]
|
||||
public class RPGTalkHelper : MonoBehaviour {
|
||||
|
||||
public static void CopyTextParameters(Object original, Object copy)
|
||||
{
|
||||
if (original is Text)
|
||||
{
|
||||
CopyTextParameters(original as Text, copy as Text);
|
||||
return;
|
||||
}
|
||||
#if RPGTalk_TMP
|
||||
if(original is TextMeshProUGUI)
|
||||
{
|
||||
CopyTextParameters(original as TextMeshProUGUI, copy as TextMeshProUGUI);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void CopyTextParameters(Text original, Text copy){
|
||||
//Replace every public option of the new text with the ancient one
|
||||
copy.text = original.text;
|
||||
copy.font = original.font;
|
||||
copy.fontStyle = original.fontStyle;
|
||||
copy.fontSize = original.fontSize;
|
||||
copy.lineSpacing = original.lineSpacing;
|
||||
copy.supportRichText = original.supportRichText;
|
||||
copy.alignment = original.alignment;
|
||||
copy.alignByGeometry = original.alignByGeometry;
|
||||
copy.horizontalOverflow = original.horizontalOverflow;
|
||||
copy.verticalOverflow = original.verticalOverflow;
|
||||
copy.resizeTextForBestFit = original.resizeTextForBestFit;
|
||||
copy.color = original.color;
|
||||
copy.material = original.material;
|
||||
copy.raycastTarget = original.raycastTarget;
|
||||
}
|
||||
#if RPGTalk_TMP
|
||||
public static void CopyTextParameters(TextMeshProUGUI original, TextMeshProUGUI copy)
|
||||
{
|
||||
//Replace every public option of the new text with the ancient one
|
||||
copy.text = original.text;
|
||||
copy.font = original.font;
|
||||
copy.fontStyle = original.fontStyle;
|
||||
copy.fontSize = original.fontSize;
|
||||
copy.lineSpacing = original.lineSpacing;
|
||||
copy.richText = original.richText;
|
||||
copy.alignment = original.alignment;
|
||||
copy.horizontalMapping = original.horizontalMapping;
|
||||
copy.verticalMapping = original.verticalMapping;
|
||||
copy.enableAutoSizing = original.enableAutoSizing;
|
||||
copy.color = original.color;
|
||||
copy.material = original.material;
|
||||
copy.raycastTarget = original.raycastTarget;
|
||||
copy.enableWordWrapping = original.enableWordWrapping;
|
||||
copy.wordWrappingRatios = original.wordWrappingRatios;
|
||||
copy.overflowMode = original.overflowMode;
|
||||
}
|
||||
#endif
|
||||
public static int CountRichTextCharacters(string line){
|
||||
int richTextCount = 0;
|
||||
//check for any rich text
|
||||
if (line.IndexOf('<') != -1) {
|
||||
bool thereIsRichTextLeft = true;
|
||||
|
||||
//repeat for as long as we find a tag
|
||||
while (thereIsRichTextLeft) {
|
||||
int inicialBracket = line.IndexOf ('<');
|
||||
int finalBracket = line.IndexOf ('>');
|
||||
//Here comes the tricky part... First check if there is any '<' before a '>'
|
||||
if (inicialBracket < finalBracket) {
|
||||
//Ok, there is! It should be a tag. Let's count every char inside of it
|
||||
richTextCount += finalBracket-inicialBracket+1;
|
||||
|
||||
|
||||
//Good! Now finaly, remove it from the original text
|
||||
string textWithoutRichText = line.Substring (0, inicialBracket);
|
||||
textWithoutRichText += line.Substring (finalBracket + 1);
|
||||
line = textWithoutRichText;
|
||||
|
||||
} else {
|
||||
thereIsRichTextLeft = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return richTextCount;
|
||||
}
|
||||
|
||||
public static int CountRPGTalkTagCharacters(string line){
|
||||
int tagCount = 0;
|
||||
//check for any rich text
|
||||
if (line.IndexOf('[') != -1) {
|
||||
bool thereAreTagsLeft = true;
|
||||
|
||||
//repeat for as long as we find a tag
|
||||
while (thereAreTagsLeft) {
|
||||
int inicialBracket = line.IndexOf ('[');
|
||||
int finalBracket = line.IndexOf (']');
|
||||
//Here comes the tricky part... First check if there is any '[' before a ']'
|
||||
if (inicialBracket < finalBracket) {
|
||||
//Ok, there is! It should be a tag. Let's count every char inside of it
|
||||
tagCount += finalBracket-inicialBracket+1;
|
||||
|
||||
|
||||
//Good! Now finaly, remove it from the original text
|
||||
string textWithoutTag = line.Substring (0, inicialBracket);
|
||||
textWithoutTag += line.Substring (finalBracket + 1);
|
||||
line = textWithoutTag;
|
||||
|
||||
} else {
|
||||
thereAreTagsLeft = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return tagCount;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
[MenuItem("RPGTalk/Create RPGTalk/Base Instance")]
|
||||
private static void CreateRPGTalkBase()
|
||||
{
|
||||
GameObject newGO = new GameObject ();
|
||||
newGO.AddComponent<RPGTalk> ();
|
||||
newGO.name = "RPGTalk Holder";
|
||||
Undo.RegisterCreatedObjectUndo (newGO, "Create RPGTalk");
|
||||
}
|
||||
|
||||
[MenuItem("RPGTalk/Create RPGTalk/With Dub Sound")]
|
||||
private static void CreateRPGTalkWithDub()
|
||||
{
|
||||
GameObject newGO = new GameObject ();
|
||||
newGO.AddComponent<RPGTalk> ();
|
||||
newGO.AddComponent<RPGTALK.Dub.RPGTalkDubSounds> ();
|
||||
newGO.name = "RPGTalk Holder & Dub";
|
||||
Undo.RegisterCreatedObjectUndo (newGO, "Create RPGTalk");
|
||||
}
|
||||
[MenuItem("RPGTalk/Create RPGTalk/With Timeline")]
|
||||
private static void CreateRPGTalkWithTimeline()
|
||||
{
|
||||
GameObject newGO = new GameObject ();
|
||||
newGO.AddComponent<RPGTalk> ();
|
||||
newGO.AddComponent<RPGTALK.Timeline.RPGTalkTimeline> ();
|
||||
newGO.name = "RPGTalk Holder & Timeline";
|
||||
Undo.RegisterCreatedObjectUndo (newGO, "Create RPGTalk");
|
||||
}
|
||||
[MenuItem("RPGTalk/Create RPGTalk/With Dub and Timeline")]
|
||||
private static void CreateRPGTalkWithDubTimeline()
|
||||
{
|
||||
GameObject newGO = new GameObject ();
|
||||
newGO.AddComponent<RPGTalk> ();
|
||||
newGO.AddComponent<RPGTALK.Dub.RPGTalkDubSounds> ();
|
||||
newGO.AddComponent<RPGTALK.Timeline.RPGTalkTimeline> ();
|
||||
newGO.name = "RPGTalk Holder & Dub & Timeline";
|
||||
Undo.RegisterCreatedObjectUndo (newGO, "Create RPGTalk");
|
||||
}
|
||||
|
||||
[MenuItem("RPGTalk/Create RPGTalk Area")]
|
||||
private static void CreateRPGTalkArea()
|
||||
{
|
||||
|
||||
GameObject newGO = new GameObject ();
|
||||
if (EditorSettings.defaultBehaviorMode == EditorBehaviorMode.Mode2D) {
|
||||
BoxCollider2D newBox = newGO.AddComponent<BoxCollider2D> ();
|
||||
newBox.size = new Vector2 (1, 1);
|
||||
newBox.isTrigger = true;
|
||||
} else {
|
||||
BoxCollider newBox = newGO.AddComponent<BoxCollider> ();
|
||||
newBox.size = new Vector3 (1, 1, 1);
|
||||
newBox.isTrigger = true;
|
||||
}
|
||||
newGO.AddComponent<RPGTalkArea> ();
|
||||
newGO.name = "RPGTalk Area";
|
||||
Undo.RegisterCreatedObjectUndo (newGO, "Create RPGTalk Area");
|
||||
}
|
||||
|
||||
[MenuItem("RPGTalk/Create RPGTalk Localization")]
|
||||
private static void CreateRPGTalkLocalization()
|
||||
{
|
||||
|
||||
GameObject newGO = new GameObject ();
|
||||
|
||||
newGO.AddComponent<RPGTALK.Localization.RPGTalkLocalization> ();
|
||||
newGO.name = "RPGTalk Localization";
|
||||
Undo.RegisterCreatedObjectUndo (newGO, "Create RPGTalk Localization");
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
//this class has every dialog (line) that need to be show
|
||||
public class RpgtalkElement {
|
||||
public bool hasDialog = false;
|
||||
public bool allowPlayerAdvance = true;
|
||||
public string speakerName;
|
||||
public string originalSpeakerName;
|
||||
public string dialogText;
|
||||
public string expression;
|
||||
|
||||
public override string ToString () {
|
||||
return "(" + this.hasDialog + ")" + this.speakerName + "::" + this.dialogText + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//A class to be the variables a text could have
|
||||
[System.Serializable]
|
||||
public class RPGTalkVariable{
|
||||
public string variableName;
|
||||
public string variableValue;
|
||||
}
|
||||
|
||||
//A class to keep any rich text used
|
||||
[System.Serializable]
|
||||
public class RPGTalkRichText{
|
||||
public int lineWithTheRichText;
|
||||
public int initialTagPosition;
|
||||
public string initialTag;
|
||||
public int finalTagPosition;
|
||||
public string finalTag;
|
||||
}
|
||||
|
||||
//A class to keep any sprite used inside the text
|
||||
[System.Serializable]
|
||||
public class RPGTalkSprite{
|
||||
public Sprite sprite;
|
||||
[HideInInspector]
|
||||
public int lineWithSprite = -1;
|
||||
[HideInInspector]
|
||||
public int spritePosition = -1;
|
||||
public float width = 1;
|
||||
public float height = 1;
|
||||
[HideInInspector]
|
||||
public bool alreadyInPlace;
|
||||
public RuntimeAnimatorController animator;
|
||||
}
|
||||
|
||||
//A class to keep any dub used inside the text
|
||||
[System.Serializable]
|
||||
public class RPGTalkDub{
|
||||
public int dubNumber;
|
||||
public int lineWithDub = -1;
|
||||
}
|
||||
|
||||
//A class to keep any speed changes used inside the text
|
||||
[System.Serializable]
|
||||
public class RPGTalkSpeed{
|
||||
public int speed = 0;
|
||||
public int lineWithSpeed = -1;
|
||||
public int speedPosition = -1;
|
||||
public bool alreadyGone;
|
||||
}
|
||||
|
||||
//A class to keep any question used inside the text
|
||||
[System.Serializable]
|
||||
public class RPGTalkQuestion{
|
||||
public string questionID;
|
||||
public int lineWithQuestion = -1;
|
||||
public bool alreadyHappen;
|
||||
public List<string> choices = new List<string>();
|
||||
}
|
||||
|
||||
//A class to keep the targets that the canvas can follow
|
||||
[System.Serializable]
|
||||
public class RPGTalkCharacterSettings{
|
||||
[Tooltip("What is the Character that those settings represent?")]
|
||||
public RPGTalkCharacter character;
|
||||
[Tooltip("Who to follow?")]
|
||||
public Transform follow;
|
||||
|
||||
[Tooltip("If he is following someone, should there be an offset?")]
|
||||
public Vector3 followOffset;
|
||||
|
||||
[Tooltip("The animations should happen in a different Animator than the one set on RPGTalk?")]
|
||||
public Animator animatorOverwrite;
|
||||
}
|
||||
|
||||
public class RPGtalkSaveStatement
|
||||
{
|
||||
public string lineToStart;
|
||||
public string lineToBreak;
|
||||
public string savedData;
|
||||
public int modifier;
|
||||
}
|
||||
|
||||
//A class to keep any jitter used inside the text
|
||||
[System.Serializable]
|
||||
public class RPGTalkJitter
|
||||
{
|
||||
public float angle = 1;
|
||||
public float jitter = 1;
|
||||
public int lineWithJitter = -1;
|
||||
public int jitterPosition = -1;
|
||||
public bool alreadyGone;
|
||||
public int numberOfCharacters = 1;
|
||||
}
|
||||
|
||||
|
||||
}
|
12
Assets/RPGTALK/Scripts/Helpers/RPGTalkHelper.cs.meta
generated
Normal file
12
Assets/RPGTALK/Scripts/Helpers/RPGTalkHelper.cs.meta
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cb075acdefb6c4d54b7021f94f38fcdc
|
||||
timeCreated: 1504966029
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
14
Assets/RPGTALK/Scripts/Helpers/RPGTalkLanguage.cs
Normal file
14
Assets/RPGTALK/Scripts/Helpers/RPGTalkLanguage.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RPGTALK.Localization
|
||||
{
|
||||
[CreateAssetMenu(fileName = "NewLanguage", menuName = "RPGTalk/Language", order = 12)]
|
||||
public class RPGTalkLanguage : ScriptableObject
|
||||
{
|
||||
public string identifier;
|
||||
public bool mainLanguage;
|
||||
public TextAsset[] txts;
|
||||
}
|
||||
}
|
11
Assets/RPGTALK/Scripts/Helpers/RPGTalkLanguage.cs.meta
generated
Normal file
11
Assets/RPGTALK/Scripts/Helpers/RPGTalkLanguage.cs.meta
generated
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d23970c48242454683c72c504048a86
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
473
Assets/RPGTALK/Scripts/Helpers/TMP_Translator.cs
Normal file
473
Assets/RPGTALK/Scripts/Helpers/TMP_Translator.cs
Normal file
@@ -0,0 +1,473 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using RPGTALK.Helper;
|
||||
#if RPGTalk_TMP
|
||||
using TMPro;
|
||||
#endif
|
||||
|
||||
//We may see a lot of "Uncreachable code" warnings if have or don't TMP. Let's desable them for now
|
||||
#pragma warning disable 0162
|
||||
|
||||
namespace RPGTALK.Texts
|
||||
{
|
||||
// This class has the objective of translate any variables that have different names between Unity's regular UI and TMPUGUI.
|
||||
public class TMP_Translator
|
||||
{
|
||||
|
||||
public Text UIText;
|
||||
public bool hasUIText;
|
||||
#if RPGTalk_TMP
|
||||
public TextMeshProUGUI TMPText;
|
||||
#endif
|
||||
public bool errorSetting;
|
||||
|
||||
public TMP_Translator(GameObject obj)
|
||||
{
|
||||
Text isText = obj.GetComponent<Text>();
|
||||
if (isText)
|
||||
{
|
||||
UIText = isText;
|
||||
hasUIText = true;
|
||||
errorSetting = false;
|
||||
return;
|
||||
}
|
||||
|
||||
#if RPGTalk_TMP
|
||||
TextMeshProUGUI isTMP = obj.GetComponent<TextMeshProUGUI>();
|
||||
if (isTMP)
|
||||
{
|
||||
TMPText = isTMP;
|
||||
errorSetting = false;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
errorSetting = true;
|
||||
}
|
||||
|
||||
public void ChangeTextTo(string text)
|
||||
{
|
||||
if (errorSetting)
|
||||
{
|
||||
DebugError();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (UIText != null)
|
||||
{
|
||||
UIText.text = text;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if RPGTalk_TMP
|
||||
|
||||
TMPText.text = text;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public string GetCurrentText()
|
||||
{
|
||||
if (errorSetting)
|
||||
{
|
||||
DebugError();
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
if (UIText != null)
|
||||
{
|
||||
return UIText.text;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if RPGTalk_TMP
|
||||
|
||||
return TMPText.text;
|
||||
#endif
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void DebugError()
|
||||
{
|
||||
Debug.LogError("The object setted on RPGTalk wasn't a Text or a Text Mesh Pro UGUI. Be sure to check RPGTalk Configuration if you wnat to use the later.");
|
||||
}
|
||||
|
||||
|
||||
public void ChangeRichText(bool active)
|
||||
{
|
||||
if (errorSetting)
|
||||
{
|
||||
DebugError();
|
||||
return;
|
||||
}
|
||||
|
||||
if (UIText != null)
|
||||
{
|
||||
UIText.supportRichText = active;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if RPGTalk_TMP
|
||||
|
||||
TMPText.richText = active;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public bool RichText()
|
||||
{
|
||||
if (errorSetting)
|
||||
{
|
||||
DebugError();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (UIText != null)
|
||||
{
|
||||
return UIText.supportRichText;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if RPGTalk_TMP
|
||||
|
||||
return TMPText.richText;
|
||||
#endif
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public void Enabled(bool enable)
|
||||
{
|
||||
if (errorSetting)
|
||||
{
|
||||
DebugError();
|
||||
}
|
||||
|
||||
if (UIText != null)
|
||||
{
|
||||
UIText.enabled = enable;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if RPGTalk_TMP
|
||||
|
||||
TMPText.enabled = enable;
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public bool Enabled()
|
||||
{
|
||||
if (errorSetting)
|
||||
{
|
||||
DebugError();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (UIText != null)
|
||||
{
|
||||
return UIText.enabled;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if RPGTalk_TMP
|
||||
|
||||
return TMPText.enabled;
|
||||
#endif
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public Object GetTextObject()
|
||||
{
|
||||
if (errorSetting)
|
||||
{
|
||||
DebugError();
|
||||
return null;
|
||||
}
|
||||
|
||||
if (UIText != null)
|
||||
{
|
||||
return UIText;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if RPGTalk_TMP
|
||||
|
||||
return TMPText;
|
||||
#endif
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A function that returns if the Object is an acceptable type (Text or TextMeshProUGUI)
|
||||
/// </summary>
|
||||
/// <returns><c>true</c>, if valid type was used, <c>false</c> otherwise.</returns>
|
||||
/// <param name="obj">Object.</param>
|
||||
public static bool IsValidType(GameObject obj)
|
||||
{
|
||||
if (obj.GetComponent<Text>())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#if RPGTalk_TMP
|
||||
if (obj.GetComponent<TextMeshProUGUI>())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A simple function that returns true if the object has a Text Component
|
||||
/// </summary>
|
||||
public static bool IsText(GameObject obj)
|
||||
{
|
||||
if (obj.GetComponent<Text>())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public ITextWithIcon AddTextWithIconComponent(GameObject gameObject)
|
||||
{
|
||||
if (errorSetting)
|
||||
{
|
||||
DebugError();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
if (hasUIText)
|
||||
{
|
||||
return gameObject.AddComponent<TextWithIconSimpleText>();
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public string GetCorrectSpriteLine(string line, ref List<RPGTalkSprite> sprites, ref List<RPGTalkSprite>spritesUsed, int spriteNum, int initialBracket, int finalBracket, int lineWithSprite, string tmpSpriteAtlas)
|
||||
{
|
||||
|
||||
if (hasUIText)
|
||||
{
|
||||
|
||||
//Neat, we definely have a sprite with a valid number. Time to keep track of it
|
||||
RPGTalkSprite newSprite = new RPGTalkSprite();
|
||||
newSprite.sprite = sprites[spriteNum].sprite;
|
||||
newSprite.width = sprites[spriteNum].width;
|
||||
newSprite.height = sprites[spriteNum].height;
|
||||
newSprite.spritePosition = initialBracket;
|
||||
//Make sure that the the sprite only work for that next line to be added to RpgTalkElements
|
||||
//newSprite.lineWithSprite = rpgtalkElements.Count;
|
||||
newSprite.lineWithSprite = lineWithSprite;
|
||||
newSprite.animator = sprites[spriteNum].animator;
|
||||
|
||||
spritesUsed.Add(newSprite);
|
||||
|
||||
//Looking good! We found out that a sprite should be there and we are already keeping track of it
|
||||
//But now we should remove the [sprite=X] from the line.
|
||||
//The magic here is that we will replace it with the <color=#00000000> tag and the content will be
|
||||
//a text with the length of the sprite's width. So in fact there will be text in there so the next word
|
||||
//will have the right margin, but the text will be invisible so the sprite can take its place
|
||||
string filledText = "";
|
||||
for (int i = 0; i < Mathf.CeilToInt(newSprite.width); i++)
|
||||
{
|
||||
//The letter "S" is used to fill because in most fonts the letter S occupies a perfect character square
|
||||
filledText += "S";
|
||||
}
|
||||
|
||||
if (finalBracket == line.Length - 1)
|
||||
{
|
||||
//if the sprite was the last thing on the text, we should place an empty space to align correctly the vertexes
|
||||
filledText += "SS";
|
||||
}
|
||||
return line.Substring(0, initialBracket) +
|
||||
"<color=#00000000>" + filledText + "</color>" +
|
||||
line.Substring(finalBracket + 1);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
#if RPGTalk_TMP
|
||||
|
||||
//if we are using TMP, everything is easier. We just need to make the text says <sprite=X index=Y> and let TMP's components do the rest
|
||||
return line.Substring(0, initialBracket) +
|
||||
"<sprite=\"" + tmpSpriteAtlas + "\" index="+spriteNum+">" +
|
||||
line.Substring(finalBracket + 1);
|
||||
#endif
|
||||
return line;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Structure to hold pre-computed animation data.
|
||||
/// </summary>
|
||||
private struct VertexAnim
|
||||
{
|
||||
public float angleRange;
|
||||
public float angle;
|
||||
public float speed;
|
||||
}
|
||||
|
||||
//Jitters the part of the text
|
||||
public IEnumerator Jitter(RPGTalkJitter jitter)
|
||||
{
|
||||
#if RPGTalk_TMP
|
||||
if(TMPText == null)
|
||||
{
|
||||
Debug.LogError("Only TextMeshPro users can use the Jitter Tag");
|
||||
yield return null;
|
||||
}
|
||||
|
||||
|
||||
TMP_TextInfo textInfo = TMPText.textInfo;
|
||||
// Cache the vertex data of the text object as the Jitter FX is applied to the original position of the characters.
|
||||
TMP_MeshInfo[] cachedMeshInfo = textInfo.CopyMeshInfoVertexData();
|
||||
int characterCount = textInfo.characterCount;
|
||||
|
||||
// Create an Array which contains pre-computed Angle Ranges and Speeds for a bunch of characters.
|
||||
VertexAnim[] vertexAnim = new VertexAnim[1024];
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
vertexAnim[i].angleRange = Random.Range(10f, 25f);
|
||||
vertexAnim[i].speed = Random.Range(1f, 3f);
|
||||
}
|
||||
|
||||
int loopCount = 0;
|
||||
|
||||
Matrix4x4 matrix;
|
||||
|
||||
while (true)
|
||||
{
|
||||
int repeatUntil = jitter.jitterPosition + jitter.numberOfCharacters;
|
||||
|
||||
|
||||
// yield until we have all the characters in the jitter
|
||||
while (characterCount < repeatUntil)
|
||||
{
|
||||
|
||||
// Update the copy of the vertex data for the text object.
|
||||
cachedMeshInfo = textInfo.CopyMeshInfoVertexData();
|
||||
characterCount = textInfo.characterCount;
|
||||
|
||||
|
||||
yield return new WaitForEndOfFrame();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
for (int i = jitter.jitterPosition; i < repeatUntil; i++)
|
||||
{
|
||||
TMP_CharacterInfo charInfo = textInfo.characterInfo[i];
|
||||
|
||||
// Skip characters that are not visible and thus have no geometry to manipulate.
|
||||
if (!charInfo.isVisible)
|
||||
continue;
|
||||
|
||||
// Retrieve the pre-computed animation data for the given character.
|
||||
VertexAnim vertAnim = vertexAnim[i];
|
||||
|
||||
// Get the index of the material used by the current character.
|
||||
int materialIndex = textInfo.characterInfo[i].materialReferenceIndex;
|
||||
|
||||
// Get the index of the first vertex used by this text element.
|
||||
int vertexIndex = textInfo.characterInfo[i].vertexIndex;
|
||||
|
||||
// Get the cached vertices of the mesh used by this text element (character or sprite).
|
||||
Vector3[] sourceVertices = cachedMeshInfo[materialIndex].vertices;
|
||||
|
||||
// If we dont have the vertices yet, don't do it
|
||||
if (sourceVertices.Length < vertexIndex+3)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Determine the center point of each character at the baseline.
|
||||
//Vector2 charMidBasline = new Vector2((sourceVertices[vertexIndex + 0].x + sourceVertices[vertexIndex + 2].x) / 2, charInfo.baseLine);
|
||||
// Determine the center point of each character.
|
||||
Vector2 charMidBasline = (sourceVertices[vertexIndex + 0] + sourceVertices[vertexIndex + 2]) / 2;
|
||||
|
||||
// Need to translate all 4 vertices of each quad to aligned with middle of character / baseline.
|
||||
// This is needed so the matrix TRS is applied at the origin for each character.
|
||||
Vector3 offset = charMidBasline;
|
||||
|
||||
Vector3[] destinationVertices = textInfo.meshInfo[materialIndex].vertices;
|
||||
|
||||
destinationVertices[vertexIndex + 0] = sourceVertices[vertexIndex + 0] - offset;
|
||||
destinationVertices[vertexIndex + 1] = sourceVertices[vertexIndex + 1] - offset;
|
||||
destinationVertices[vertexIndex + 2] = sourceVertices[vertexIndex + 2] - offset;
|
||||
destinationVertices[vertexIndex + 3] = sourceVertices[vertexIndex + 3] - offset;
|
||||
|
||||
vertAnim.angle = Mathf.SmoothStep(-vertAnim.angleRange, vertAnim.angleRange, Mathf.PingPong(loopCount / 25f * vertAnim.speed, 1f));
|
||||
Vector3 jitterOffset = new Vector3(Random.Range(-.25f, .25f), Random.Range(-.25f, .25f), 0);
|
||||
|
||||
matrix = Matrix4x4.TRS(jitterOffset * jitter.jitter, Quaternion.Euler(0, 0, Random.Range(-5f, 5f) * jitter.angle), Vector3.one);
|
||||
|
||||
destinationVertices[vertexIndex + 0] = matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 0]);
|
||||
destinationVertices[vertexIndex + 1] = matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 1]);
|
||||
destinationVertices[vertexIndex + 2] = matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 2]);
|
||||
destinationVertices[vertexIndex + 3] = matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 3]);
|
||||
|
||||
destinationVertices[vertexIndex + 0] += offset;
|
||||
destinationVertices[vertexIndex + 1] += offset;
|
||||
destinationVertices[vertexIndex + 2] += offset;
|
||||
destinationVertices[vertexIndex + 3] += offset;
|
||||
|
||||
vertexAnim[i] = vertAnim;
|
||||
}
|
||||
|
||||
// Push changes into meshes
|
||||
for (int i = 0; i < textInfo.meshInfo.Length; i++)
|
||||
{
|
||||
textInfo.meshInfo[i].mesh.vertices = textInfo.meshInfo[i].vertices;
|
||||
TMPText.UpdateGeometry(textInfo.meshInfo[i].mesh, i);
|
||||
}
|
||||
|
||||
loopCount += 1;
|
||||
|
||||
yield return new WaitForSeconds(0.1f);
|
||||
}
|
||||
#else
|
||||
|
||||
Debug.LogError("Only TextMeshPro users can use the Jitter Tag");
|
||||
yield return null;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore 0162
|
11
Assets/RPGTALK/Scripts/Helpers/TMP_Translator.cs.meta
generated
Normal file
11
Assets/RPGTALK/Scripts/Helpers/TMP_Translator.cs.meta
generated
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b987b78358ffd4b18baae9bb70dff324
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
24
Assets/RPGTALK/Scripts/Helpers/TextWithIcon.cs
Normal file
24
Assets/RPGTALK/Scripts/Helpers/TextWithIcon.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace RPGTALK.Texts
|
||||
{
|
||||
|
||||
public interface ITextWithIcon
|
||||
{
|
||||
Image icon { get; set; }
|
||||
Vector3 iconPosition { get; set; }
|
||||
List<Image> icons { get; set; } //= new List<Image>();
|
||||
List<int> indexes { get; set; }
|
||||
RPGTalk rpgtalk { get; set; }
|
||||
|
||||
void RepopulateImages();
|
||||
|
||||
bool FitImagesOnText(int y);
|
||||
|
||||
|
||||
}
|
||||
}
|
12
Assets/RPGTALK/Scripts/Helpers/TextWithIcon.cs.meta
generated
Normal file
12
Assets/RPGTALK/Scripts/Helpers/TextWithIcon.cs.meta
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 61423d107b3ca4062a1aa4fa912c83c7
|
||||
timeCreated: 1504879243
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
122
Assets/RPGTALK/Scripts/Helpers/TextWithIconSimpleText.cs
Normal file
122
Assets/RPGTALK/Scripts/Helpers/TextWithIconSimpleText.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using RPGTALK.Helper;
|
||||
|
||||
namespace RPGTALK.Texts
|
||||
{
|
||||
[AddComponentMenu("Seize Studios/RPGTalk/Helper/Text With Icon")]
|
||||
public class TextWithIconSimpleText : Text , ITextWithIcon
|
||||
{
|
||||
public Image icon { get { return _icon; } set { _icon = value; } }
|
||||
Image _icon;
|
||||
public Vector3 iconPosition { get { return _iconPosition; } set { _iconPosition = value; } }
|
||||
Vector3 _iconPosition;
|
||||
public List<Image> icons { get { return _icons; } set { _icons = value; } }
|
||||
List<Image> _icons = new List<Image>();
|
||||
public List<int> indexes { get { return _indexe; } set { _indexe = value; } }
|
||||
List<int> _indexe;
|
||||
public RPGTalk rpgtalk { get { return _rpgtalk; } set { _rpgtalk = value; } }
|
||||
RPGTalk _rpgtalk;
|
||||
|
||||
|
||||
public void RepopulateImages()
|
||||
{
|
||||
foreach (Image childImage in icons)
|
||||
{
|
||||
//Destroy every ancient image that might be left standing from previous talks
|
||||
if (childImage)
|
||||
{
|
||||
DestroyImmediate(childImage.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
//new icons, new indexes and new positions
|
||||
icons = new List<Image>();
|
||||
indexes = new List<int>();
|
||||
|
||||
foreach (RPGTalkSprite sprite in rpgtalk.spritesUsed)
|
||||
{
|
||||
//for each sprites in this talk, let's create an Image.
|
||||
GameObject newGo = new GameObject();
|
||||
Image newImg = newGo.AddComponent<Image>();
|
||||
newImg.sprite = sprite.sprite;
|
||||
newGo.transform.SetParent(transform);
|
||||
icons.Add(newImg);
|
||||
|
||||
//if it has an animator, put it
|
||||
if (sprite.animator)
|
||||
{
|
||||
newGo.AddComponent<Animator>().runtimeAnimatorController = sprite.animator;
|
||||
}
|
||||
|
||||
//We don't want it to appear right from the start
|
||||
newGo.SetActive(false);
|
||||
|
||||
//Where this sprite should appear? Width/2 because each width a new character is put.
|
||||
//That way the image will be put right in the middle.
|
||||
indexes.Add(sprite.spritePosition + Mathf.CeilToInt(sprite.width / 2));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPopulateMesh(VertexHelper toFill)
|
||||
{
|
||||
base.OnPopulateMesh(toFill);
|
||||
}
|
||||
|
||||
public bool FitImagesOnText(int y)
|
||||
{
|
||||
|
||||
//Check the right position/size of text, considering that canvas could be Scale With Screen Size
|
||||
Vector2 textAnchorPivot = GetTextAnchorPivot(alignment);
|
||||
Vector2 refPoint = Vector2.zero;
|
||||
refPoint.x = (textAnchorPivot.x == 1 ? rectTransform.rect.xMax : rectTransform.rect.xMin);
|
||||
refPoint.y = (textAnchorPivot.y == 0 ? rectTransform.rect.yMin : rectTransform.rect.yMax);
|
||||
Vector2 roundingOffset = PixelAdjustPoint(refPoint) - refPoint;
|
||||
float unitsPerPixel = 1 / pixelsPerUnit;
|
||||
|
||||
//var textGen = cachedTextGenerator;
|
||||
|
||||
//The position of the image on the text. It will be plus 16 because it will come after <color=#00000000>.
|
||||
//The width is mesured in characters, so, whatever characters it may have on width, the middle will be this number/2.
|
||||
int position = rpgtalk.spritesUsed[y].spritePosition + 16 + Mathf.CeilToInt(rpgtalk.spritesUsed[y].width / 2);
|
||||
|
||||
//If the cached text generator still doesn't have this character... we are not ready to place the image
|
||||
if (cachedTextGenerator.characters.Count <= position)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//Each character occupies 4 verts
|
||||
Vector2 locUpperLeft = new Vector2(cachedTextGenerator.verts[position * 4].position.x, cachedTextGenerator.verts[position * 4].position.y) * unitsPerPixel;
|
||||
locUpperLeft.x += roundingOffset.x;
|
||||
locUpperLeft.y += roundingOffset.y;
|
||||
|
||||
Vector2 locBottomRight = new Vector2(cachedTextGenerator.verts[position * 4 + 2].position.x, cachedTextGenerator.verts[position * 4 + 2].position.y) * unitsPerPixel;
|
||||
locBottomRight.x += roundingOffset.x;
|
||||
locBottomRight.y += roundingOffset.y;
|
||||
|
||||
//The middle of the character should be its corners /2
|
||||
Vector3 mid = (locUpperLeft + locBottomRight) / 2;
|
||||
//If the size would be important...
|
||||
//Vector3 size = locBottomRight - locUpperLeft;
|
||||
|
||||
//The font height and width based on the distance between the characters
|
||||
float _fontHeight = Vector3.Distance(cachedTextGenerator.verts[position * 4].position, cachedTextGenerator.verts[position * 4 + 2].position);
|
||||
float _fontWidth = Vector3.Distance(cachedTextGenerator.verts[position * 4].position, cachedTextGenerator.verts[position * 4 + 1].position);
|
||||
if (_fontWidth == 0 || _fontHeight == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//Finally! Activate the image and put it in the middle position, also change its size based on character height and width
|
||||
icons[y].gameObject.SetActive(true);
|
||||
icons[y].rectTransform.localPosition = mid;
|
||||
icons[y].rectTransform.sizeDelta = new Vector2(_fontWidth * rpgtalk.spritesUsed[y].width, _fontHeight * rpgtalk.spritesUsed[y].height);
|
||||
icons[y].rectTransform.localScale = new Vector3(1, 1, 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/RPGTALK/Scripts/Helpers/TextWithIconSimpleText.cs.meta
generated
Normal file
11
Assets/RPGTALK/Scripts/Helpers/TextWithIconSimpleText.cs.meta
generated
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c95432bd70d846dd8c8a11be6911244
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user