チュートリアル – Componentを操作する

Tutorial

C#Scriptから以下のようにGameObjectのComponentを操作するチュートリアルです。

  • Sphere GameObjectの位置情報を持つTransform Componentのpositionで配置します。
  • Sphere GameObjectに物理特性のRigidbody Componentをつけ重力により落ちるようにします。
  • Sphere GameObjectの衝突判定のCollider Componentのmaterialに物理マテリアルを設定し弾むようにします。
  • Sphere GameObjectの描画のMeshRenderer Componentのmaterialのcolorで色を変えます。

プロジェクトを作成する

Unity Hubで新規プロジェクトを作成します。

どのバージョンでも構いませんが、バージョンによりメニュー等が異なるかもしれません。ここでは、Unity 2020.2.6f1でプロジェクトを作成します。プロジェクト名、保存先はお好きなように入力してください。

レイアウトを変更する

レイアウトはお好きなように、ここではScene viewとGame viewが同時に見れる[nmxi style]にしています。Layoutはツールバーの右端にあるComboboxで変えられます。

C#Scriptアタッチ用のGameObjectを生成する

Hierarchyの[+]あるいはコンテキストメニューから[Create Empty]を選択し、空のGameObjectを生成します。Inspectorを見ると、Transform Componentくらいしかありません。

C#Scriptを生成する

ProjectのAssetsの下に[+]-[Folder]あるいはコンテキストメニューの[Create]-[Folder]により”Scripts”フォルダーを作成します。”Scripts”フォルダーの下にいき、[+]-[C#Script]あるいはコンテキストメニューの[Create]-[C#Script]によりC#Scriptを生成し”TestComponent”という名前にします。フォルダー構成やファイル名はお好みで変更してかまいません。C#Scriptのファイル名とクラス名は同じにしてください。

生成したC#Scriptを先ほど作成したGameObjectにアタッチ(GameObjectのComponentとして追加する)してください。C#ScriptをGameObjectにドラッグ&ドロップ等でアタッチできます。

C#Scriptを編集する

C#Scriptをダブルクリックして編集用のツール、ここではVisual Studioを起動します。拡張機能にはVisual Studio Tools for Unityをインストールしています。

球(Sphere)を配置する

using UnityEngine;

public class TestComponent : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        for (int x = -5; x < 5; ++x)
        {
            for (int z = -5; z < 5; ++z)
            {
                // 球のGameObjectをインスタンス生成する
                var sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                // 10x10になるように配置する
                sphere.transform.position = new Vector3(x + 0.5f, 0, z + 0.5f);
            }
        }
    }
}

Playボタンを押すと、10×10の球が表示されます。

球が落ちるようにする

Sphere GameObjectインスタンスに物理特性のRigidbody Componentを追加することで落ちるようにします。

sphere.AddComponent<Rigidbody>();
using UnityEngine;

public class TestComponent : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        for (int x = -5; x < 5; ++x)
        {
            for (int z = -5; z < 5; ++z)
            {
                // 球のGameObjectをインスタンス生成する
                var sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                // 10x10になるように配置する
                sphere.transform.position = new Vector3(x + 0.5f, 0, z + 0.5f);

                // 重力で動くようにする
                sphere.AddComponent<Rigidbody>();
            }
        }
    }
}

床を用意する

球を受け止める床を用意します。

// 床を作る
var floor = GameObject.CreatePrimitive(PrimitiveType.Cube);
// 10x10の大きさにする
floor.transform.localScale = new Vector3(10, 1, 10);

球のY座標を床より高くして床に落ちるようにします。

sphere.transform.position = new Vector3(x + 0.5f, 10, z + 0.5f);
using UnityEngine;

public class TestComponent : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        // 床を作る
        var floor = GameObject.CreatePrimitive(PrimitiveType.Cube);
        // 10x10の大きさにする
        floor.transform.localScale = new Vector3(10, 1, 10);

        for (int x = -5; x < 5; ++x)
        {
            for (int z = -5; z < 5; ++z)
            {
                // 球のGameObjectをインスタンス生成する
                var sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                // 10x10になるように配置する
                sphere.transform.position = new Vector3(x + 0.5f, 10, z + 0.5f);

                // 重力で動くようにする
                sphere.AddComponent<Rigidbody>();
            }
        }
    }
}

球を弾ませる

床にピタッと張り付くように落ちますね。衝突判定のCollider Componentのmaterialに物理マテリアルを設定して弾ませてみましょう。

