読者です 読者をやめる 読者になる 読者になる

Excelから翻訳データを読み込んでTextに突っ込むTranslateManagerを作った

Unity c#

タイトルでだいたい説明した感じですが、ポイントとしては、

  • TagProcessorクラスを介することでタグ解釈ができる(後述)
  • UnityEngine.UI.Textのtextに$$で始まるキーを入れておくと、対応する訳を入れてくれる
  • Resources.FindObjectsOfTypeAll()でヒエラルキーをなめて、Textに翻訳データをぶち込む

といった感じです。

さっそくですがサンプルプロジェクトを以下に置きました。(Unity version 5.3.5f1 )
github.com


以下、説明していきます。
TranslateManagerのソースはこのようになっています。(今は日本語と英語だけに対応しています。)

using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
using System.Xml;

public class TranslateText {
    public string jp;
    public string eng;
    public TranslateText( string jp_, string eng_ )
    {
        jp  = jp_;
        eng = eng_;
    }
}

public class TranslateManager : Singleton< TranslateManager > {
    private Dictionary<string, TranslateText> texts = new Dictionary<string, TranslateText>();

    ITagProcessor tagProcessor = null;

    //------------------------------------------------------------------------------
    //Resourceフォルダ以下にあるExcelデータを読み込む
    public void Read( string path )
    {
        TextAsset text_asset = Resources.Load<TextAsset>(path);
        Debug.Assert( text_asset != null );

        XmlDocument xmldoc = new XmlDocument ();
        xmldoc.LoadXml ( text_asset.text );

        var nsmgr = new XmlNamespaceManager(xmldoc.NameTable);
        nsmgr.AddNamespace("ss", "urn:schemas-microsoft-com:office:spreadsheet");

        XmlNodeList rows = xmldoc.GetElementsByTagName("Row");

        foreach (XmlNode row in rows){
            XmlNodeList datas = row.SelectNodes("ss:Cell/ss:Data", nsmgr);

            string key = datas[0].InnerText;
            string jp  = datas[1].InnerText;
            string eng = datas[2].InnerText;

            //改行コードを変換する
            //手元のExcelを使ってxml形式で保存すると改行が\r(CR)になっているので、
            //それを変換する
            jp = jp.Replace( "\r", "\n" );
            eng = eng.Replace( "\r", "\n" );

            texts[ key ] = new TranslateText( jp, eng );
        }
    }


    //------------------------------------------------------------------------------
    //ヒエラルキーにあるテキスト仕込んだキーから変換
	public void ApplyAllUIText()
	{
        Text[] text_components = Resources.FindObjectsOfTypeAll<Text>();
        for (var i = 0; i < text_components.Length; ++i) {
            InterpretText( ref text_components[i] );
        }
	}

    //------------------------------------------------------------------------------
    //タグプロセッサーを設定
	public void SetTagProcessor( ITagProcessor processor )
    {
        tagProcessor = processor;
    }

    //------------------------------------------------------------------------------
    //キーからテキスト取得
    public string GetText( string key )
    {
        string str = getTextRaw(key);
        if( tagProcessor != null )
        {
            str = tagProcessor.Process( str );
        }
        return str;
    }

    //------------------------------------------------------------------------------
    //Textクラスを与えて、キーが入ってたら翻訳データを挿入
    public void InterpretText( ref Text t )
    {
        if( t.text.StartsWith( "$$" ) )
        {
            string key = t.text.Substring(2).TrimEnd();//たまに間違って改行が入っている場合があって気づきにくいのでTrimEndしておく
            t.text = GetText( key );
        }
    }

    //------------------------------------------------------------------------------
    //タグ解釈していない、そのままのテキスト取得
    private string getTextRaw( string key )
    {
        // Debugしやすいように Application.systemLanguage を直接見ずにConfigというクラス経由で参照
        if( Config.Language == SystemLanguage.Japanese )
        {
            return texts[key].jp;
        }
        else
        {
            return texts[key].eng;
        }
    }
}

Excelの翻訳データはこんな感じになっています。1列目がキー、2列目が日本語訳、3列目が英語訳です。

f:id:wkpn:20160728113451p:plain

使い方としては、Editor上で、こんな感じで$$から始まるキーを打ち込んでおきます。

f:id:wkpn:20160728113930p:plain

そんで、ゲームが起動した直後に、

    tagProcessor = new TagProcessor();//タグプロセッサー作成
    TranslateManager.Instance.SetTagProcessor( tagProcessor );//タグプロセッサー設定
    TranslateManager.Instance.Read( "Text/texts" );//Resourcesから読み込む
    TranslateManager.Instance.ApplyAllUIText();//ヒエラルキーにある全Textに適用する

としておくと、

このように、対応した翻訳データに置き換わります。

f:id:wkpn:20160728121837p:plain

また、Scriptで直接キーを指定して翻訳データをとってきたい場合には、

 string text = TranslateManager.Instance.GetText( "1001" ); 

っとすることで取得できます。

TagProcessorとは?

先ほどのExcelデータの中で、#{MovieAward}っとなっている部分がタグです。

ゲームを作っていると文字列の中に変数を埋め込みたい時があります。

例えば、動画を見た時にコインをゲットできるけど、そのコイン枚数はレベルによって変わる。っという場合を考えてみます。

単純に考えると、レベルの数だけ文章を用意すれば良いということになります。すると、

  • 10枚コインゲット!, You got 10 coins!
  • 20枚コインゲット!, You got 20 coins!
  • 40枚コインゲット!, You got 40 coins!
  • ...

っと大量の翻訳データが必要になってしまいます。

それを、解決してくれるのがTagProcessorです。Excel

 Key  |  #{MovieAward}枚コインゲット!  |  You got #{MovieAward} coins!

と書いておき、TagProcessorの中で以下のように記述しておきます。

public class TagProcessor : ITagProcessor {
    protected int movieAward;

    public void SetMoviewAward( int award )
    {
        movieAward = award;
    }

    //タグを処理する
    public string Process( string text )
    {
        const string cTagWatchingMovieAward = "#{MovieAward}";

        if( text.Contains( cTagWatchingMovieAward ) )
        {
            //タグを置き換える
            text = text.Replace( cTagWatchingMovieAward, movieAward.ToString() );
        }

        return text;
    }
}

そして、TagProcessorに与える予定の枚数をSetMoviewAwardで与えておいて、

TranslateManager.Instance.GetText( Key )

っとすると、状況に応じた枚数の入った文章をゲットすることができます。

ちなみに、ITagProcessorの中身はこれだけです。

using UnityEngine;
using System.Collections;

public interface ITagProcessor {
    string Process( string text );
}


上記を利用して作ったアプリです!良かったらダウンロードお願いします!

Make 10 by using 4 numbers

Make 10 by using 4 numbers

  • Ken Watanabe
  • ゲーム
  • 無料
play.google.com