スクラッチの次は?Unityへシフトアップ!スクラッチブロック→Unity変換表「動き編」

スクラッチ Unity変換表「動き」


スクラッチブロック 10歩動かす

10 歩動かす

スクラッチではキャラクターを動かすのに、座標を使用します。

Unityでも座標を使って動かすこともできるのですが、もう一つ物理エンジンというものを使って、物体に直接速度を与えて動かすことが出来ます。

Transform(座標情報)を使ったオブジェクトの移動方法

スクラッチの場合、座標はx座標とy座標で構成されています。

一方、Unityではx座標、y座標の他に、z座標という奥行きを表す軸があります。 座標は Transformコンポーネント Positionプロパティ が管理しています。

Unity transformコンポーネント

右方向に進む場合 右方向は transform.right と表記します。 移動には transform の positionプロパティを直接書き換える方法と、transform.positionプロパティを変化させるメソッド:Translate()メソッド を使用する方法があります。

スクラッチは上下左右の2Dの構造ですが、Unityでは3Dの構造を持つことが出来ます。キャラクターを前後に移動させることが出来、その時の transformプロパティは Forward という値を使用します。

  • Position プロパティを直接更新
transform.positon += transform.right;       //右方向に移動
transform.positon -= transform.right;       //左方向に移動
transform.positon += ransform.up;           //上方向に移動
transform.positon -= ransform.up;           //下方向に移動
transform.positon += ransform.forward;      //前方向に移動
transform.positon -= ransform.forward;      //後ろ方向に移動
  • Translate()メソッドでPosition プロパティを更新
transform.Translate(transform.right);       //右方向に移動
transform.Translate(-transform.right);      //左方向に移動
transform.Translate(transform.up);          //上方向に移動
transform.Translate(-transform.up);         //下方向に移動
transform.Translate(transform.forward);    //前方向に移動
transform.Translate(-transform.forward);    //後ろ方向に移動

Rigidbody(物理エンジン) を使ったオブジェクトの移動方法

物理エンジンを使うと、オブジェクトに速度を与えて移動させることが出来ます。transformを使った移動は座標情報の置き換え、いわゆる連続した瞬間移動であるのに対し、rigidbodyを使った移動は現実世界に近い物理移動になります。

Rigidbody コンポーネントを使用するためには、オブジェクトにRigidbodyを追加する必要があります。

AddComponent でRigidbodyコンポーネントを追加します。検証の為、追加されたRigidbodyコンポーネントの UseGravity のチェックを外し、重力を無効化にします。

Unity Rigidbodyコンポーネントの設定

Rigidbodyコンポーネントを使用するには、Rigidbody型の変数を作り、Start関数で初期値を取得すると良いでしょう。下の記述を行います。

Rigidbody rb;                             //Rigidbodyを使用するため、変数の宣言

void Start()  
{
    rb = GetComponent<Rigidbody>();  //Rigidbodyに初期値を代入
}

方向の指示は、transformコンポーネントを使用した移動と同じです。またプロパティ値を置き換える方法も、transformコンポーネント同様直接変更する方法と、AddForce()メソッドを使って置き換える方法があります。ただし、AddForceを使った場合、力が加わり続けますので、第二引数(ForceMode)などで適切な値を指定する必要があります。

右方向に進む場合、transform.right を指定します。

  • velocity プロパティを直接更新
rb.velocity = transform.right;           //右方向に移動
rb.velocity = -transform.right;          //左方向に移動
rb.velocity = transform.up;              //上方向に移動
rb.velocity = -transform.up;             //下方向に移動
rb.velocity = transform.forward;         //前方向に移動
rb.velocity = -transform.forward;        //後ろ方向に移動
  • velocity プロパティを AddForce()メソッドで更新
rb.AddForce(transform.right);         //右方向に移動
rb.AddForce(-transform.right);        //左方向に移動
rb.AddForce(transform.up);            //上方向に移動
rb.AddForce(-transform.up);         //下方向に移動
rb.AddForce(transform.forward);       //前方向に移動
rb.AddForce(-transform.forward);      //後ろ方向に移動

