code ソーシャル

Unityアプリcodetips(14)

スポンサーリンク

//tips

//Unity3Dとcamera、UI表示の関係性

Unity2Dはカメラの表示範囲にアプリの制作物を納めれば問題ないが、Unity3Dは制作物が大抵のケースでカメラの表示範囲から外れてしまうので、その場合の一般的なプレイヤーとカメラ、そして、プレイヤーと一緒に常に表示されるUI(canvas)の関係性を確認した。

3D空間の中で、プレイヤーを動かす場合は、プレイヤーにカメラの照準を合わせる必要があるので、カメラをプレイヤーの子オブジェクトとし、プレイヤーの動きをカメラで追従する。

その追従画面に対して、常に表示させておきたいテキストなどはcanvasのUIで作成されることになるが、単純にcanvasのrender modeをScreen Space - cameraにするだけではダメで、さらにPlane Distanceによって、カメラの最大奥行の表示からプレイヤーがカメラに写る最適なPlane Distanceへの変更が必要となる。

これは、カメラの表示可能領域も3dで表されているので、その3dの中の一つの2d(プレイヤーが最適に表示される画面枠)を選ばなければいけないということである。

プレイヤーのスクリプトは以下になる。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerManager : MonoBehaviour
{
public float speed = 10.0f;
public Rigidbody rb;

void Start()
{
rb = GetComponent<Rigidbody>();
}

void FixedUpdate()
{
float x = Input.GetAxis("Horizontal") * speed;
float z = Input.GetAxis("Vertical") * speed;
rb.AddForce(x, 0, z);
}
}

//追加ステージの作成

ベースとなるSceneの作成ができたら、それを複製することで別のステージを制作していくことができる。

これはFile→Save Scene as を利用し、別名で保存すれば良い。

//ボタンを押したらステージ遷移

まず複数のボタンがあるため配列を使用する。

HingeJoint[] hingeJoints;
hingeJoints = GetComponents<HingeJoint>();

配列の取得のベースは上記の形となる。

この各ボタンに遷移の処理を付加していく必要がある。

なので、今回はstageButtonsという配列の変数を用意し、配列番号によってステージとボタンの遷移を行なっていく。

int clearStageNo = PlayerPrefs.GetInt ("CLEAR", 0);

とは、事前にPlayerPrefs.SetInt(string key, int i);で保存したものをロードするときに使用するint i =PlayerPrefs.GetInt(string key);をベースにしており、読み込もうとしたときにデータがない場合は、デフォルト値である第二引数の0が代わりに保存される。

stageButtons.GetUpperBound(0)でステージの数を取得し、ループさせる。

クリアしたステージがある場合は数字が加算していくので、それにより、入れるステージが増えていくことになる。

interactableとはbool型でボタンに付加して、falseにすると半透明にし、選択できなくする使われ方をする。

最後にボタンを押されたときに遷移するSceneManager.LoadScene ("GameScene" + stageNo);を記述し、インスペクターの中のButton(Script)のOn Click()でスクリプトの貼り付けとメソッドPushStartButtonの設定を行う。

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

using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class StageSelectManager : MonoBehaviour {

public GameObject[] stageButtons; //ステージ選択ボタン配列

// Use this for initialization
void Start () {
int clearStageNo = PlayerPrefs.GetInt ("CLEAR", 0); //どのステージまでクリアしているのかをロード(セーブされていなければ「0」)

//ステージボタンを有効化
for (int i = 0; i <= stageButtons.GetUpperBound(0); i++) {
bool buttonEnable;

if (clearStageNo < i) {
buttonEnable = false; //前ステージをクリアしていなければ無効
}else{
buttonEnable = true; //前ステージをクリアしていれば有効
}

stageButtons[i].GetComponent<Button>().interactable = buttonEnable; //ボタンの有効/無効を設定
}
}

// Update is called once per frame
void Update () {

}

//ステージ選択ボタンを押した
public void PushStageSelectButton (int stageNo) {
SceneManager.LoadScene ("GameScene" + stageNo); //ゲームシーンへ
}
}

