Unity は怒れる鳥を作る


参考動画: [SiKi Academy Unity] Unity Elementary Case - Angry Birds



1. プロジェクトの準備

リソースのダウンロード: http://www.sikiedu.com/course/134

新築:

ここに画像の説明を挿入

を選択し2D、プロジェクト名を入力して、プロジェクトのパスを選択します。
ここに画像の説明を挿入


リソースからImageと をMusicプロジェクト フォルダーにコピーします。

ここに画像の説明を挿入
ここに画像の説明を挿入



2、スライス

最初の章の豚と鳥の画像を選択し、次のようSprite Modeに変更しますMultipleApply
ここに画像の説明を挿入


以下のようにスライスします。
ここに画像の説明を挿入


4 つの爆発による煙が適切にセグメント化されていないことが判明したため、手動でセグメント化します。
ここに画像の説明を挿入


Apply:
ここに画像の説明を挿入


スリングショットと鳥をシーンにドラッグし、階層関係を設定します。
ここに画像の説明を挿入



3. 鳥の引きずりや飛行を実現


1. Spring Joint 2D の追加と設定

鳥のコンポーネントを追加するSpring Joint 2Dと、次の追加後に剛体コンポーネントが自動的に追加されます。
ここに画像の説明を挿入


同時に、スリングショットの右側に剛体コンポーネントを追加し、次のように設定しますStatic(重力の影響を防ぐため)。
ここに画像の説明を挿入


スリングショットの右側にあるリジッド ボディをSpring Joint 2Dにドラッグし、Spring Joint 2Dパラメータを設定します。
ここに画像の説明を挿入


2. マウスに追従する鳥の動きを実装する

コライダーとBirdスクリプトを追加します。
ここに画像の説明を挿入


bird.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Bird : MonoBehaviour
{
    
    
    private bool isClick = false;


    private void Update()
    {
    
    
        MoveWithMouse();
    }

    private void MoveWithMouse()
    {
    
    
        // 让小鸟跟随鼠标的位置
        if (isClick)
        {
    
    
            transform.position = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            transform.position += new Vector3(0, 0, -Camera.main.transform.position.z);
        }
    }

    // 鼠标按下
    private void OnMouseDown()
    {
    
    
        isClick = true;   
    }

    // 鼠标抬起
    private void OnMouseUp()
    {
    
    
        isClick = false;
    }

}

このとき、鳥をマウスでドラッグすると、鳥もマウスと一緒に移動します。


3. 鳥の最大引きずり距離を制限する


まず、鳥が回転するポイントとしてスリングショットの右側にポイントを設定します。
ここに画像の説明を挿入


Bird.csrightPos 変数と maxDis 変数を次のように宣言します

    public Transform rightPos;   // 弹弓右部点,即拖拽小鸟时让其跟着转
    public float maxDis;  // 最大推拽距离

次のように変更しますMoveWithMouse()

    private void MoveWithMouse()
    {
    
    
        // 让小鸟跟随鼠标的位置
        if (isClick)
        {
    
    
            transform.position = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            transform.position += new Vector3(0, 0, -Camera.main.transform.position.z);

            // 限定小鸟最大拖拽距离
            if (Vector2.Distance(transform.position, rightPos.position) >= maxDis)
            {
    
    
                transform.position = rightPos.position + (transform.position - rightPos.position).normalized * maxDis;
            }
        }
    }

Inspectorパネル内のスクリプトrightPosにドラッグしbirdて設定しますmaxDis。このとき、鳥はドラッグした距離に制限されます。
ここに画像の説明を挿入


4.鳥が飛び出すのを実感する