スクラッチブロック左〇度回す

〇度まわす

Unityで向きを管理しているのはtransformコンポーネント の Rotation プロパティです。

Untiy transformコンポーネント

このプロパティの値を変更する場合も、移動同様 transformコンポーネントを直接操作する方法と、Rigidbodyコンポーネントを使って値を操作する方法があります。

/

Transform(座標情報)を使ったオブジェクトの回転

Unityの場合、3軸のうちどの軸を回転させるかを指定する必要があります。スクラッチ同様2次元でとらえた場合、オブジェクトを時計回りに回すにはZ軸を中心に回転させます。

回転も移動と同様、transformコンポーネントの rotationプロパティを直接変化させる方法と、transform.rotationプロパティを変化させるメソッド:Rotate()メソッド を使用する方法があります。

Untiyでは角度をQuaternionという4軸で管理しています。プロパティを直接変化するには4軸を3軸に置き換える Quaternion.Euler() を使用します。一方、Rotate()メソッドの場合はVector3で指定することが出来ます。

Unityは角度の正負がスクラッチの逆になるので注意が必要です。左回りに回転の場合、z軸を正の値ずつ変化させます

右回りに回転の場合、Z軸を 負の方向に増加させます

  • rotation プロパティを直接変動
transform.rotation *= Quaternion.Euler(1, 0, 0);      //x軸を右回りに回転
transform.rotation *= Quaternion.Euler(-1, 0, 0);    //x軸を左回りに回転
transform.rotation *= Quaternion.Euler(0, 1, 0);      //Y軸を右回りに回転
transform.rotation *= Quaternion.Euler(0, -1, 0);    //y軸を左回りに回転
transform.rotation *= Quaternion.Euler(0, 0, -1);     //Z軸を右回りに回転
transform.rotation *= Quaternion.Euler(0, 0, 1);     //z軸を左回りに回転
  • ratation Property を Ratate()メソッドを使って変動
transform.Rotate(1,0,0);          //x軸を右回りに回転
transform.Rotate(-1,0,0);         //x軸を左回りに回転
transform.Rotate(0,1,0);          //y軸を右回りに回転
transform.Rotate(0,-1,0);         //y軸を左回りに回転
transform.Rotate(0,0,-1);         //Z軸を右回りに回転
transform.Rotate(0,0,1);          //z軸を左回りに回転

x軸、y軸、またはそれぞれを組み合わせた回転をするときは、3軸の値をそれぞれ変化させます。

Rigidbody(物理エンジン) を使ったオブジェクトの回転方法

他のオブジェクトの影響を受けるような回転をさせる場合、Rigidbodyコンポーネントを使用した回転を使用します。Rigidbodyコンポーネントの回転を管理するプロパティは angularVelocity です。移動を管理するvelocityプロパティ同様、この angularVelocity を直接変更する方法と、AddTorque()メソッドを使用して変更する方法があります。

  • angularVelocity を直接変更
rb.angularVelocity = transform.right;      //x軸を右回り
rb.angularVelocity = -transform.right;     //x軸を左回り
rb.angularVelocity = transform.up;         //y軸を右回り
rb.angularVelocity = -transform.up;        //y軸を左回り
rb.angularVelocity = transform.forward;    //z軸を右回り
rb.angularVelocity = -transform.forward;   //z軸を左回り

AddToruque()メソッドを使って angularVelocity を更新

rb.AddTorque(1, 0, 0);      //x軸を右回り
rb.AddTorque(-1, 0, 0);     //x軸を左回り
rb.AddTorque(0, 1, 0);      //y軸を右回り
rb.AddTorque(0, -1, 0);     //y軸を左回り
rb.AddTorque(0, 0, -1);     //z軸を右回り
rb.AddTorque(0, 0, 1);      //z軸を左回り

スクラッチブロック どこかの場所に行く

「~」へ行く

このブロックには「どこかの場所に行く」「マウスポインターの場所に行く」「指定のスプライトに行く」のいずれかを選択することが出来ます。


