【Unity】2Dゲーム - Angry Birdsの教育実習(ソースコードと実装手順を超詳しく解説)

ソースコードとリソースファイルが必要な場合は、いいね、フォロー、コメントエリアにプライベートメッセージを残してください~~~

以下では、Unity3D で Angry Birds の単純なバージョンを実装します。ゲームの最も複雑な部分は物理システムですが、Unity3D エディターの助けを借りて、あまり心配する必要はありません

1.エフェクト表示

まず、次のようにプログラムの実行結果を表示します。 

プログラムを実行すると鳥を射出して軌跡を表示することができ、読者自身で最適化することができます。

 

 

2. プログラムのディレクトリ構造

階層ビューの構造は次のとおりです 

Assets フォルダーのディレクトリ構造は次の図に示されています。

 

Scriptsに格納されるC#スクリプトファイルの構造は以下のとおりです。

 Prefabsフォルダに格納されているプレハブ構造は以下のとおりです

3. 導入手順

Angry Birds は 2D ゲームであるため、新しいプロジェクトを作成するときに 2D テンプレートを選択し、次の図に示すように画像やその他のリソースが含まれるリソース パックをプロジェクトにインポートする必要があります。

 

カメラの設定

プロジェクト ビューで Scenes フォルダーを見つけ、level01.unity フォルダーを見つけてダブルクリックして設定で背景色を開きます

地面の設定

プロジェクト ビューの Sprites フォルダーで ground.png ファイルを見つけ、インスペクター ビューで設定をインポートし、ユニットあたりのピクセル数を 16 に設定して適用ボタンをクリックします。

ヒント: その後、すべてのアイコンが 16 に設定されます (これは、ゲーム世界では 16*16 ピクセルが単位であることを意味します。16 を選択した理由は、鳥のサイズが 16*16 であるためです)

地面は単なる画像であり、物理世界の一部ではありません。物が地面に衝突したり、その上に立つことはありません。そのため、物が地面に立つことができるように、物理を与えるためにコライダーを追加する必要があります。 。インスペクター ビューで、追加するコンポーネント -> Physics 2D -> Box Collider 2D コンポーネントを選択します。

境界設定

bordersという名前の空のオブジェクトを作成し、それにコライダーを追加します 操作手順は以下の通りで、Is Triggerプロパティにチェックを入れて、右と上に2つのコライダーを追加します。

次に、境界線に入るオブジェクトを破棄する機能が必要です。境界線オブジェクトをクリックします。インスペクター ビューで、[コンポーネントの新規スクリプトの追加] コマンドを選択します。スクリプトに Borders という名前を付けます。

クラウド設定

Cloud.png をシーン ビューにドラッグし、前の手順を繰り返して、好きな位置に雲を配置します。

打撃対象設定

次に、鳥が衝突するオブジェクト (木、石、氷など) を追加して、シーン ビューにドラッグします。ユニットあたりのピクセル数を 16 に設定します。また、剛体プロパティを追加し、コンポーネントの追加 -> 物理 2D -> を選択します。リジッドボディ 2D コマンド。

スリングショットの設定

slingshot.png ファイルをシーン ビューにドラッグし、ピボットを上部に設定します。

鳥を設定します

鳥の運動軌跡の衝突などの物理的特性を設定します。ここでは省略します。

敵の設定

緑の豚を敵が攻撃できるように設定し、敵のゲームロジックも設定します

スリングショットラバーセッティング

また、スリングショットにゴムを追加して、見た目がより美しく、よりリアルになるようにします。

4. コード

コードの一部は次のとおりです。すべてのソース コードとリソース ファイルが必要です。コレクションを「いいね」してフォローし、コメント エリアにプライベート メッセージを残してください。

1

using UnityEngine;

public class Spawn : MonoBehaviour
{
    // 鸟的预制体
    public GameObject birdPrefab;
    // 鸟是否在触发区域
    bool occupied = false;