マウスを押すと、剛体の状態が動的に設定されます。
マウスアップすると、ダイナミクスが false に設定され、SpringJoint2Dコンポーネントは一定の時間が経過すると無効になります。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Bird : MonoBehaviour
{
    
    
    private SpringJoint2D springJoint;
    private Rigidbody2D rb;

    public Transform rightPos;   // 弹弓右部点,即拖拽小鸟时让其跟着转
    public float maxDis;  // 最大推拽距离


    private bool isClick = false;


    private void Start()
    {
    
    
        springJoint = GetComponent<SpringJoint2D>();
        rb = GetComponent<Rigidbody2D>();
    }

    private void Update()
    {
    
    
        MoveWithMouse();
    }

    private void MoveWithMouse()
    {
    
    
        // 让小鸟跟随鼠标的位置
        if (isClick)
        {
    
    
            transform.position = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            transform.position += new Vector3(0, 0, -Camera.main.transform.position.z);

            // 限定小鸟最大拖拽距离
            if (Vector2.Distance(transform.position, rightPos.position) >= maxDis)
            {
    
    
                transform.position = rightPos.position + (transform.position - rightPos.position).normalized * maxDis;
            }
        }
    }

    // 鼠标按下
    private void OnMouseDown()
    {
    
    
        isClick = true;
        rb.isKinematic = true;
    }

    // 鼠标抬起
    private void OnMouseUp()
    {
    
    
        isClick = false;
        rb.isKinematic = false;
        Invoke(nameof(Fly), 0.12f);
    }

    private void Fly()
    {
    
    
        springJoint.enabled = false;
    }

}


5. スリングショットのスクライビングを実現する


スリングショットのleftPosこの点に点を 1 つ作成しleftPosrightPos線を引く 2 つの点を作成します。
ここに画像の説明を挿入


leftコンポーネントを追加するにはLine Renderer:
ここに画像の説明を挿入


セット素材、色、長さ:
ここに画像の説明を挿入


そのコンポーネントを次のようにコピーしますright
ここに画像の説明を挿入
ここに画像の説明を挿入


コードを書きます:
bird.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Bird : MonoBehaviour
{
    
    
    private SpringJoint2D springJoint;
    private Rigidbody2D rb;

    [Header("弹弓")]
    public Transform rightPos;   // 弹弓右部点,即拖拽小鸟时让其跟着转; 同时画线
    public Transform leftPos;    // 弹弓左部点, 画线
    public LineRenderer leftLine;
    public LineRenderer rightLine;

    [Space]
    public float maxDis;  // 最大推拽距离


    private bool isClick = false;


    private void Start()
    {
    
    
        springJoint = GetComponent<SpringJoint2D>();
        rb = GetComponent<Rigidbody2D>();
    }

    private void Update()
    {
    
    
        MoveWithMouse();
    }

    private void MoveWithMouse()
    {
    
    
        // 让小鸟跟随鼠标的位置
        if (isClick)
        {
    
    
            transform.position = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            transform.position += new Vector3(0, 0, -Camera.main.transform.position.z);

            // 限定小鸟最大拖拽距离
            if (Vector2.Distance(transform.position, rightPos.position) >= maxDis)
            {
    
    
                transform.position = rightPos.position + (transform.position - rightPos.position).normalized * maxDis;
            }

            DrawLine();
        }
    }

    // 鼠标按下
    private void OnMouseDown()
    {
    
    
        isClick = true;
        rb.isKinematic = true;
    }

    // 鼠标抬起
    private void OnMouseUp()
    {
    
    
        isClick = false;
        rb.isKinematic = false;
        DeleteLine();  // 删除弹弓的线
        Invoke(nameof(Fly), 0.12f);
    }

    // 飞出
    private void Fly()
    {
    
    
        springJoint.enabled = false;
    }

    // 画线
    private void DrawLine()
    {
    
    
        // 设置线的两个端点
        leftLine.SetPosition(0, leftPos.position);
        leftLine.SetPosition(1, transform.position);

        rightLine.SetPosition(0, rightPos.position);
        rightLine.SetPosition(1, transform.position);
    }

    // 删除线
    private void DeleteLine()
    {
    
    
        leftLine.SetPosition(1, leftPos.position);
        rightLine.SetPosition(1, rightPos.position);
    }
}