スクラッチブロック どこかの場所に行く

「どこかの場所に行く」

このブロックは初期状態で「どこかの場所」が指定されています。この場合、スクラッチでは押すたびにランダムな場所が再設定されます。Unityでは Randam.range() を使って、x,y,z の3軸にそれぞれ乱数を指定します。

transform.position = new Vector3(Random.Range(-10.0f, 10.0f), 
                                  Random.Range(-10.0f, 10.0f), 
                                  Random.Range(-10.0f, 10.0f));

スクラッチブロック マウスポインターへ行く

「マウスポインター」へ行く

マウスをクリックしたときに取得される座標は「スクリーン座標」、一方オブジェクトが持つ座標は「ワールド座標」です。 Cameraクラスが持つ ScreenToWorldPoint()メソッドを使ってスクリーン座標をワールド座標に変換しオブジェクトの座標を指定します。

Vector3 mousePos = Input.mousePosition;                        //マウスの座標を取得
mousePos.z = 10f;                                              //Z座標調整 
transform.position = Camera.main.ScreenToWorldPoint(mousePos); //スクリーン座標をワールド座標に変換 

スクラッチブロック 他のオブジェクトへ行く

「他のオブジェクト」へ行く

ターゲットを指定する方法は様々です。サンプルでは事前に GameObject.Find ()メソッド でオブジェクトの名前を指定して探し出し、変数:target に代入しています。

GameObject target = GameObject.Find("TargetName"); 
transform.position = target.transform.position;

スクラッチブロック x座標を0,y座標を0にする

x座標を 0、y座標を 0 にする

transformコンポーネントの positionプロパティ に Vector3 の値を指定します。Vector3 のカッコ内の引数は順に、x,y,z の座標の値です。

transform.position = new Vector3(0, 0, 0);

スクラッチブロック 1秒でどこかの場所に行く

〇秒でどこかの場所に行く

Unityで時間を管理するには、Coroutine(コルーチン) や DeltaTime(デルタタイム) を使うと良いでしょう。今回の事例では特定のキーを押したとき、またはマウスをクリックしたときにそれぞれの処理を発動したいと思います。

まずスタート位置、ゴール位置を変数宣言します。 コルーチンのメソッドの中では、引数で受け取った秒数でゴール位置に移動するコードを作っています。

今回はスペースキーを押したときに3秒かけてx、y、zそれぞれ -10 から 10 の間のランダムな座標に移動する内容にしました。

  • 変数の宣言
Vector3 startPos;  //初めの場所 
Vector3 endPos;    //向かう場所 
  • 引数 :t秒 を受けて移動を実行するコルーチンの宣言
IEnumerator GotoTargetR(float t)     //引数:t秒で指定した場所へ移動する関数
{
    float duration = t;                        //移動にかける時間(引数:t) 
    float currentTime = 0;                     //経過時間を初期化 
    startPos = transform.position;             //移動開始位置
    //endPosを乱数で取得(対象が他Objectの場合、下の※を対象Objectの座標で置換) 
    ※endPos = new Vector3(Random.Range(-10.0f, 10.0f), 
                          Random.Range(-10.0f, 10.0f),
                          Random.Range(-10.0f, 10.0f)); 
    //指定した時間を越えない間、以下の処理を繰り返す 
    while (currentTime < duration) 
    { 
        currentTime += Time.deltaTime;         // 経過時間を更新 
        float p = currentTime / duration;      //経過時間の割合を算出 
        transform.position = Vector3.Lerp(startPos, endPos, p); //座標更新
        yield return null;                     //1フレームスキップ
    }
 }
  • コルーチン型関数の呼び出し
void Update() 
{
    if (Input.GetKeyDown(KeyCode.Space))    //スペースキーが押されたら
    {
        StartCoroutine(GotoTargetR(3));    //引数 3(秒)を入れて移動のコルーチン発動 
    }
}

どこかの場所が指定するオブジェクトの場合、endPos にターゲットとなるオブジェクトの transfomPositon を指定します。

