1.18 0から学ぶUnityゲーム開発 -- リソースの読み込み

前回の記事で、おそらくリソースの読み込みについて触れ始めました。シーン リソースは特別なリソースです。ビルド設定に追加するだけで、API を通じて直接読み込むことができます。

しかし、他の種類のリソースについてはどうでしょうか? 例えばオンラインゲームを作ってバックグラウンドからデータを返してもらってキャラクターに銃を設置する場合、全ての銃をメンバーデータとして割り当てることは不可能なので、必ずどれを使用するかを読み込みたいので、現時点では、同様の名前またはパスによるリソースのロードをサポートする必要があります。

したがって、この章では、Unity にどのようなリソースがあるのか​​、それらをロードする方法、およびいくつかのロード方法が適用できるシナリオについて説明します。

参照によるロード

これまでの章では、特定のリソースを使用したい場合、コードにメンバー変数を追加し、Unity のシリアル化機能を利用してエディター パネルに表示し、シーンまたはプロジェクトにオブジェクトをドラッグ アンド ドロップします。ウィンドウ。リソースは対応する変数に割り当てられます。リソースをロードするこのメソッドは参照によってロードされます。

以前に実際のシーン ファイルを分析しました。ゲームオブジェクトであってもコンポーネント クラスであっても、シリアル化中に一意の ID が生成されます。この ID は参照関係を保存するために使用され、シーンの開始時に作成されます。既存のゲームオブジェクトをロードします。シーンを作成し、ファイル内の ID データに従ってすべての参照関係にインデックスを付けます。

しかし問題があり、実際に以前シーン内のオブジェクトのコンポーネント変数にPrefabを使って代入したのですが、その参照関係はどうなっているのでしょうか?

Demo.unity ファイルをテキスト モードで開き、箇条書きを割り当てた FireController オブジェクトの FireController コンポーネントを見つけてもよいでしょう。

ここでも fileID が表示されていることがわかりますが、シーン ファイル内でこの fileID の 2 番目の使用を検索することはできません。結局のところ、ここで割り当てられたプレハブはシーンではなくプロジェクト ウィンドウに存在するので、そこに注意を払います。グローバル検索が得意な友人は、Assets ディレクトリ全体を検索しようとすると、すぐにこの GUID が Bullet.prefab.meta ファイルに存在することがわかるでしょう。

開いて内容を確認すると、次のようになります。

このメタ ファイルに記録されている GUID が、シーン内のプレハブを参照する変数に格納されている GUID と一致していることがわかります。また、Bullet.prefab を再度開くと、fileID に対応するプレハブ上のコンポーネントを見つけることができます。

このとき実際に理解しているのは、シーン以外で直接参照できるリソースについては、シーン外のリソースファイルにはそのリソースのguidを格納した.metaファイルがあり、シーン外のリソースを参照する方法はこのガイドで検索してください。

Assets フォルダー内のすべてのファイルには .meta ファイルが含まれていることがよくわかります。これは、フォルダーを含むすべてのファイルが Unity で参照できることを意味します。

これは、ゲーム プロジェクトを git や svn、p4 などのバージョン管理システムにアップロードする必要がある場合、.meta ファイルをアップロードする必要があることも説明しています。アップロードされていない場合、他の人がプロジェクトを開いたときに、Unity新しい .meta ファイルが自動的に生成されます。その時点で、guid によって参照されるすべてのリソースは無効になります。

もちろん、.meta ファイルには GUID 情報だけでなく、他の多くの情報も保存されます。詳細については、各リソース タイプの高度なチュートリアルで後ほど説明します。

Unity がシーン内外のリソースの参照をどのように処理するかを理解すると、なぜパッケージ化できるのかを実際に理解できるようになります。Unity パッケージは、ビルド設定で追加されたシーンからすべてのリソース参照を検索し、使用されるすべてのリソースがパッケージ化されるからです。最終的なゲームパッケージ。

リソースフォルダー

コード メンバー内でコンポーネントやゲームオブジェクト、プレハブ リソースを直接参照していない場合、プレハブやその他のリソースを動的にロードするにはどうすればよいでしょうか? Unity には、Resources という名前のフォルダーという特別な暗黙のルールが用意されています。Assets ディレクトリでは、Resources という名前のフォルダーであれば問題なく、異なるディレクトリに複数の Resources フォルダーが同時に存在することができます。これらのファイルは、Unity によって均一に認識されます。その後、Resources.Load API を使用して内部のリソースをロードできます。

Unity - スクリプト API: Resources.Load docs.unity3d.com/ScriptReference/Resources.Load.html

新しいシーンをロードするのと少し似ています。相対パスを使用して Resources フォルダーの内容をロードできます。パスでは、パス区切り文字として \ の代わりに / を使用する必要があることに注意してください。

例えば:

  1. Assets/Test1/Resources/a.prefab の場合、ロード時にファイル拡張子なしで を使用します。
  2. Assets/Test1/Resources/BB/a.prefab の場合、ロード時に BB/a を使用します
  3. Assets/Test2/Resources/BB/a.prefab の場合、2 と競合し、Resources フォルダー内のすべてのファイルが同じ相対パスを持つことはできないと Unity から通知されます。