この時、鳥をドラッグすると普通に線が引けて、鳥を離すと線が消えます。


6. 鳥が繰り返し引きずるのを防ぎます


このとき、鳥をドラッグして放した後、もう一度鳥を長押しするとスリングショットに戻ります。

このバグを修正するには、bird に bool パラメータを追加します。

    private bool flied = false;  // 是否飞过,用以让小鸟不能重复拖拽

マウスを離した後、true に設定します。

    // 鼠标抬起
    private void OnMouseUp()
    {
    
    
        isClick = false;
        flied = true;
        rb.isKinematic = false;
        DeleteLine();  // 删除弹弓的线
        Invoke(nameof(Fly), 0.12f);
    }

マウスが押された後、それがfliedすでに true である場合、効果はありません。

    // 鼠标按下
    private void OnMouseDown()
    {
    
    
        if (flied)
            return;
        isClick = true;
        rb.isKinematic = true;
    }

この時点で、鳥をドラッグできるのは 1 回だけです。



4. シーンの構築


カットするシーン 1 を選択します。
ここに画像の説明を挿入


地面をドラッグしてコライダーを追加します。
ここに画像の説明を挿入


プレハブ関連のフォルダーを作成し、次の場所にドラッグします。
ここに画像の説明を挿入


地面を設定します。
ここに画像の説明を挿入


同様に、空を設定します。
ここに画像の説明を挿入



5.鳥の攻撃豚を実現する


豚を追加し、関連コンポーネントを追加してレイヤーを設定します。
ここに画像の説明を挿入


鳥と豚が停止せずに地面を転がることを防ぐために、鳥と豚の両方の角の抵抗を 2 に設定します。
ここに画像の説明を挿入


1. 豚の負傷と死亡


Pigpig にスクリプトを追加します。
ここに画像の説明を挿入


豚が鳥に襲われたときに負傷して死亡する相対速度を設定します。

    public float hurtSpeed = 5.0f;  // 受伤速度
    public float deadSpeed = 10.0f;  // 死亡速度

豚が負傷した後の写真を設定します。

    // 受伤图片
    public Sprite hurtSprite;

ここに画像の説明を挿入


対応する煙の画像をシーンにドラッグします。
ここに画像の説明を挿入

boomアニメーションを作成します。
ここに画像の説明を挿入


開いてAnimation、それに応じて調整します。
ここに画像の説明を挿入


同時にアニメーションのループをキャンセルします。
ここに画像の説明を挿入


Boomスクリプトを追加しますBoom
ここに画像の説明を挿入


コードを書きます:
Boom.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Boom : MonoBehaviour
{
    
    
    public void DestorySelf()
    {
    
    
        Destroy(gameObject);
    }
}

に設定してAnimation、再生後にこの関数を実行します。つまり、それ自体を破棄します。
ここに画像の説明を挿入

Boomオブジェクトをプレハブにします。
ここに画像の説明を挿入


豚の死のロジック:

相対速度が死亡速度より大きい場合: 豚は死亡します;
相対速度が負傷速度よりも大きい場合: この時点で豚が負傷すると死亡します、そうでない場合は負傷します

ではPig.cs、豚の怪我と死を実感してください。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Pig : MonoBehaviour
{
    
    
    private SpriteRenderer spriteRenderer;

    // 受伤图片
    public Sprite hurtSprite;
    public GameObject boomPrefab;

    [Header("相对速度")]
    public float hurtSpeed = 5.0f;  // 受伤速度
    public float deadSpeed = 10.0f;  // 死亡速度

    private bool isHurt = false;

    private void Start()
    {
    
    
        spriteRenderer = GetComponent<SpriteRenderer>();
    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
    
    
        float relativeV = collision.relativeVelocity.magnitude;
        print(relativeV);
        // 大于死亡速度
        if (relativeV >= deadSpeed)
        {
    
    
            Dead();
        }
        // 大于受伤速度
        else if (relativeV >= hurtSpeed)
        {
    
    
            if (isHurt)
                Dead();
            else
            {
    
    
                isHurt = true;
                spriteRenderer.sprite = hurtSprite;
            }
        }
    }

    // 死亡,生成爆炸动画和分数
    private void Dead()
    {
    
    
        Instantiate(boomPrefab, transform.position, Quaternion.identity);
        Destroy(gameObject);
    }

}