//シーン上のオブジェクトからターゲットの名前で検索、その座標を endPos に指定 
※endPos = GameObject.Find("TargetName").transform.position;

スクラッチブロック 1秒でマウスのポインターへ行く

〇秒で「マウスポインター」へ行く

マウスをクリックしたときに取得される座標は「スクリーン座標」、一方オブジェクトが持つ座標は「ワールド座標」です。マウスを左クリックをしたタイミングで、クリックしたスクリーン座標を Cameraクラスが持つScreenToWorldPoint メソッドを使ってワールド座標に変換し、ゴールの座標を指定します。引数には同じように3秒を指定したので、3秒かけてクリックした座標に移動します。

  • 変数の宣言
Vector3 startPos;     //初めの場所 
Vector3 endPos;       //向かう場所 
  • コルーチン型関数の宣言
IEnumerator GotoTargetM(float t) //引数:t秒でクリックした座標に移動する関数 
{
    float duration = t;                      //移動にかける時間
    float currentTime = 0;                   //経過時間を初期化
    startPos = transform.position;           //移動開始位置 
    //指定した時間を越えない間、以下の処理を繰り返す
    while (currentTime < duration)
    { 
        currentTime += Time.deltaTime;      // 経過時間を更新 
        float p = currentTime / duration;   //経過時間の割合を算出 
        transform.position = Vector3.Lerp(startPos, endPos, p); //座標更新 
        yield return null;                  //1フレームスキップ 
   }
}
  • 関数の呼び出し 左クリックしたタイミングで3秒かけてマウス座標移動
void Update() 
{
    if(Input.GetMouseButtonDown(0)) 
    { 
        Vector3 mousePos; 
        mousePos = Input.mousePosition;     //マウスの座標を取得 
        mousePos.z = 10f;                   //Z座標調整 
        //スクリーン座標をワールド座標に変換 
        endPos = Camera.main.ScreenToWorldPoint(mousePos); 
        //引数 3(秒)を入れて移動のコルーチン発動 
        StartCoroutine(GotoTargetM(3)); 
    } 
}

スクラッチブロック1秒でx座標を0,y座標を0に変える

〇秒でx座標を0、y座標を0に変える

Unityで時間を管理するには、Coroutine(コルーチン)や DeltaTime(デルタタイム) を使うと良いでしょう。今回の事例では特定のキーを押したときに指定した座標に移動する処理を作ります。

「〇秒でどこかの場所に行く」の内容とほぼ同じです。ターゲットとなる場所を Vector3 の座標で指定しました。

  • 変数の宣言
Vector3 startPos;   //初めの場所 
Vector3 endPos;     //向かう場所
  • コルーチン型関数の宣言
 IEnumerator GotoTargetR(float t) //引数:t秒で指定した場所へ移動する関数
{
    float duration = t;                        //移動にかける時間(引数:t)
    float currentTime = 0;                     //経過時間を初期化 
    vector3 startPos = transform.position;     //移動開始位置 
    vector3 endPos = new Vector3(5,-5,5);      //向かう場所を指定 
    //指定した時間を越えない間、以下の処理を繰り返す
    while (currentTime < duration)
    { 
        currentTime += Time.deltaTime;       //経過時間を更新
        float p = currentTime / duration;    //経過時間の割合を算出 
        transform.position = Vector3.Lerp(startPos, endPos, p);   //座標更新 
        yield return null;                   //1フレームスキップ 
    } 
}
  • コルーチン型関数の呼び出し スペースキーが押されたら3秒で指定の場所に移動
 void Update() 
{
    if (Input.GetKeyDown(KeyCode.Space))  //スペースキーが押されたら
    { 
        StartCoroutine(GotoTargetR(3));   //引数 3(秒)を入れて移動のコルーチン発動 
    }
}

スクラッチブロック 90度に向ける

90度に向ける

スクラッチ同様2Dの視点でとらえた場合、オブジェクトを90度に向ける(初期状態の角度)にはZ軸の値を変更します。

transform.rotation = Quaternion.Euler(0, 0, 90);    //90度に向ける

