code ソーシャル

Unityアプリcodetips(33)

スポンサーリンク

//tips

//spriteAtlasの使用

コルーチンで画像を切り替えるために、切り替える画像をパッケージ化できるspriteAtlasを使用する。

また、パッケージすることにより処理が軽くなるなどの利点もある。

SpriteAtlasはプロジェクトビューのCreate - Sprite Atlasからファイルを作成できる。

パックするため生成したSpriteAtlasのObjects for PackingにパックしたいSpriteを指定する。

sprite editorで大元の画像を加工したら、加工画像と別途に大元の画像を再度Unityに読み込んでおく必要がある。

パックしたい部品分のspriteが必要となる。

Unity 2019.2のSprite Editor立ち上げについて

https://docs.unity3d.com/ja/2018.4/Manual/SpriteAtlasWorkflow.html

//imageとSprite Rendererの違い

双方とも2Dの絵を表示するが違いがある。

Sprite Rendererは、自身でアセットを描画する機能を持っており、Sprite(アセット)に設定したポリゴン情報を元に、描画する。

Imageは、CanvasRendererとCanvasとの組み合わせで描画する機能で、Sprite(アセット)に指定したTextureとUV情報を元に描画を行う。

なので、型が分かれている。

ちなみに、Textureは画像。正確には「グラフィックを示すビットマップ」とその画像の情報。
「1ピクセル目は○色。2ピクセル目は○色。……」という画像の内容と、ファイル形式などのデータを持つ。

SpriteはTextureファイルのこの部分を実際に使用すると指定する為のクラス。

基本的にTexture=Spriteだが、複数の画像をパックにしてアトラス化した場合、1つのTextureファイルから複数のSpriteを作成することになる。

//imageコンポーネントを使用した画像切り替え

spriteAtlasを利用して画像表示しようとしたがうまくできなかったので基本に立ち返り、imageでの画像表示から行う。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// UI処理のクラスを使用する宣言
using UnityEngine.UI;

public class SpriteChange : MonoBehaviour
{
// Image コンポーネントを格納する変数
private Image m_Image;
// スプライトオブジェクトを格納する配列
public Sprite[] m_Sprite;
// スプライトオブジェクトを変更するためのフラグ
bool Change;

// ゲーム開始時に実行する処理
void Start()
{
// スプライトオブジェクトを変更するためのフラグを false に設定
Change = false;
// Image コンポーネントを取得して変数 m_Image に格納
m_Image = GetComponent<Image>();
}

// ゲーム実行中に毎フレーム実行する処理
void Update()
{
// スペースキーが押された場合
if (Input.GetKeyDown(KeyCode.Space))
{
// スプライトオブジェクトの変更フラグが true の場合
if (Change)
{
// スプライトオブジェクトの変更
//(配列 m_Sprite[0] に格納したスプライトオブジェクトを変数 m_Image に格納したImage コンポーネントに割り当て)
m_Image.sprite = m_Sprite[0];
Change = false;
}
// スプライトオブジェクトの変更フラグが false の場合
else
{
// スプライトオブジェクトの変更
//(配列 m_Sprite[1] に格納したスプライトオブジェクトを変数 m_Image に格納したImage コンポーネントに割り当て)
m_Image.sprite = m_Sprite[1];
Change = true;
}
}
}
}

これにコルーチンを追加して文字同様クリックしたら変化にする。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// UI処理のクラスを使用する宣言
using UnityEngine.UI;

public class SpriteChange : MonoBehaviour
{
// Image コンポーネントを格納する変数
private Image m_Image;
// スプライトオブジェクトを格納する配列
public Sprite[] m_Sprite;
// スプライトオブジェクトを変更するためのフラグ

// ゲーム開始時に実行する処理
IEnumerator Start()
{
m_Image = GetComponent<Image>();

m_Image.sprite = m_Sprite[0];
yield return new WaitUntil(() => Input.GetMouseButtonDown(0));
yield return null;

m_Image = GetComponent<Image>();
m_Image.sprite = m_Sprite[1];
yield return new WaitUntil(() => Input.GetMouseButtonDown(0));
yield return null;

m_Image = GetComponent<Image>();
m_Image.sprite = m_Sprite[2];

 

}
}

さらに顔の部分のimageと体の部分のimageとを分けることで切り替え時に変化をおこすことができる。

//UI-textの文字送り設定

まずはUIからPanelを作成。一緒に作成されるcanvasをscale with screen、match modeをexpandに設定。

その際reference resolutionを覚えておき、Panelのアンカーを中央に設定した後、同じ値をwidth, heightに入れる。

Reference Resolution では、レイアウトの基準となる解像度を指定。異なる解像度の端末で動かした場合、この解像度を基準としてパーツの比率が変更される。
Screen Match Mode では、解像度の違いをどのように吸収するかを選択する。

Panelの下にサイズを合わせたimageをおき、その下にtextを配置する。textは位置を整え、アンカーを全画面表示に変更。