OK、試してみましょう。以前は、Bullet はメンバー変数に直接割り当てられていました。今では、Prefab リソースを Resources フォルダーに置きます。現在はリソース フォルダーがないので、新しい Resources フォルダーを作成します。 [プロジェクト] ウィンドウで [作成] > [フォルダー] をクリックし、Bullet プレハブ ファイルをそのフォルダーに直接ドラッグします (これはカットと同じです)。

Windows エクスプローラーでこの操作を直接実行している場合は、対応する .meta ファイルもカットする必要があることに注意してください。また、この .meta ファイルにはこのリソースの guid 情報が含まれているとも言いました。カットしない場合 カットされている場合離れてしまうと、元の参照関係は見つかりません (リソースとともに直接ロードされますが、影響しない可能性があります)。.meta ファイルは、リソースを切り取るときに自動的に処理されるため、Unity のプロジェクト ウィンドウには表示されません。

次に、前に弾丸を作成した FireController のコードを変更する必要があります。

using UnityEngine;
using Object = UnityEngine.Object;

public class FireController : MonoBehaviour
{
    private bool isMouseDown = false;
    private float lastFireTime = 0f;
    private Vector3 fireDirection;
    private AddVelocity bullet;
    public string bulletResourcesPath;
    public float fireInterval = 0.1f;
    public Transform fireBeginPosition;

    private void Start()
    {
        bullet = Resources.Load<AddVelocity>(bulletResourcesPath);
    }

    void Update()
    {
        if (Input.GetButton("Fire1"))
        {
            if (!isMouseDown)
            {
                isMouseDown = true;
                lastFireTime = Time.time;
                Fire();
            }
            else if (Time.time - lastFireTime > fireInterval)
            {
                lastFireTime = Time.time;
                Fire();
            }
        }
        else
        {
            isMouseDown = false;
        }
    }

    void Fire()
    {
        // 在这里实现每次触发的逻辑

        // 创建新的子弹,每次都是从模板bullet复制一个出来
        AddVelocity newBullet = Object.Instantiate(bullet);
        newBullet.transform.position = fireBeginPosition.position;
        newBullet.SetDirection(fireDirection);
    }

    public void SetDirection(Vector3 direction)
    {
        fireDirection = direction;
    }
}

私たちの変更は主に、以前のパブリック メンバーの箇条書きをプライベート メンバーに置き換えることです。このメンバーをシリアル化する必要はなくなりました。代わりに、文字列メンバーを使用して、エディターがリソース パスを入力できるようにします。

次に、Start メソッドの Resources.Load を通じてこのリソースを 1 回ロードします。その後の処理は前のメソッドと同じです。Resources.Load メソッドはジェネリック型、または C++ 用語でテンプレート型を持ちます。<> で満たされた型は、GetComponent と同様のメソッドを使用して、ロードされたゲームオブジェクトから取得されます。当然、ゲームオブジェクトをロードする必要があります。 <> には GameObject の種類を入力できます。

OK、エディターで箇条書きのリソース パス Bullet を直接入力しましょう。

もう一度実行すると、箇条書きも作成でき、以前と同じ効果が得られることがわかります。

この読み込み方法には欠点があり、Resources フォルダーに置かれたリソースは参照されているかどうかは関係なく、ゲームをパッケージ化するときにパッケージ化されてしまうため、Unity ではどれを使用するかわからないため、この方法を使用します。は、小規模なボリュームのリソースに適しています。

資産データベース

エディターモードでの専用リソースロードメソッドは、主にエディター内での拡張や機能操作に使用され、通常のゲーム動作ロジックとは独立していますが、エディターのゲームランタイムの概念に関わるため、本章では説明を省略します。エディター拡張機能の開発を具体的に説明するときまで保存しておきます。

アセットバンドル

Unity が提供するオーソドックスなゲームは、ゲームをパッケージ化してリリースした後に通常のリソースをロードする方式ですが、理解するのが非常に面倒な概念が多く、この章の一連の記事はまだ初期段階にあるため、これについては説明しません。ゲームのパッケージングについては後ほど詳しく説明することにし、リソース管理についてもう一度話しましょう。

考える質問

  1. Resources.Load はリソースを同期的に読み込み、コードの実行をブロックします。当然、公式 API には非同期バージョンがあります。非同期に変更した場合はどのように記述すればよいでしょうか?

次の章

上記では、参照による自動読み込みとパスによる動的読み込みの 2 つのリソース読み込み方法について説明しました。Resources.Load はイライラさせられますが、この段階ではまず Unity のリソース読み込みを学習するだけで十分です。

次の章では、エディター拡張機能について簡単に紹介します。Unity エディターは変更されていませんが、コードを通じて必要に応じて調整できます。これは、最新の商用ゲーム エンジンによって提供されるエディター拡張機能でもあります。拡張機能を通じて、私たちは、カスタマイズされたニーズにエンジンをより適切に対応させることができます。もちろん、エディタのロジックとゲームのロジックの違いも学びます。

おすすめ

転載: blog.csdn.net/z175269158/article/details/130258917