但し、スクラッチはオブジェクトの向きが初期状態で90度であるのに対し、Unityではすべての軸が0度となります。


「」に向ける

「」にはマウスポインター、または任意のスプライトを指定することができます。

スクラッチブロック マウスのポインターに向ける

マウスのポインターに向ける

この動きは作品が2Dなのか3Dなのかでプログラムを分ける必要があります。3Dの場合 transform.LookAt()メソッド を使って対象のオブジェクトをターゲットに向けることが出来ます。この時オブジェクト自体の正面がターゲットを向くので3軸にそれぞれ向きが与えられます。これを2Dで使って場合、画像が傾いてしまい元の形が崩れてしまいます。

  • 3Dの場合
Vector3 mousePos = Input.mousePosition;  //マウスの座標を取得
mousePos.z = 10f;                        //Z座標調整 
//スクリーン座標をワールド座標に変換 
Vector3 targetPos = Camera.main.ScreenToWorldPoint(mousePos); 
transform.LookAt(targetPos);
  • 2Dの場合
Vector3 mousePos = Input.mousePosition;                 //マウスの座標を取得 
mousePos.z = 10f;                                       //Z座標調整 
//スクリーン座標をワールド座標に変換し、自分の座標からの向きを取得 
Vector3 dir = Camera.main.ScreenToWorldPoint(mousePos) - transform.position; 
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;  // ベクトルの方向を回転角度に変換 
// オブジェクトを指定した角度に回転 
transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);

スクラッチブロック 他のオブジェクトへ向ける

他のオブジェクトへ向ける

  • 3Dの場合
Vector3 targetPos = GameObject.Find("TargetName").transform.position; //ターゲットを探す
transform.LookAt(targetPos);    //ターゲットの方向を向く
  • 2Dの場合
Vector3 targetPos = GameObject.Find("TargetName").transform.position;  //ターゲットを探す
Vector3 dir = targetPos - transform.position;              // ベクトルの方向を回転角度に変換
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;   //オブジェクトの方向を算出
 transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);  //指定した角度に回転

スクラッチブロック x座標を10ずつ変える

X座標を10ずつ変える

座標情報は、transformコンポーネントの Position プロパティが管理しています。10ずつ変える場合は、加算演算子を使って次のように記述します。

ただし、スクラッチと移動量や画面内の座標の範囲が大きく違っていますので、指定する値には注意が必要です。

transform.position += new Vector3(10, 0, 0);    //x座標を10ずつ変える

スクラッチブロック x座標を0にする

X座標を〇 にする

transformコンポーネントの Position プロパティを指定した値にするのですが、スクラッチと違って Positionプロパティに1つの軸の値だけ入れることが出きません。x以外の値は元の値を保持させたいので、次のように y 及び z の値には現在の値を指定します。

//x座標を10、y座標、z座標をそのままにする
transform.position = new Vector3(10, transform.position.y, transform.position.z);

スクラッチブロック y座標を10ずつ変える

Y座標を10ずつ変える

座標情報は、transformコンポーネントの Position プロパティが管理しています。10 ずつ変える場合は、加算演算子を使って次のように記述します。

ただし、スクラッチと移動量や画面内の座標の範囲が大きく違っていますので、指定する値には注意が必要です。

transform.position += new Vector3(0, 10, 0);   //y座標を10ずつ変える

スクラッチブロック y座標を0にする

y座標を〇 にする

transformコンポーネントの Position プロパティを指定した値にするのですが、スクラッチと違って Positionプロパティに1つの軸の値だけ入れることが出きません。y以外の値は元の値を保持させたいので、次のように x 及び z の値には現在の値を指定します。

//y座標を10、x座標、z座標をそのままにする
transform.position = new Vector3(transform.position.x, 10, transform.position.z);

スクラッチブロック もし端に着いたら跳ね返る

もし端に着いたら跳ね返る