2. 豚のボーナスポイント

部分画像を切り取る:
ここに画像の説明を挿入


スコアをドラッグしてプレハブにします。
ここに画像の説明を挿入


pig.csコードを書きます:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Pig : MonoBehaviour
{
    
    
    private SpriteRenderer spriteRenderer;

    // 受伤图片
    public Sprite hurtSprite;
    public GameObject boomPrefab;
    public GameObject scorePrefab;

    [Header("相对速度")]
    public float hurtSpeed = 5.0f;  // 受伤速度
    public float deadSpeed = 10.0f;  // 死亡速度

    private bool isHurt = false;

    [Space]
    public float scoreYOffset = 0.65f;  // 分数相对猪的Y位置

    private void Start()
    {
    
    
        spriteRenderer = GetComponent<SpriteRenderer>();
    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
    
    
        float relativeV = collision.relativeVelocity.magnitude;
        print(relativeV);
        // 大于死亡速度
        if (relativeV >= deadSpeed)
        {
    
    
            Dead();
        }
        // 大于受伤速度
        else if (relativeV >= hurtSpeed)
        {
    
    
            if (isHurt)
                Dead();
            else
            {
    
    
                isHurt = true;
                spriteRenderer.sprite = hurtSprite;
            }
        }
    }

    // 死亡,生成爆炸动画和分数
    private void Dead()
    {
    
    
        GameManager.instance.pigs.Remove(this);
        Instantiate(boomPrefab, transform.position, Quaternion.identity);
        GameObject scoreObject = Instantiate(scorePrefab, transform.position + new Vector3(0, scoreYOffset, 0),
            Quaternion.identity);
        Destroy(scoreObject, 1.5f);
        Destroy(gameObject);
    }

}


6.複数の鳥の制御を実現

鳥をプレハブとして作成し、コピーを 2 つ作成します。

ここに画像の説明を挿入


空のオブジェクトを作成しGame Manager、新しいオブジェクトを作成して、GameManagerスクリプトをハングします。
ここに画像の説明を挿入

シングルトン パターンを使用して、鳥と豚をリストに保存します。

public class GameManager : MonoBehaviour
{
    
    
    public static GameManager instance;

    public List<Bird> birds;
    public List<Pig> pigs;


    private void Awake()
    {
    
    
        instance = this;
    }

}

と書き込みBird、鳥を数秒間飛び出させて破壊し、爆発アニメーションを生成して、GameManagerリストから削除します。


    private bool isClick = false;
    private bool flied = false;  // 是否飞过,用以让小鸟不能重复拖拽

    // 飞出
    private void Fly()
    {
    
    
        springJoint.enabled = false;
        Invoke(nameof(DestroySelf), flyTime);
    }
    
    // 飞出5秒后销毁
    private void DestroySelf()
    {
    
    
        GameManager.instance.birds.Remove(this);
        Instantiate(boomPrefab, transform.position, Quaternion.identity);
        Destroy(gameObject);
    }

同様に、豚が死亡した場合も、GameMangerリストから削除する必要があります。

    // 死亡,生成爆炸动画和分数
    private void Dead()
    {
    
    
        GameManager.instance.pigs.Remove(this);
        Instantiate(boomPrefab, transform.position, Quaternion.identity);
        GameObject scoreObject = Instantiate(scorePrefab, transform.position + new Vector3(0, scoreYOffset, 0),
            Quaternion.identity);
        Destroy(scoreObject, 1.5f);
        Destroy(gameObject);
    }