Textに表示させる文字をpublic string[] scenarios; の中に入れ込み、uiText.text = scenarios[currentLine];でcurrentLineの数値変化に伴い、表示されるシナリオが変わるようにする。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using UnityEngine.UI; // uGUIの機能を使うお約束

public class TextController2 : MonoBehaviour
{
public string[] scenarios; // シナリオを格納する
public Text uiText; // uiTextへの参照を保つ

int currentLine = 0; // 現在の行番号

void Start()
{
TextUpdate();
}

void Update()
{
// 現在の行番号がラストまで行ってない状態でクリックすると、テキストを更新する
if (currentLine < scenarios.Length && Input.GetMouseButtonDown(0))
{
TextUpdate();
}
}

// テキストを更新する
void TextUpdate()
{
// 現在の行のテキストをuiTextに流し込み、現在の行番号を一つ追加する
uiText.text = scenarios[currentLine];
currentLine++;
}
}

文字を一文字ずつ順番に表示させるには、
・想定終了時間を設定
・現在時刻がその何%程度進んだか
で判定したものをString.Substringで表示処理する。

抜き出す文字列の開始文字位置と抜き出す文字列の文字数を指定できる。文字数を省略すると文の末尾までになる。

using System;

namespace Sample
{
class Sample
{
static void Main()
{
string str = “アイウエオカキ”;
Console.WriteLine(str.Substring(0, 1));
Console.WriteLine(str.Substring(1, 5));
Console.WriteLine(str.Substring(6));

Console.ReadKey();
}
}
}
とするとString.Substringにより


イウエオカ

が抜き出されることになる。

scenarios.Lengthで要素数をとっているので、SetNextLine()を通し、currentLineは1から始めさせる。

文字数カウントlastUpdateCharacter = -1;は、String.Substringの文字数に関係し、初期時点で何も表示させず、updateの中でdisplayCharacterCount != lastUpdateCharacter を成り立たせるために-1とする。

まず
void Start()
{
SetNextLine();
}
でSetNextLineメソッドに飛ばす。

currentText = scenarios[currentLine];でscenarios[0]を表示文章にセット。
currentLine ++;で一文目の表示が始まったことをセット。

文字の数×一文字ごとの表示時間つまり文の想定表示時間を計算
timeUntilDisplay = currentText.Length * intervalForCharacterDisplay;

想定表示時間と比べるために時刻をセット。
timeElapsed = Time.time;

次の文に移る際にdisplayCharacterCount != lastUpdateCharacterを成り立たせる必要があるので

lastUpdateCharacter = -1;

で初期化。

次にUpdate () メソッドの中に入る。

シナリオ文の数がシナリオ文の要素数の総計より少なく、かつ、クリックされた場合、

currentLine < scenarios.Length && Input.GetMouseButtonDown(0)

SetNextLine();へ移行。

もし全シナリオ表示済み、または、クリックされていなければ、

現時刻-開始時刻で経過時間を算出、それを想定終了時間でわり、何割分経過しているかを確認。それを文のそう文字数にかけることで表示可能文字数を計算。

int displayCharacterCount = (int)(Mathf.Clamp01((Time.time - timeElapsed) / timeUntilDisplay) * currentText.Length);

表示可能文字数が前回記録した表示可能文字数と異なる場合、つまり、文章が全て表示され終わっている場合を除くとき、
displayCharacterCount != lastUpdateCharacter

テキストに対して、セットされたシナリオ文章の最初から計算された文字数までを表示し、

uiText.text = currentText.Substring(0, displayCharacterCount);

表示した文字数を前回記録として記録する。
lastUpdateCharacter = displayCharacterCount;

人気の記事

1

皆さん、ついに、エアラインでも、サブスクリプションが始まったのはご存じですか? まだ実験段階ですが、ANAが、定額全国住み放題サービスを提供する「ADDress」と組んで、国内線を4回まで定額利用可能 ...

2

無料でネットショップを開けるアプリとして多くの人に驚きを与えたBASE株式会社が、2019年10月25日東証マザーズに上場しました。2020年2月時点で90万店を超えるショップを抱えるまでに成長してい ...

3

2011年にサービスを開始してから圧倒的な成長率を誇るインテリア通販サイト 【FLYMEe/フライミー】を皆さんご存じでしょうか。 「自分のイメージするインテリア、本当に欲しいインテリアがどこにあるの ...

4

ついに、noteの月間アクティブユーザー数が4400万人(2020年3月時点)に到達しました。 そもそも、「note」とは、クリエイターが、文章やマンガ、写真、音声を投稿することができ、ユーザーはその ...

5

ボードゲームカフェが1日2回転で儲かるという記事をみつけたので興味を持ち、調べてみました。 まずは、需要がどれくらいあるのか、市場のようすからみていきましょう。 世界最大のボードゲーム市場はドイツで、 ...

-code, ソーシャル
-,

Copyright© BUSINESS HUNTER , 2023 All Rights Reserved Powered by AFFINGER5.