Unityで2Dサンドゲーム(砂場)を作成。Part2.大量の砂を作成

当ページのリンクには広告が含まれています。

Unity2Dで「砂場」を作成するPart2です。今回は大量の砂を生成してみます。

はじめに

前回の続きのPart2を作成していきます。Part1は下記から。

Part1ではLow-level2DPhysics(PhysicsCore2D)の簡単な動作確認をしました。

作成開始

Part2では「大量の砂」を生成していきます。

土台の作成

簡単な土台を作成します。スクリプトを下記に変更します。受け皿を作成しています。

using UnityEngine;
#if UNITY_6000_5_OR_NEWER
using Unity.U2D.Physics;
#else
using UnityEngine.LowLevelPhysics2D;
#endif

public class Manager : MonoBehaviour
{
    private PhysicsWorld World;

    private void Start()
    {

        World = PhysicsWorld.defaultWorld;
        World.drawFillOptions = PhysicsWorld.DrawFillOptions.Interior;

        CreateFiled();

    }

    private void CreateFiled()
    {

        PhysicsShapeDefinition shapeDef = PhysicsShapeDefinition.defaultDefinition;

        PhysicsBody body = World.CreateBody();

        var boxTransform = new PhysicsTransform(new Vector2(-6f, 0f), PhysicsRotate.identity);
        var boxGeometry = PolygonGeometry.CreateBox(new Vector2(0.2f, 5f), radius: 0f, transform: boxTransform);
        body.CreateShape(boxGeometry, shapeDef);

        boxTransform = new PhysicsTransform(new Vector2(0f, -2.5f), PhysicsRotate.identity);
        boxGeometry = PolygonGeometry.CreateBox(new Vector2(12f, 0.2f), radius: 0f, transform: boxTransform);
        body.CreateShape(boxGeometry, shapeDef);

        boxTransform = new PhysicsTransform(new Vector2(6f, 0f), PhysicsRotate.identity);
        boxGeometry = PolygonGeometry.CreateBox(new Vector2(0.2f, 5f), radius: 0f, transform: boxTransform);
        body.CreateShape(boxGeometry, shapeDef);
    }
}

実行して下記の様に表示されたらOKです。

砂を作成

土台の中に砂を生成します。スクリプト内に下記の関数を作成します。中央に小さな円(砂)を生成して自然落下します。スクリプト内で色の指定、サイズの指定をしています。(スクリプト一部抜粋)

    private void CreateSand()
    {
        PhysicsBodyDefinition bodyDef = new PhysicsBodyDefinition
        { type = PhysicsBody.BodyType.Dynamic };
        bodyDef.position = new Vector2(0, 0);

        var body = World.CreateBody(bodyDef);

        var shapeDef = new PhysicsShapeDefinition
        {
            surfaceMaterial = new PhysicsShape.SurfaceMaterial
            { customColor = new Color(0.17f,0.1f,0f) }
        };
        var circleGeometry = new CircleGeometry { center = Vector2.zero, radius = 0.1f };

        body.CreateShape(circleGeometry, shapeDef);

    }

「Start」内に記述して動作を確認します。(スクリプト一部抜粋)

    private void Start()
    {

        World = PhysicsWorld.defaultWorld;
        World.drawFillOptions = PhysicsWorld.DrawFillOptions.Interior;

        CreateFiled();

        CreateSand();
    }

下記の様に

大量に生成するので最終的なスクリプトを下記の様に変更します。1000個生成しています。

using UnityEngine;
#if UNITY_6000_5_OR_NEWER
using Unity.U2D.Physics;
#else
using UnityEngine.LowLevelPhysics2D;
#endif

public class Manager : MonoBehaviour
{
    private PhysicsWorld World;
    private int MaxSand = 1000;

    private void Start()
    {
        World = PhysicsWorld.defaultWorld;
        World.drawFillOptions = PhysicsWorld.DrawFillOptions.Interior;

        CreateFiled();
    }

    private void Update()
    {
        if (MaxSand > 0)
        {
            CreateSand();
            MaxSand -= 1;
        }
    }

    private void CreateFiled()
    {

        var shapeDef = PhysicsShapeDefinition.defaultDefinition;

        var body = World.CreateBody();

        var boxTransform = new PhysicsTransform(new Vector2(-6f, 0f), PhysicsRotate.identity);
        var boxGeometry = PolygonGeometry.CreateBox(new Vector2(0.2f, 5f), radius: 0f, transform: boxTransform);
        body.CreateShape(boxGeometry, shapeDef);

        boxTransform = new PhysicsTransform(new Vector2(0f, -2.5f), PhysicsRotate.identity);
        boxGeometry = PolygonGeometry.CreateBox(new Vector2(12f, 0.2f), radius: 0f, transform: boxTransform);
        body.CreateShape(boxGeometry, shapeDef);

        boxTransform = new PhysicsTransform(new Vector2(6f, 0f), PhysicsRotate.identity);
        boxGeometry = PolygonGeometry.CreateBox(new Vector2(0.2f, 5f), radius: 0f, transform: boxTransform);
        body.CreateShape(boxGeometry, shapeDef);

        //var segmentGeometry = new SegmentGeometry { point1 = new Vector2(-8f, 4f), point2 = new Vector2(-8f, 4f) };
        //body.CreateShape(segmentGeometry, shapeDef);

    }

    private void CreateSand()
    {
        var bodyDef = new PhysicsBodyDefinition { type = PhysicsBody.BodyType.Dynamic };
        bodyDef.position = GetRandomPosition();

        var body = World.CreateBody(bodyDef);

        var shapeDef = new PhysicsShapeDefinition
        {
            surfaceMaterial = new PhysicsShape.SurfaceMaterial { customColor = new Color(0.17f,0.1f,0f)},
//            contactFilter = new PhysicsShape.ContactFilter { categories = PhysicsMask.One, contacts = PhysicsMask.All }
        };
        var circleGeometry = new CircleGeometry { center = Vector2.zero, radius = 0.1f };

        body.CreateShape(circleGeometry, shapeDef);

    }

    private Vector2 GetRandomPosition()
    {
        var x = Random.Range(-2.0f,2.0f);
        var y = Random.Range(-.5f,.5f);
        return new Vector2(x, y);
    }
}

実行して下記の様に動けばOK。

タイトルとURLをコピーしました