スクラッチからUnityへシフトアップ
第二回目の今回は「見た目」偏です。
Unityで見た目を管理するには「UI」という機能が必須です。コスチューム変更はアニメーション機能を使うと便利です。
こんにちは!と言う
Unityで文字を表示させる方法は次の2つがあります。
Debug.Logメソッドを使って、Consoleに表示
Text などの UI を使ってScene上に表示
スクラッチと同じように、キャラクターにしゃべらせるには、UIを使うのが良いでしょう。
1,Consoleに表示
Debug.Logメソッドはプログラムの動きを確認したり、バグを検出するときに使用します。シーン上には表示されません。
Debug.Log("こんにちは!");
2,シーン(ステージ)上に表示
事前準備として、しゃべらせたいキャラクターの子要素にUI の Text を配置します。
Inspector の RectTransformコンポーネントではキャラクターに対する相対的な座標、Textの幅、高さなどを指定します。
Textコンポーネントではフォントサイズ、フォントスタイル、整列位置などを指定します。
UIツールを使用するには、NameSpace と呼ばれるスクリプトファイルの上部で以下のようにUIを使用する宣言をします。尚、このスクリプトファイルは発言する対象(サンプルではCat)にアタッチします。
using UnityEngine.UI;
次にUI の Text コンポーネント型の変数の宣言と初期値の取得、及びテキストを置き換える関数を作ります。
Text catText; //Textコンポーネント型の変数を宣言
void Start()
{
//子要素が持つTextコンポーネントを取得し、変数に代入
catText = GetComponentInChildren<Text>();
}
void Say(string s) //指定した言葉を発する関数を作成
{
catText.text = s; //受け取った引数をテキストに表示
}
作った関数を利用して発言をするときは以下のコードを記述します。
Say("こんにちは!"); //こんにちは!と言う
こんにちは!と2秒言う
コンソールには2秒だけ表示するという機能はありません。今回はUIを使ってステージ上でキャラクターに言葉を2秒間言わせます。
上の「こんにち!はと言う」ブロックで用意した様に、キャラクターに UI の Text を子要素として配置します。
NameSpaceに UIを使用する宣言をします。
using UnityEngine.UI;
次にUI の Text コンポーネント型の変数の宣言と初期値の取得します。テキストは2秒後に消す必要があるので、テキストを置き換える関数はコルーチンにします。
Text catText; //Textコンポーネント型の変数を宣言
void Start()
{
//子要素が持つTextコンポーネントを取得し、変数に代入
catText = GetComponentInChildren<Text>();
}
//引数:s の文字を表示、引数:t秒後に消す関数
IEnumerator Say(string s,float t)
{
catText.text = s; //引数:s でテキストを更新
yield return new WaitForSeconds(t); //引数:t秒待機
catText.text = null; //テキスト文字をnull(無し)に
}
作った関数を利用して発言をするときは以下のコードを記述します。
StartCoroutine( Say("こんにちは!",2.0f)); //2秒後にこんにちは!と言う
うーん...と考える / うーん...と2秒考える
「〇〇という」「〇〇と2秒言う」と同じです。
コスチュームを〇にする
コスチュームは、AnimatorコンポーネントでAnimationを発動する方法と、SpriteRendererコンポーネントで Sprite を変える方法があります。今回はスクラッチに近い、SpriteRenderer コンポーネントの Spriteプロパティを変更する方法をご紹介します。
事前に SpriteRenderer コンポーネント型の変数の宣言と初期値の取得、変更するコスチューム(スプライト)を アクセス修飾子 public で宣言、Inspector から Assign します。
SpriteRenderer sr; //SpritRenderer型の変数を宣言
public Sprite catImg; //変更する画像をpublicで宣言
void Start()
{
sr = GetComponent<SpriteRenderer>(); //srの初期値を取得
}
変更するときは次のコードを記述します。
sr.sprite = catImage; //コスチュームを指定した画像に変更
次のコスチュームにする
複数のコスチュームを切り替えるには、SpriteRendererコンポーネントを使う方法とAnimatorコンポーネント使う方法があります。
1,SpriteRendererコンポーネント
事前に SpriteRenderer コンポーネント型の変数の宣言と初期値の取得、変更するコスチューム(スプライト)を アクセス修飾子 public で配列として宣言、Inspector から配列に変更するスプライトの数だけ順番にAssignします。
SpriteRenderer sr; //SpritRenderer型の変数を宣言
public Sprite[] picoImage; //使用するコスチューム(Sprite)を配列で登録
int count; //コスチュームの順番を管理
void Start()
{
sr = GetComponent<SpriteRenderer>(); //srの初期値を取得
}
インスペクターから作成した配列に、変更したい順にスプライトをAssignします。
コスチュームを変更させるには、SpriteRendererコンポーネントの画像を順番に置き換えます。
int num = count % picoImage.Length; //次の番号はcountを配列数で割った値に
sr.sprite = picoImage[num]; //スプライト番号を指定
count++; //count を更新
活用例
ずっと、次の処理を繰り返す
もしどれかのキーが押されたら、
0.2秒待つ
次のコスチュームにする
float currentTime; //経過時間を管理
void Update()
{
currentTime += Time.deltaTime; //経過時間を更新
//もし何かのキーがおされた、かつ、経過時間が0.2秒を越えたら
if (Input.anyKey && currentTime > 0.2f)
{
int num = count % picoImage.Length; //次のコスチューム番号を算出
sr.sprite = picoImage[num]; //コスチュームを指定
currentTime = 0; //経過時間をリセット
count++; //countを更新
}
}
2,Animatorコンポーネント
Animatorコンポーネントを使ったコスチューム変更を行うには、事前にAnimationを作る必要があります。
事前にAnimatorコンポーネントを使う変数を宣言し初期値を取得します。
Animator animator; //Animatorコンポーネント型の変数を宣言
void Start()
{
animator = GetComponent<Animator>(); //初期値を取得
animator.enabled = false; //アニメーションを無効にする
}
必要に応じアニメーションの有効、無効を切り替えます。
animator.enabled = true; //アニメーションを有効にする
活用例
もしどれかのキーが押されたら 次のコスチュームにする
そうでなければ コスチュームを止める
void Update()
{
if (Input.anyKey){ animator.enabled = true; }
else{ animator.enabled = false; }
}
背景を〇する
背景を必要とするのは2Dのケースがほとんどかと思いますので、2Dを前提で説明します。
事前に UI の Panel を使って背景を準備します。
通常UIは最前面に配置されるので、Canvas の Render Mode を Screen Space-Camera にし、RenderCamera に MainCamera を指定、SortingLayer を使って最背面に表示させましょう。
Panel には最初の背景を指定します
まずはUIを使うので、NameSpace で UI を使う宣言をします。
using UnityEngine.UI;
Panel の Imageコンポーネント にアクセスするための変数と、変更後の背景画像を変数で宣言します。
public Sprite bgSprite; //画像を管理する変数
public Image image; //パネルの Imageコンポーネント
インスペクターから 変数:bgSprite に変更したい画像を、変数:Image に用意した Panel をそれぞれAssignします。
背景画像を変更するには次のコードを記述します。
image.sprite = bgSprite;
次の背景にする
「背景を〇にする」と同じ手順で、UIを用意します。
まずはUIを使うので、NameSpace で UI を使う宣言をします。
using UnityEngine.UI;
Panel の Imageコンポーネント にアクセスするための変数と、複数の背景画像を管理する配列を宣言します。
public Sprite[] bgSprites; //画像を管理する配列
public Image image; //パネルの Imageコンポーネント
int count; //コスチュームの順番を管理する変数
インスペクターから 配列:bgSprites に変更したい複数の画像を、変数:Image に用意した Panel をそれぞれAssignします。
背景画像を順番に変更するには、変更したい場所で次のコードを記述します。
count++;
int num = count % bgSprites.Length;
image.sprite = bgSprites[num];
大きさを 10 ずつ変える
大きさは transformコンポーネントの Scale プロパティ が管理しています。
スクラッチは基準の大きさが100で、10ずつ変えるということは10%ずつ大きくなることです。Unityでは基準の大きさが 1 なので、0.1ずつ大きくなります。
transform.localScale += Vector3.one * 0.1f;
大きさを 100% にする
大きさは transformコンポーネントの Scale プロパティ が管理しています。大きさを100%にするということは、基準の大きさにするということです。
transform.localScale = Vector3.one;
「〇〇」の効果を〇ずつ変える
色の効果は 3DオブジェクトではRendererコンポーネント、2DコンポーネントではSpriteRendererコンポーネント が管理します。
スクラッチでは「色」「魚眼レンズ」「渦巻き」「ピクセル」「モザイク」「明るさ」「幽霊」それぞれの効果を指定することが出来ますが、Unityでは標準機能で「色」「明るさ」「幽霊」の効果を変更することが出来ます。
色の効果を〇ずつ変える
Unityで色の指定には 赤、緑、青の強さを指定するRGB形式と、色相、彩度、明るさを指定す HSV形式があります。
スクラッチの色の効果はHSV形式の色相に相当し、Inspector では0度~360度で同じ色相に戻るように設計されています。(Scratchでは0~200で1周)
コードで指定するには HSVToRGBメソッドを使用し、H,S,Vそれぞれ0~1の間の値で指定します。
今回の事例では2Dオブジェクトで指定します。
事前に変数の宣言と初期値の取得を行います。
float hue; //現在の色相
SpriteRenderer sr; //spriteRendererコンポーネント
void Start()
{
sr = GetComponent<SpriteRenderer>(); //コンポーネントの取得
}
色を更新するには HSVToRGBメソッドを使用 します。サンプルでは hue の値を1ずつ更新していますが、必要に応じ変化する数値を指定します。
hue++; //現在の色相をインクリメント
//色相を変更させて、新しい色で更新
sr.color = Color.HSVToRGB(hue % 360 / 360, 1.0f, 1.0f);
明るさの効果を〇ずつ変える
明るさの効果を指定する場合は HSV のSaturation(彩度)を指定すればよいのですが、変更では正しく表示されないようです。
またRGB形式でRed,Green,Blueそれぞれの値を徐々に大きくすることで、明るく(白身をつよく)することが出来ます。ただし、初期状態が白の2Dのスプライトの場合、この効果は発揮されません。
明るさの効果を暗くする場合は、同様にRed,Green,Blueそれぞれの値を小さくすることで、暗く(黒みを強く)することが出来ます。このケースでは2Dのスプライトでも効果が発揮されます。
今回のサンプルでは、3DオブジェクトにMaterialを適用します。
事前にMaterialを用意(Create→Material)し、任意の色を指定します。これを3Dオブジェクトの MeshRenderer の Materials にAssign(直接オブジェクトにドラッグ&ドロップでも可)します。
事前に変数の宣言と初期値の取得を行います。
変数:changeSpeed には、明るくしたい時はプラスの値を、暗くしたい時はマイナスの値を指定します。
Renderer rend; //Materialを持つRendererコンポーネント
float changeSpeed = 0.01f; //明るさの効果の変更速度
void Start()
{
rend = GetComponent<Renderer>(); //初期値を取得
}
明るさの効果を更新する場合は、Red、Green、Blue、それぞれの値を変更し、Materialの色を更新します。
float r = rend.material.color.r + changeSpeed; //赤の値を変更
float g = rend.material.color.g + changeSpeed; //緑の値を変更
float b = rend.material.color.b + changeSpeed; //青の値を変更
rend.material.color = new Color(r, g, b); //明るさを更新
幽霊の効果を〇ずつ変える
幽霊の効果はRGBAのAの値(Alpha値)を変更します。
スクラッチでは大きくなるほど幽霊の効果が強くなりますが、Unityでは逆で小さくなるほど透明に近くなります。
明るさの効果で準備した素材と同じ様に、3DオブジェクトのRenderコンポーネントに任意のMaterialをセットします。
この際、MaterialのRendring Mode を「Fade」に切り替え、Alpha値の変更で透明になるように指定します。 ※この作業は2Dのスプライトの色を変更する場合には必要ありません。
事前に変数の宣言と初期値の取得を行います。
変数:ghoatSpeed には、幽霊の効果が進む速度を指定します。
Renderer rend; //Materialを持つRendererコンポーネント
float ghostSpeed = 0.01f; //幽霊の効果の変更速度
void Start()
{
rend = GetComponent<Renderer>(); //初期値を取得
}
幽霊の効果を変更する際は、既存の Red,Green,Blue の変化量は0、Alpha値のみ変更されるようにします。
rend.material.color -= new Color(0, 0, 0, ghostSpeed);
画像効果をなくす
「〇〇」の効果を〇にする のブロックで変更した値をもとに戻します。
変更前に現在の色の各値を変数として保存、再度呼び出すことで画像効果がリセットされます。
事前に変数の宣言と初期値の取得を行います。
変数:ghoatSpeed には、幽霊の効果が進む速度を指定します。
Renderer rend; //Materialを持つRendererコンポーネント
Color myColor; //変更前のcolor情報
void Start()
{
rend = GetComponent<Renderer>(); //初期値を取得
myColor = rend.material.color; //変更前の色を取得
}
後は任意の場所で、変更前の color に戻します。
rend.material.color = myColor; //事前に保存している情報にリセット
隠す
オブジェクトを隠すには、Renderコンポーネント、またはSpriteRendererコンポーネントの enabled プロパティを false にして無効化にします。この時オブジェクトの見た目が透明になるだけで、実際には元の場所に存在しています。
GetComponent<Renderer>().enabled = false;
表示する
オブジェクトを再表示するには、Renderコンポーネント、またはSpriteRendererコンポーネントの enabled プロパティを true にして有効化します。
GetComponent<Renderer>().enabled = true;
最前面へ移動する
最前面、最背面などのLayerは、Rendererコンポーネント、またはSpriteRendererコンポーネントが管理しています。Layerを最前面、最背面に移動するには、Order in Layerプロパティを使うこともできますが、今回は Sorting Layerプロパティを使用します。
事前に下のように最前面のLayer、最背面のLayerを準備します。
最前面へ移動する場合
GetComponent<SpriteRenderer>().sortingLayerName = "ForeGround";
最背面へ移動する場合
GetComponent<SpriteRenderer>().sortingLayerName = "BackGround";
1層 手前に出す/奥に下げる
Layerの順番は Rendererコンポーネント、またはSpriteRendererコンポーネントが管理しています。
1層手前に出す場合
GetComponent<SpriteRenderer>().sortingOrder += 1;
1層奥に下げる場合
GetComponent<SpriteRenderer>().sortingOrder -= 1;
コスチュームの名前
コスチュームの名前、今回はAnimationに置き換えて説明します。Unityでは一つのオブジェクトに複数のアニメーションクリップを持たせることが出来ます。この中で現在起動しているアニメーションは、Animatorコンポーネントが持つGetCurrentAnimatorStateInfo() メソッドで取得したオブジェクトの IsNama プロパティが持ちます。
GetComponent<Animator>().GetCurrentAnimatorStateInfo(0).IsName
使用例
Animator animator
animator = GetComponent<Animator>();
//もし今動いているアニメーションクリップの名前が「idle」なら
if(animator.GetCurrentAnimatorStateInfo(0).IsName("idle"))
{
animator.SetBool("isRun", true); //isRun パラメータを true にする
}
背景の番号
背景の番号は「次の背景にする」で使用した配列の番号(変数:num)になります。
大きさ
大きさは transformコンポーネントの Scaleプロパティが管理しています。Scaleプロパティはx,y,z それぞれの軸を持っており、使用する場合は localscale.x などの様に対象の軸を指定する必要があります。
transform.localScale
使用例
もし大きさが100%より大きいなら、大きさを100%にする
if (transform.localScale.x > 1)
{
transform.localScale = Vector3.one;
}
ファイブボックスでは、スクラッチはもう卒業、という方向けにUnityの個別指導のオンラインレッスンを行っています。
ご興味のある方は当サイト、オンラインレッスンから、無料体験授業へお問い合わせ下さい。
Opmerkingen