ではGameManager、最初に最初のバードを有効にし、他のバード スクリプトと SpringJoint を無効にし、バードが破壊された後のゲームの状態と次のバードを有効にするかどうかを判断します
GameManager.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    
    
    public static GameManager instance;

    public List<Bird> birds;
    public List<Pig> pigs;

    private Vector3 originBirdPos;  // 小鸟初始位置

    private void Awake()
    {
    
    
        instance = this;
        if (birds.Count > 0)
            originBirdPos = birds[0].transform.position;
        InitBird();
    }

    // 初始化小鸟
    private void InitBird()
    {
    
    
        for(int i = 0; i <birds.Count; i++)
        {
    
    
            if (i == 0)
            {
    
    
                birds[i].transform.position = originBirdPos;
                birds[i].enabled = true;
                birds[i].GetComponent<SpringJoint2D>().enabled = true;
            }
            else
            {
    
    
                birds[i].enabled = false;
                birds[i].GetComponent<SpringJoint2D>().enabled = false;
            }
        }
    }

    // 判断游戏状态 及 是否启用下一只小鸟
    public void Next()
    {
    
    
        if (pigs.Count == 0)
        {
    
    
            // 游戏胜利
        }
        else
        {
    
    
            if (birds.Count == 0)
            {
    
    
                // 游戏失败
            }
            else
            {
    
    
                InitBird();
            }
        }
    }

}

鳥が破壊された後、`Next()`: `bird.cs` を呼び出します。
    // 飞出5秒后销毁
    private void DestroySelf()
    {
    
    
        GameManager.instance.birds.Remove(this);
        GameManager.instance.Next();
        Instantiate(boomPrefab, transform.position, Quaternion.identity);
        Destroy(gameObject);
    }

最後に、Inspector鳥と豚をパネル内にドラッグすると、複数の鳥を正常に制御できるようになります。



7. バードトレイルの実施

マテリアルに Unity パッケージをインポートします。
ここに画像の説明を挿入

ここに画像の説明を挿入

を追加するだけですWeapon Trail:
ここに画像の説明を挿入


Trail Rendererコンポーネントを鳥に追加します。
ここに画像の説明を挿入


末尾の素材、長さ、幅を設定します。
ここに画像の説明を挿入


他のプレハブを同時にロードします。
ここに画像の説明を挿入


後続効果:
画像の説明を追加してください



8. 豚の家を建てる


切断:
ここに画像の説明を挿入


角材を例に挙げます。
ここに画像の説明を挿入


Pig.csbool の isPig をスクリプトに追加して、木のブロックも使用できるようにします。

    [Space]
    public bool isPig = false;
    
    // 死亡,生成爆炸动画和分数
    private void Dead()
    {
    
    
        if (isPig)
            GameManager.instance.pigs.Remove(this);
        Instantiate(boomPrefab, transform.position, Quaternion.identity);
        GameObject scoreObject = Instantiate(scorePrefab, transform.position + new Vector3(0, scoreYOffset, 0),
            Quaternion.identity);
        Destroy(scoreObject, 1.5f);
        Destroy(gameObject);
    }

前の豚を確認してくださいisPig:
ここに画像の説明を挿入


スクリプトをチェックせずに木にマウントしisPig、hartSpeed などのパラメータを設定します。
ここに画像の説明を挿入

Wood にはコンポーネントが必要です: Rigidbody、Collider、Pig スクリプト


同様に他の項目も追加していきます。

セットアップする簡単なシナリオは次のとおりです。
ここに画像の説明を挿入


実行結果:
画像の説明を追加してください



9. ゲームの勝利と失敗のインターフェース


1. 勝敗の基本画面を表示


切断:

ここに画像の説明を挿入


UIを作成します(第15章を参照)。

Lose UI:
画像の説明を追加してください


Win UI:
画像の説明を追加してください


