スクラッチからUnityに変換
6回目は「調べる」グループのご紹介です。
スクラッチの「調べる」ブロックは、指定した条件を判定したり、自分や他のスプライトの状態、マウスの位置、時間などの値を取得するブロックです。調べるブロックは条件分岐のブロックと組み合わせて使用するケースがほとんどです。 Unity でも同様に、他のオブジェクトやコンポーネントの情報を取得することが出来ます。
マウスのポインターに触れた
マウスの位置から光線を飛ばし、光線がオブジェクトに当たった時に、それが該当のオブジェクトなのかを調べます。
// マウスの位置からRayを発射し、ray という名で変数化
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
// ray が他のオブジェクトと衝突したかどうかをチェック
if (Physics.Raycast(ray, out RaycastHit hit))
{
// 衝突したオブジェクトが自分自身であるかを確認
if (hit.collider.gameObject == gameObject)
{
// マウスポインターに触れた際のイベントをここに記載
}
}
他のオブジェクトに触れた
他のオブジェクトに触れた時に信号をあげるには、事前準備として次の2つを行います。
互いにColliderコンポーネント(当たり判定)を追加
衝突対象オブジェクトには「Target」というタグをセット
スクリプトファイルには、Unityに事前に備わっているイベント関数を使用します。イベント関数は3D用の Collider の場合、2D用の Collider2D の場合、それぞれ違いますので注意してください。
3DのColliderを使用している場合
//Collideをもつオブジェクトに当たった時のイベント関数
void OnCollisionEnter(Collision col)
{
if (col.gameObject.tag == "Target") //相手にTargetタグが付いていれば
{
//当たった時のイベントを記載
}
}
2DのColliderを使用している場合
//Collide2Dをもつオブジェクトに当たった時のイベント関数
void OnCollisionEnter2D(Collision2D col)
{
if (col.gameObject.tag == "Target") //相手にTargetタグが付いていれば
{
//当たった時のイベントを記載
}
}
端に触れた
Unityにはスクラッチのような「端」がありません。そこでオブジェクトを配置して端を作ってみましょう。
BoxColliderなどの当たり判定を持ったオブジェクトを両端に配置
Colliderコンポーネントの IsTrigger にチェックを入れ、侵入判定状態に
MeshRenderer などのチェックを外し、透明にする
Wall などのタグをセットしておく
侵入判定のオブジェクトへの侵入検知は、イベント関数:OnTriggerEnter を使用します。
3DのColliderを使用している場合
//Trigger状態のColliderコンポーネントを持つオブジェクトに侵入したとき
void OnTriggerEnter(Collider other)
{
if (other.tag == "Wall") //侵入した相手がwallタグを持っていたら
{
//侵入したときのイベントを記載
}
}
2DのColliderを使用している場合
//Trigger状態のColliderコンポーネントを持つオブジェクトに侵入したとき
void OnTriggerEnter2D(Collider2D col)
{
if(col.tag == "Wall") //侵入した相手がwallタグを持っていたら
{
//侵入したときのイベントを記載
}
}
例文
変数:Speed を10にする
ずっと以下の処理を繰り返す
Speed 歩動かす
もし端に触れたら
speed を -speed にする
Rigidbody rb; //Rigidbody を扱うための変数
float speed = 10; //変数:speed を宣言し初期値に10を代入
void Start()
{
rb = GetComponent<Rigidbody>(); //rb に初期値を代入
}
void Update()
{
rb.velocity = transform.right * speed; //speed の速度で右方向へ移動
}
void OnTriggerEnter(Collider other) //当たり判定
{
if (other.tag == "Wall") //当たった相手がWallタグを持っていたら
{
speed *= -1; //speed を-1倍
}
}
〇色に触れた
事前に変数でターゲットとなる色を指定し、触れた相手のマテリアルの色がターゲットの色と同じかチェックします。
変数の宣言 Inspectorからターゲットとなる色を指定します
public Color targetColor; // ターゲットの色
衝突したときのプログラム
void OnTriggerEnter(Collider other)
{
// 衝突したオブジェクトのRendererコンポーネントを取得し変数化
Renderer renderer = other.GetComponent<Renderer>();
if (renderer != null) //もしrendererが取得出来たら
{
// マテリアルの色がターゲットの色と一致するかチェック
if (renderer.material.color == targetColor)
{
// 特定の色に触れた時のイベントをここに記載
}
}
}
※サンプルではイベント関数:OnTriggerEnter() で作成していますが、OnCollisionEnter でも可能、 また共に2D用のイベント関数でも同様です。
〇色が〇色に触れた
先に説明した「〇色に触れた」とほぼ同じで、触れたタイミングのイベント発生条件に自らの色の条件が追加されます。
変数の宣言 Inspectorからターゲットと衝突する側の色を指定します
public Color targetColor; // ターゲットの色
public Color thisColor; // 衝突する側の色
衝突する側のプログラム
void OnTriggerEnter(Collider other)
{
// 衝突したオブジェクトのRendererコンポーネントを取得し変数化
Renderer renderer = other.GetComponent<Renderer>();
if (renderer != null) //もしrendererが取得出来たら
{
// 衝突相手の色、自分の色、それぞれが指定した色と一致するかをチェック
if (renderer.material.color == targetColor &&
GetComponent<Renderer>().material.color == thisColor)
{
// 特定の色が特定の色に触れた時のイベントをここに記載
}
}
}
マウスポインターまでの距離
マウスの位置から光線を飛ばしマウスの座標を取得、そこからオブジェクトまでの距離を計測します。
2点間の距離を計測するには、Vector3.Distance メソッドを使用します。
事前に変数を宣言
Vector3 mousePos; //マウスの座標
float distance; //マウスまでの距離
マウス座標からの距離を計測
mousePos = Input.mousePosition; //マウスの座標を取得
mousePos.z = 10f; //Z座標調整
//マウス座標とオブジェクト座標の距離を計測
distance = Vector3.Distance(Camera.main.ScreenToWorldPoint(mousePos),
transform.position);
Debug.Log("マウスからの距離" + distance );
他のオブジェクトまでの距離
2点間の距離を計測するもう一つの方法は magnitude を使用する方法です。
変数の宣言とターゲットの取得
GameObject target; //ターゲット
float distance; //ターゲットとオブジェクト、2点間の距離
void Start()
{
target = GameObject.Find("Sphere"); //ターゲットを探す
}
2点間の距離を計測
distance = (transform.position - target.transform.position).magnitude;
〇?と聞いて待つ/答え
「〇と聞いて待つ」とその「答え」は UI の InputField を使って作成します。
事前にHierarchyに UI の InputField を用意します。
下のようにステージ上に入力できるインプットフィールドが配置されます。
今回のスクリプトファイルは作成したInputFieldオブジェクトにアタッチします。 ※今回はInputFieldにスクリプトファイルをアタッチしましたが、他のオブジェクトにアタッチしても大丈夫です。
変数の宣言と初期値の取得
InputField inputField; //InputField を使うための変数
string answer; //入力した内容が代入される変数(答えになる部分)
void Start()
{
inputField = GetComponent<InputField>(); //変数の初期値を取得
}
InputField に入力した内容を answer に代入
public void SetAnswer() //public で任意の名前の関数を作成
{
answer = inputField.text; //変数:answer に入力した内容を代入
Debug.Log(answer); //入力された内容を確認(必要に応じ)
}
Inspector からイベントをセット
Unityを起動させ、任意の文字や数字を入力し、Enterキーなどで確定。
変数:answer に入力した内容が代入されます。サンプルではコンソールに入力された文字を表示するように指定したので、入力文字が表示されます。
「〇キー」が押された
スクラッチと違い、Unityではあらゆるキーの入力を検知することが出来ます。
詳細は Unity公式リファレンス をご参照ください。
また、キーを押している間、押した瞬間(1度だけ)、上げた瞬間、それぞれ信号をとることが出来ます。
スペースキーが押された(押している間ずっと信号をあげる)
Input.GetKey(KeyCode.Space)
スペースキーが押された(押した瞬間1度だけ信号が上がる)
Input.GetKeyDown(KeyCode.Space)
スペースキーが離された(キーを離したときに信号が上がる)
Input.GetKeyUp(KeyCode.Space)
マウスが押された
マウスが押されたときの情報を取得するには、Input.GetMouseButton(0) を使います。 この時の引き数はそれぞれ次のボタンに対応します。
引数 | マウスの位置 |
---|---|
GetMouseButton( 0 ) | 左クリック |
GetMouseButton( 1 ) | 右クリック |
GetMouseButton( 2 ) | 中央のホイール |
マウスがクリックされた(押している間ずっと信号をあげる)
Input.GetMouseButton(0)
マウスがクリックされた(押した瞬間に信号をあげる)
Input.GetMouseButtonDown(0)
マウスがクリックされた(押している間ずっと信号をあげる)
Input.GetMouseButtonUp(0)
マウスのx座標/マウスのy座標
マウスの座標を取得するには、Input.mousePosition を使用します。しかしInput.mousePosition はスクリーン上の座標なので、ステージ上の座標にするにはCamera.main.ScreenToWorldPoint() で取得した座標をワールド座標に置き換えます。
マウスのスクリーン座標をワールド座標へ置換
Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
マウスのx座標
mousePos.x
マウスのy座標
mousePos.y
マウスのz座標
mousePos.z
ドラッグできるようにする
オブジェクトをドラッグするには、クリックした状態かどうかを判定し、クリックした状態であればオブジェクトをマウスの座標にする、という方法をとります。
変数の宣言
bool isDrag; //drag出来る状態かを判定するフラグ
Vector3 mousePos; //マウスがクリックされたときのスクリーン座標
ドラック判定
void OnMouseDown() //マウスがクリックされた
{
isDrag = true; //dragフラグを true に
}
void OnMouseUp() //マウスボタンが離された
{
isDrag = false; //dragフラグを false に
}
マウス座標に追従するプログラム
void Update()
{
if (isDrag) //dragフラグが true なら
{
mousePos = Input.mousePosition; //マウスの座標を取得
mousePos.z = 10f; //カメラの位置補正
//スクリーン座標をワールド座標に変換
transform.position = Camera.main.ScreenToWorldPoint(mousePos);
}
}
音量
Unityで音量を取得するにはAudioSourceコンポーネントを使用します。
事前に音量を取得するプログラムを保有するオブジェクトにAudioSauceを追加します。
変数の宣言と初期値の取得、及び音声入力の準備と開始
float volume; //音量(スクラッチの音量ブロック)
string microphone; // 使用するマイクの名前
int sensitivity = 100; // 音量の最大値
AudioSource source; //AudioSauceコンポーネントを使用するための変数
void Start()
{
source = GetComponent<AudioSource>(); //AudioSourceを取得
// マイクデバイスのリストを取得
string[] microphones = Microphone.devices;
microphone = microphones[0]; // デフォルトで最初のマイクを使用
// AudioSauceに選択したマイクを設定
source.clip = Microphone.Start(microphone, true, 10, 44100);
source.loop = true; //AudioSauceをループ状態に
//音声入力の準備が整うまで待つ
while (!(Microphone.GetPosition(null) > 0)) { }
source.Play(); // マイクの入力を開始
}
音声データを取得し、音量を0~100の数値で置き換る
void Update()
{
// 音量を取得
float[] data = new float[256]; //音声データを格納するための配列
float sum = 0; // 音声データの絶対値を合計する変数を初期化
source.GetOutputData(data, 0); //data配列に音声データをコピー
foreach (float d in data) //dataの数(256回)繰り返す
{
// 配列内の各音声データの絶対値を合計し音量の強度を算出
sum += Mathf.Abs(d);
}
// 音声データの平均絶対値を算出、これが音量の強度となる
float average = sum / data.Length;
volume = average * sensitivity; // 音量averageを0から100の範囲に変換
Debug.Log("音量: " + volume.ToString());
}
タイマー
Unityでは、Timeクラスが管理しているTimeプロパティ(Time.time)を使って、ゲーム開始からの経過時間を取得することが出来ます。
使用例
Debug.Log(Time.time);
しかしこの値はリセットすることはできません。スクラッチと同じようにタイマーを任意の場所でリセットしたい時には、以下のようにプログラムを組み立てます。
変数でタイマーを用意
繰り返し関数内で Time.deltatime を使いタイマーに経過時間を加算
任意のポイントでその値をリセット
使用例(上記1~3)
float timer = 0; //1,時間を計る変数を用意
void Update()
{
timer += Time.deltaTime; //2,timerに経過時間を加算
//timer を小数点下2桁に切り捨て、コンソールに表示
Debug.Log("経過時間:" + timer.ToString("F2"));
if (Input.GetKeyDown(KeyCode.Space)) //スペースキーが押されたとき
{
timer = 0; //タイマーをリセット
}
}
「他のオブジェクト」の「x座標」
Unity では他のオブジェクトにアクセスすることで、そのオブジェクトのプログラムの変数や各種コンポーネントのプロパティを取得することが出来ます。
以下のサンプルでは Hierarchy 上から「Other」という名前のオブジェクトを探して、各種プロパティ値を取得する方法をご紹介します。
「他のオブジェクト」の「x座標」
GameObject.Find("Other").transform.position.x
「他のオブジェクト」の「y座標」
GameObject.Find("Other").transform.position.y
「他のオブジェクト」の「向き」
GameObject.Find("Other").transform.rotation
「他のオブジェクト」の「コスチューム名」
GameObject.Find("Other").GetComponent<SpriteRenderer>().sprite.name
「他のオブジェクト」の「大きさ」
GameObject.Find("Other").transform.localScale
「他のオブジェクト」の「音量」
GameObject.Find("Other").GetComponent<AudioSource>().volume
他にも各種コンポーネントのプロパティの値、アタッチされたスクリプトファイルのpublic変数などを取得することが出来ます。
現在の「年」
スクラッチブロックの「現在の年」ブロックでは年の他に付き、日、曜日、時、分、秒などの値を取得することが出来ます。
Unity では DateTime を使って時間を取得します。取得した値には、年、月、日など時間に関するあらゆるプロパティ値が含まれています。
時間を取得し変数にDateTime型の変数代入
DateTime now = DateTime.Now; // 現在の日時を取得
年を取得
int year = now.Year;
月を取得
int month = now.Month;
曜日を取得(日本の曜日に変換)
DayOfWeek dayOfWeek = now.DayOfWeek;
// 日本の曜日名の配列を用意
string[] jpNames =
CultureInfo.GetCultureInfo("ja-JP").DateTimeFormat.DayNames;
string youbi = jpNames[(int)dayOfWeek]; //日本語曜日に変換
日付を取得
int day = now.Day;
時間を取得
nt hour = now.Hour;
分を取得
int minute = now.Minute;
秒を取得
int second = now.Second;
2000年からの日数
2000年からの日数を取得するには、DataTime を使って今日の日数、2000年1月1日の日数をそれぞれ取得、その差を求めます。
変数の宣言
int elapsed; //2000年1月1日からの経過時間
日数の計算
DateTime today = DateTime.Now; // 現在の日付を取得
DateTime startDate = new DateTime(2000, 1, 1); // 2000年1月1日を指定
// todayとstartDate の差を求め、整数値に置換
elapsed = (int)(today - startDate).TotalDays;
ファイブボックスでは、スクラッチはもう卒業、という方向けにUnityの個別指導のオンラインレッスンを行っています。
ご興味のある方は当サイト、オンラインレッスンから、無料体験授業へお問い合わせ下さい。
Comments