// 物理マテリアルを生成する
var physicMaterial = new PhysicMaterial();
// バウンドしやすさをランダムにする
physicMaterial.bounciness = Random.value;
// バウンドが続くようにする
physicMaterial.bounceCombine = PhysicMaterialCombine.Maximum;
// 摩擦係数を低くし転がりやすくする
physicMaterial.dynamicFriction = 0;
physicMaterial.staticFriction = 0;
// コライダーに物理マテリアルを設定する
var collider = sphere.GetComponent<Collider>();
collider.material = physicMaterial;
using UnityEngine;

public class TestComponent : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        // 床を作る
        var floor = GameObject.CreatePrimitive(PrimitiveType.Cube);
        // 10x10の大きさにする
        floor.transform.localScale = new Vector3(10, 1, 10);

        for (int x = -5; x < 5; ++x)
        {
            for (int z = -5; z < 5; ++z)
            {
                // 球のGameObjectをインスタンス生成する
                var sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                // 10x10になるように配置する
                sphere.transform.position = new Vector3(x + 0.5f, 10, z + 0.5f);

                // 重力で動くようにする
                sphere.AddComponent<Rigidbody>();

                // 物理マテリアルを生成する
                var physicMaterial = new PhysicMaterial();
                // バウンドしやすさをランダムにする
                physicMaterial.bounciness = Random.value;
                // バウンドが続くようにする
                physicMaterial.bounceCombine = PhysicMaterialCombine.Maximum;
                // 摩擦係数を低くし転がりやすくする
                physicMaterial.dynamicFriction = 0;
                physicMaterial.staticFriction = 0;
                // コライダーに物理マテリアルを設定する
                var collider = sphere.GetComponent<Collider>();
                collider.material = physicMaterial;
            }
        }
    }
}

球に色をつける

球に色をつけてみましょう。

// 色をランダムに付ける
meshRenderer = sphere.GetComponent<MeshRenderer>();
meshRenderer.material.color = new Color(Random.value, Random.value, Random.value);
using UnityEngine;

public class TestComponent : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        // 床を作る
        var floor = GameObject.CreatePrimitive(PrimitiveType.Cube);
        // 10x10の大きさにする
        floor.transform.localScale = new Vector3(10, 1, 10);

        for (int x = -5; x < 5; ++x)
        {
            for (int z = -5; z < 5; ++z)
            {
                // 球のGameObjectをインスタンス生成する
                var sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                // 10x10になるように配置する
                sphere.transform.position = new Vector3(x + 0.5f, 10, z + 0.5f);

                // 重力で動くようにする
                sphere.AddComponent<Rigidbody>();

                // 物理マテリアルを生成する
                var physicMaterial = new PhysicMaterial();
                // バウンドしやすさをランダムにする
                physicMaterial.bounciness = Random.value;
                // バウンドが続くようにする
                physicMaterial.bounceCombine = PhysicMaterialCombine.Maximum;
                // 摩擦係数を低くし転がりやすくする
                physicMaterial.dynamicFriction = 0;
                physicMaterial.staticFriction = 0;
                // コライダーに物理マテリアルを設定する
                var collider = sphere.GetComponent<Collider>();
                collider.material = physicMaterial;

                // 色をランダムに付ける
                var meshRenderer = sphere.GetComponent<MeshRenderer>();
                meshRenderer.material.color = new Color(Random.value, Random.value, Random.value);
            }
        }
    }
}

画面から消えた球をDestroyする

画面から消えてもHierarchyではSphereがたくさんありますね。画面から消えたらDestroyするようにしてみましょう。

Unity EditorのProject windowで”DestoryMyself”という名前でC#Scriptを生成します。

using UnityEngine;

public class DestroyMySelf : MonoBehaviour
{
    private void OnBecameInvisible()
    {
        Destroy(this);
    }
}

これを球にアタッチすることでHierarchyから消えるようになります。

ただこの方法はうまくいくとは限りません。カメラの位置により一度も画面に入らないとこのイベントは発生しません。この他の方法では下に床を用意しOnCollisionEnterによりDestroyしたり、ShpereのY座標が閾値を越えたらDestoryする等色々あります。DestroyせずにPoolにして使いまわすこともあります。使用しないGameObjectをそのままにしておくとメモリ使用量が増え続ける可能性があります。大量にGameObjectを生成する場合はDestroyの方法も検討しましょう。

コメント