Revert "Musik Anderswelt & Effekte"

This reverts commit 574b404c2d
This commit is contained in:
Luca Wey
2023-06-07 11:42:40 +02:00
parent 574b404c2d
commit c7940aa8ea
1062 changed files with 181139 additions and 0 deletions

View 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;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d46921e71e9f04ccb83ec685be24573c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}

View 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:

View 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;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5d23970c48242454683c72c504048a86
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b987b78358ffd4b18baae9bb70dff324
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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);
}
}

View 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:

View 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;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3c95432bd70d846dd8c8a11be6911244
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: