Skip to content

Unity Extensibility

Mayuki Sawatari edited this page Nov 26, 2015 · 3 revisions

拡張方法

LetterWriterText コンポーネントを継承したコンポーネントを作る

LetterWriterExtensibilityProvider コンポーネントを継承して貼り付ける

パーサーとテキストフォーマッターを差し替えることのできる仕組みを用意しているので、そのコンポーネントを使って差し替えることでカスタム実装を差し込めます。

LetterWriterExtensibilityProvider コンポーネントを継承したコンポーネントを作って、下記のメンバーを適当にオーバーライドして適当に返します。

  • CreateMarkupParser
  • CreateTextFormatter

そして何らかのオブジェクトに貼り付け、LetterWriterText コンポーネントの ExtensibilityProvider プロパティに差し込みます。

pyonpyon 要素を作って、心ぴょんぴょん可能なテキストを生成する雑な例

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LetterWriter;
using LetterWriter.Markup;
using LetterWriter.Unity;
using LetterWriter.Unity.Components;
using LetterWriter.Unity.Markup;
using UnityEngine;

namespace Assets.Scripts.Components.Test12
{
    public class CustomLetterWriterExtensibilityProvider : LetterWriterExtensibilityProvider
    {
        public override LetterWriterMarkupParser CreateMarkupParser()
        {
            return new CustomMarkupParser();
        }

        public override TextFormatter CreateTextFormatter(Font font, int fontSize, Color color)
        {
            return new CustomTextFormatter(font, fontSize, color);
        }

        protected void Update()
        {
            this.GetComponent<LetterWriterText>().MarkAsRebuildRequired();
        }
    }

    public class CustomMarkupParser : UnityMarkupParser
    {
        protected override TextRun[] VisitMarkupElement(Element element, string tagNameUpper)
        {
            if (tagNameUpper == "PYONPYON")
            {
                return
                    new TextRun[] { new CustomTextModifier() }
                    .Concat(base.VisitMarkupElement(element, tagNameUpper))
                    .Concat(new TextRun[] { new TextEndOfSegment() })
                    .ToArray();
            }

            return base.VisitMarkupElement(element, tagNameUpper);
        }
    }

    public class CustomTextModifier : UnityTextModifier
    {
    }

    public class CustomTextModifierScope : UnityTextModifierScope
    {
        public CustomTextModifierScope(UnityTextModifierScope parent, UnityTextModifier textModifier) : base(parent, textModifier)
        {
        }
    }

    public class CustomTextFormatter : UnityTextFormatter
    {
        public CustomTextFormatter(Font font, int fontSize, Color color) : base(font, fontSize, color)
        {
        }

        public override TextModifierScope CreateTextModifierScope(TextModifierScope parent, TextModifier textModifier)
        {
            if (textModifier is CustomTextModifier)
            {
                return new CustomTextModifierScope((UnityTextModifierScope)parent, (UnityTextModifier)(textModifier ?? this.CreateDefaultTextModifier()));
            }
            else
            {
                return base.CreateTextModifierScope(parent, textModifier);
            }
        }

        public override GlyphPlacement CreateGlyphPlacement(TextModifierScope currenTextModifierScope, IGlyph glyph, int x, int y, int index, int indexInTextRun, int textRunLength)
        {
            if (currenTextModifierScope is CustomTextModifierScope)
            {
                return new CustomGlyphPlacement(glyph, x, y, index, indexInTextRun, textRunLength);
            }
            else
            {
                return base.CreateGlyphPlacement(currenTextModifierScope, glyph, x, y, index, indexInTextRun, textRunLength);
            }
        }
    }

    public class CustomGlyphPlacement : GlyphPlacement
    {
        public int IndexInTextRun { get; set; }
        public int TextRunLength { get; set; }

        private int _y;
        public override int Y
        {
            get
            {
                var t = (int)(Time.time * 10);
                var isUp = (t % this.TextRunLength) == this.IndexInTextRun;

                return this._y - (isUp ? this.Glyph.Height / 2 : 0);
            }
            set { this._y = value; }
        }


        public CustomGlyphPlacement(IGlyph glyph, int x, int y, int index, int indexInTextRun, int textRunLength) : base(glyph, x, y, index)
        {
            this.IndexInTextRun = indexInTextRun;
            this.TextRunLength = textRunLength;
        }
    }
}