//PlayerPrefsの理解
セーブとロードで使用するPlayerPrefsをもう少し突っ込んで理解する。

数字をずっと加算し続けるプログラムでセーブとロードの簡単な反応を見る。

UIでテキストを作成したのち、emptyオブジェクトに下記のスクリプトを追加し、Managerとする。インスペクターのscore_object項目にUItextオブジェクトをヒエラルキーからドラッグすることでアタッチすれば準備完了。

フレームが変わるごとにscore_numが加算されていく。

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

using UnityEngine.UI; // 追加

public class ScoreManager : MonoBehaviour
{

public GameObject score_object = null; // Textオブジェクト
public int score_num = 0; // スコア変数

// 初期化時の処理
void Start()
{
// スコアのロード
score_num = PlayerPrefs.GetInt("SCORE", 0);
}
// 削除時の処理
void OnDestroy()
{
// スコアを保存
PlayerPrefs.SetInt("SCORE", score_num);
PlayerPrefs.Save();
}

// 更新
void Update()
{
// オブジェクトからTextコンポーネントを取得
Text score_text = score_object.GetComponent<Text>();
// テキストの表示を入れ替える
score_text.text = "Score:" + score_num;

score_num += 1; // とりあえず1加算し続けてみる
}
}

保存場所はローカル環境となるため

Mac:
/Users/[ユーザー名]/Library/Preferences/unity.[company name].[product name].plist

ios:
/Library/Preferences/[bundle identifier].plist」

android:
/data/data/pkg-name/shared_prefs/pkg-name.xml

へデータが保存される。

//array.GetUpperBoundとarray.GetLengthの違い

GetUpperBoundは配列の最大インデックスを返し、GetLengthは配列の要素数を返す。

1次配列の場合は、GetUpperBound = GetLength-1

2次配列の場合は事情が異なり、例えば下記は
private static readonly int[,] USHolidays =
{
{ 1, 1 },
{ 7, 4 },
{ 12, 24 },
{ 12, 25 }
};

配列には8つの要素があるため、Lengthプロパティは8を出力。
一方で、GetUpperBound()関数は、最初の次元の上限が3(縦に0,1,2,3)であるため、3を出力する。

この性質の違いから、GetUpperBound()関数は次元ごとのループ作業に適しており、

for (var i = 0; i <= USHolidays.GetUpperBound(0); i++)
{
Console.WriteLine("{0}, {1}", USHolidays[i, 0], USHolidays[i, 1]);
}
などの形で利用される。

ここで使用されているConsole.WriteLine()の便利技は、””内部で、コンソール表示する形を示し、{}に第二引数以下に続く、数字の順番(第二引数0番から始まる)を書くことで、その順番に書かれた数字そのものを取得できる。

例:
int first = 123;
int second = 234;

System.Console.WriteLine("first:{0} second:{1}", first, second); // 順番

実行結果:
first:123 second:234
となる。

人気の記事

1

コロナによる需要変化 コロナパンデミックの影響で、人々は外に出られなくなり、自宅で過ごす時間が増えました。 この自粛ムードの中、下記のようなビジネスの需要変化が引き起こされています。 【利用者減少】 ...

2

米国レストランの決済時に毎日お世話になっていた「Square」のビジネスモデルについて本日はふれていきたいと思います。 「Square」とは、ネットにつながったモバイル端末と専用のカードリーダーを用意 ...

3

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

4

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

5

ナイキのSNKRSが、なぜこれほどまでに人気なのか?調べてみました。 きっかけは米国での友達との会話。彼は自分のシューズをみせて、「これ20万円もしたんだぜ。」と語ってくれました。 あまり靴に興味がな ...

-code, ソーシャル
-,

Copyright© BUSINESS HACKER , 2020 All Rights Reserved Powered by AFFINGER5.