    void FixedUpdate()
    {
        // 鸟不在触发区域
        if (!occupied && !sceneMoving())
            spawnNext();
    }
    void spawnNext()
    {
        // 生成一只鸟
        Instantiate(birdPrefab, transform.position, Quaternion.identity);
        occupied = true;
    }

    void OnTriggerExit2D(Collider2D co)
    {
        // 鸟离开触发区域
        occupied = false;
    }

    bool sceneMoving()
    {
        // 找到所有的鸟的刚体,看看是否还有仍然移动的
        Rigidbody2D[] bodies = FindObjectsOfType(typeof(Rigidbody2D)) as Rigidbody2D[];
        foreach (Rigidbody2D rb in bodies)
            if (rb.velocity.sqrMagnitude > 5)
                return true;
        return false;
    }
}

2

using UnityEngine;

public class Rubber : MonoBehaviour
{
    //橡胶预制体
    public Transform leftRubber;
    public Transform rightRubber;

    //调整橡胶旋转和长度
    void adjustRubber(Transform bird, Transform rubber)
    {
        // 橡胶的旋转变化
        Vector2 dir = rubber.position - bird.position;
        float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
        rubber.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
        // 橡胶的长度变化
        float dist = Vector3.Distance(bird.position, rubber.position);
        dist += bird.GetComponent<Collider2D>().bounds.extents.x;
        rubber.localScale = new Vector2(dist, 1);
    }

    //OnTriggerStay2D函数将通知我们鸟是否还在弹弓上
    void OnTriggerStay2D(Collider2D coll)
    {
        // 弹弓的橡胶拉伸
        adjustRubber(coll.transform, leftRubber);
        adjustRubber(coll.transform, rightRubber);
    }

    //鸟离开时触发事件
    void OnTriggerExit2D(Collider2D coll)
    {
        // 弹弓的橡胶设置为默认值
        leftRubber.localScale = new Vector2(0, 1);
        rightRubber.localScale = new Vector2(0, 1);
    }
}

3

 

using UnityEngine;

public class PullAndRelease : MonoBehaviour
{
    // 鸟的默认位置
    Vector2 startPos;
    // 添加的力
    public float force = 1300;

    void Start()
    {
        startPos = transform.position;
    }

    //监听鼠标抬起事件
    void OnMouseUp()
    {
        // 禁用isKinematic,这样刚体就会再次受到重力和速度的影响
        GetComponent<Rigidbody2D>().isKinematic = false;
        // 添加力
        Vector2 dir = startPos - (Vector2)transform.position;
        GetComponent<Rigidbody2D>().AddForce(dir * force);
        // 销毁当前组件脚本
        Destroy(this);
    }

    //监听鼠标拖拽事件
    void OnMouseDrag()
    {
        //将鼠标位置转换为世界位置
        Vector2 p = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        //设置最大半径
        float radius = 1.8f;
        Vector2 dir = p - startPos;
        if (dir.sqrMagnitude > radius)
            dir = dir.normalized * radius;
        //设置位置
        transform.position = startPos + dir;
    }
}

4

using UnityEngine;

public class Trail : MonoBehaviour
{
    //轨迹的预制体
    public GameObject[] trails;
    //使用一个计时器变量用来记录当前生成的数组下标
    int next = 0;

    void Start()
    {
        //每100毫秒生成一条新路径对象
        InvokeRepeating("spawnTrail", 0.1f, 0.1f);
    }

    void spawnTrail()
    {
        //只要鸟的移动速度够快,才去刷出轨迹
        if (GetComponent<Rigidbody2D>().velocity.sqrMagnitude > 25)
        {
            //实例化trails数组中next下标的对象
            Instantiate(trails[next], transform.position, Quaternion.identity);
            //next+1增加next
            next = next + 1;
            //next等于预制体数组最大值就从0开始
            if (next == trails.Length) next = 0;
        }
    }
}

作成するのは簡単ではありませんが、役立つと思いますので、いいね、フォロー、収集してください~~~

Supongo que te gusta

Origin blog.csdn.net/jiebaoshayebuhui/article/details/128647688
Recomendado
Clasificación