ゲームに勝利した場合、レベル内に残っている鳥の数に応じて獲得すべき星の数を判断します。GameManager.csコードの一部は次のとおりです。

    [Header("UI")]
    public GameObject winUI;
    public GameObject loseUI;

    [Header("胜利得到星星的数量需要的小鸟存活数")]
    public int birdNumOf3Star;
    public int birdNumOf2Star;

    // 判断游戏状态 及 是否启用下一只小鸟
    public void Next()
    {
    
    
        if (pigs.Count == 0)
        {
    
    
            // 游戏胜利
            winUI.SetActive(true);
        }
        else
        {
    
    
            if (birds.Count == 0)
            {
    
    
                // 游戏失败
                loseUI.SetActive(true);
            }
            else
            {
    
    
                InitBird();
            }
        }
    }

    public void WinLevel()
    {
    
    
        if (birds.Count >= birdNumOf3Star)  // 3颗星星
        {
    
    

        }
        else if (birds.Count >= birdNumOf2Star) // 2颗
        {
    
    

        }
        else // 1颗
        {
    
    

        }
    }

一方、Win UIを作成するスクリプトの場合Win.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Win : MonoBehaviour
{
    
    
    // 动画播放完(显示UI后) 显示星星
    public void ShowStar()
    {
    
    
        GameManager.instance.WinLevel();
    }
}

アニメーションの終了後に呼び出されます。
ここに画像の説明を挿入


2.スター粒子効果


星を切る:
ここに画像の説明を挿入


3 つの星の配置:
ここに画像の説明を挿入


https://www.bilibili.com/video/BV1qb411c76x?p=16のエピソード 16 ~ 18に従って星のパーティクル エフェクトを設定します。


3. スター表示


ではGameManager.cs、コルーチンを使用して 0.7 秒ごとに星を表示します。

    public GameObject[] starsUI = new GameObject[3];
    
    public void WinLevel()
    {
    
    
        if (birds.Count >= birdNumOf3Star)  // 3颗星星
        {
    
    
            StartCoroutine("ShowTheStar", 3);
        }
        else if (birds.Count >= birdNumOf2Star) // 2颗
        {
    
    
            StartCoroutine("ShowTheStar", 2);
        }
        else // 1颗
        {
    
    
            StartCoroutine("ShowTheStar", 1);
        }
    }

    // 每隔0.7秒,显示一颗星星
    IEnumerator ShowTheStar(int num)
    {
    
    
        for(int i = 0; i < num; i++)
        {
    
    
            starsUI[i].SetActive(true);
            yield return new WaitForSeconds(0.7f);
        }
    }

Insepctor星をパネルにドラッグします
ここに画像の説明を挿入


この時点では、星は通常どおりに表示されます。

画像の説明を追加してください




10.一時停止インターフェイス


1. インターフェースとアニメーション

P20

一時停止ボタン:

ここに画像の説明を挿入


一時停止パネル:

ここに画像の説明を挿入


一時停止アニメーションを実装します。

ここに画像の説明を挿入

継続アニメーションを実装します。

ここに画像の説明を挿入


どちらのアニメーションもループされていません。

ここに画像の説明を挿入


2.一時停止と再開を実装する


Animator2 つのパラメータを作成しTrigger、2 つのアニメーションを接続します。

ここに画像の説明を挿入


アニメーションの一時停止と再開の間の関係:

ここに画像の説明を挿入

ここに画像の説明を挿入


PausePanleスクリプトを作成して次のように入力しますPause Panel

ここに画像の説明を挿入

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PausePanel : MonoBehaviour
{
    
    
    private Animator anim;

    // Start is called before the first frame update
    void Start()
    {
    
    
        anim = GetComponent<Animator>();
    }


    // 点击继续按钮
    public void Resume()
    {
    
    
        anim.SetTrigger("resume");
    }

    // 继续动画结束后,调用
    public void AfterResume()
    {
    
    
        this.gameObject.SetActive(false);
        anim.SetTrigger("pause");  // 切换回暂停动画,下次active true时则调用暂停动画
    }

}