Unityでオブジェクト同士の当たり判定を行うには、Colliderというコンポーネントが必要になります。事前準備としてステージ上に下のような2つのオブジェクトを配置します。

  • Sphere(球体)はRigidbodyコンポーネントを使って移動します。Use Gravity(重力)のチェックを外しておきます。また Sphere Collider コンポーネントが付いているのを確認しておきます。
  • Wall(壁)はSphereが衝突する対象です。跳ね返りの条件として「Wall」という名前を使用します。Box Collider コンポーネントが付いていることを確認しておきます。
Unity もし端に着いたら跳ね返るの説明画像
  • 変数の宣言、初期値の取得、オブジェクトの動き
Rigidbody rb;                              //Rigidbody 型の変数 
Vector3 force = new Vector3(-10, 1, 1);    //Sphereの移動方向(ベクトル)

void Start()
{
    rb= GetComponent<Rigidbody>();         //変数に初期値を代入 
}

void Update()
{
    rb.velocity = force;                   //常にforceの力で物理移動 
}
  • 跳ね返り
void OnCollisionEnter(Collision collision) //当たり判定
{
    //当たった相手の名前が「Wall」なら
    if (collision.gameObject.name == "Wall")
    {
        force *= -1;        //移動方向 に -1 をかけ、正反対にする
    }
}

スクラッチブロック 回転方法を左右のみにする

回転方法を左右のみにする

Unity RigidbodyコンポーネンFreezRotation

Rigidbodyコンポーネントの Constrains、Freeze Rotationプロパティ、回転を止めたい軸にチェックを入れるとその軸が固定されます。

回転方法を左右のみにしたい場合は、y軸のみ回転を有効にすればいいので、xとzにチェックを入れます。

これをスクリプトファイルから指定すると以下のようになります。

回転方法を「左右のみ」にする

Rigidbody rb = GetComponent<Rigidbody>() 
rb.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationZ;

回転方法を「自由に回転」にする

Rigidbody rb = GetComponent<Rigidbody>() 
rb.freezeRotation = false;    //回転を止めるを無効にする

回転方法を「回転しない」にする

Rigidbody rb = GetComponent<Rigidbody>() 
rb.freezeRotation = true;    //回転を止めるを有効にする

スクラッチブロック x座標

X座標

x座標は transform コンポーネントの Postion プロパティが管理しています。

transform.positon.x
  • 使用例
スクラッチブロック もしx座標が0より大きいならx座標を0にする

もしx座標が 0 より大きいなら、x座用を 0 にする

( y座標とz座標も0 にする )

if (transform.position.x > 0) 
{
    transform.position = new Vector3(0, 0, 0); 
}

スクラッチブロック y座標

Y座標

y座標は transform コンポーネントの Postion プロパティが管理しています。

transform.positon.y
  • 使用例
スクラッチブロック もしy座標が0より大きいならy座標を0にする

もしy座標が 0 より大きいなら、y座用を 0 にする

( x座標とz座標も0 にする )

if (transform.position.y > 0) 
{
    transform.position = new Vector3(0, 0, 0); 
}

スクラッチブロック 向き

向き

向きは transform コンポーネントの Rotation プロパティが管理しています。

但しUnityでは、Quaternion(クォータにオン)という4軸で角度を見ているため、3軸で角度を測るときは注意が必要です。

  • Quaternionの場合
transform.rotate
  • Vector3の場合
transform.rotation.eulerAngles
  • 使用例
スクラッチブロック もし向きが0度より大きいなら0度に向ける

もしy座標が 0 より大きいなら、y座用を 0 にする

( x座標とz座標も0 にする )

Vector3 currentRotation = transform.rotation.eulerAngles; //角度を変数化
if (currentRotation.z > 0f) //z軸の角度が0度より大きい場合
{ 
    currentRotation.z = 0f; //z軸の角度を 0 
    transform.rotation = Quaternion.Euler(currentRotation);//角度を更新 
}

ファイブボックスでは、スクラッチはもう卒業、という方向けにUnityの個別指導のオンラインレッスンを行っています。

ご興味のある方は当サイト、オンラインレッスンから、無料体験授業へお問い合わせ下さい。

TOP