GameManager.csコードを次の場所に追加します。

    [Space]
    public GameObject pausePanel;

    // 暂停按钮调用函数
    public void PauseGame()
    {
    
    
        pausePanel.SetActive(true);
    }

Inspectorパネルで、以下をドラッグしますPause Panel

ここに画像の説明を挿入


一時停止メソッドPause Btnのクリック イベントを追加するには:GameManager

ここに画像の説明を挿入


Resume Btnクリック イベントを追加するには、Pause Panelメソッドに対して次のようにしPauseます。

ここに画像の説明を挿入


Resumeアニメーションの最後に、AfterResume関数を呼び出します。

ここに画像の説明を挿入


効果:

画像の説明を追加してください


3. 再起動レベルの実装


再起動レベルのメソッドを次のように追加しますGameManager.cs

using UnityEngine.SceneManagement;

    // 重启关卡
    public void RestartLevel()
    {
    
    
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    }

各再起動ボタンで呼び出されます。
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入


実行結果:
画像の説明を追加してください



11. カメラフォロー


1.最初の鳥を追いかけます

開くPackage Manager
ここに画像の説明を挿入


ダウンロードCinemachine
ここに画像の説明を挿入


を追加します2D Camera:
ここに画像の説明を挿入


最初の鳥をドラッグしFollow、カメラが鳥を追跡できるようにします。
ここに画像の説明を挿入


いくつかのパラメータを調整して、適切な位置を選択します。
ここに画像の説明を挿入


同時に、 という名前の空のオブジェクトを作成し、それに衝突ボディをCamera BG追加してチェックし、それをカメラの範囲として使用します (つまり、鳥がこの範囲を超えると、カメラは追従しません)。PolygonIs Trigger
ここに画像の説明を挿入


先ほどの手順でCM vcam1、次を追加しますCinemachineConfiner
ここに画像の説明を挿入


Camera BGドラッグするだけです:
ここに画像の説明を挿入


2. 複数の鳥を順番に追跡します

で紹介されましたGameManager:

using Cinemachine;

エラーが報告された場合は、Cinemachineサンプル プログラム シーンをインポートします。
ここに画像の説明を挿入


GameManager.cs変更されたコード:

using Cinemachine;

    [Header("相机和弹弓")]
    public CinemachineVirtualCamera virtualCamera;
    public Transform slingshotLeftPos;    // 弹弓左部点,用于小鸟死后视角回到弹弓

    // 初始化小鸟
    private void InitBird()
    {
    
    
        for(int i = 0; i <birds.Count; i++)
        {
    
    
            if (i == 0)
            {
    
    
                birds[i].transform.position = originBirdPos;
                birds[i].enabled = true;
                birds[i].GetComponent<SpringJoint2D>().enabled = true;
                virtualCamera.Follow = birds[i].transform;  // 相机跟随小鸟
            }
            else
            {
    
    
                birds[i].enabled = false;
                birds[i].GetComponent<SpringJoint2D>().enabled = false;
            }
        }
    }
    
	// 判断游戏状态 及 是否启用下一只小鸟
    public void Next()
    {
    
    
        virtualCamera.Follow = slingshotLeftPos;
        virtualCamera.transform.position = slingshotLeftPos.position;

        if (pigs.Count == 0)
        {
    
    
            // 游戏胜利
            winUI.SetActive(true);
        }
        else
        {
    
    
            if (birds.Count == 0)
            {
    
    
                // 游戏失败
                loseUI.SetActive(true);
            }
            else
            {
    
    
                InitBird();
            }
        }
    }

最終的なデモ効果:

画像の説明を追加してください



参考

[SiKi Academy Unity] Unity エレメンタリーケース - Angry Birds

おすすめ

転載: blog.csdn.net/weixin_46628481/article/details/122272140