This document is about: PUN 1
SWITCH TO

PUN Classic (v1)、PUN 2、Boltはメンテナンスモードとなっております。Unity2022についてはPUN 2でサポートいたしますが、新機能が追加されることはありません。お客様のPUNプロジェクトおよびBoltプロジェクトが停止することはなく、将来にわたってパフォーマンス性能が落ちることはありません。 今後の新しいプロジェクトについては、Photon FusionまたはQuantumへ切り替えていただくようよろしくお願いいたします。

5-プレイヤーの構築

このセクションでは、このチュートリアルで使用するPlayer[プレハブ] を一から作成し、作成プロセスのすべてのステップを説明します。

PUNに接続していなくても動作するPlayer [プレハブ] の作成を試みるのは良いことです。
そうすれば、テストやデバッグを簡単におこなえて、ネットワーク機能なしで動作することができます。 そこから構築を進めて修正を加え、それぞれの機能をネットワーク対応のキャラクターに合わせていきます。
通常、ユーザ入力は他のプレイヤーのコンピュータではなく、プレイヤーが所有するインスタンスでのみ有効にするべきです。
以下で詳細を説明します。

プレハブの基本

PUNについて最初に知るべきなのは、[プレハブ]がネットワーク上でインスタンス化されるためには、プレハブがResourcesフォルダ内に存在する必要があるということです。

Resources内に[プレハブ] を置く場合のもう1つの重要な点は、その名前に注意が必要ということです。
AssetsのResourcesパス内の[プレハブ]の名前が重複してしまうと、Unityは最初に見つけた方を選びます。Project AssetsのResourcesフォルダパス内でPrefabの名前が重複しないよう注意してください。後ほど詳細について説明します。

Unityが無料のアセットとして提供するKyle Robotを使用します。
これは、3ds Max、Maya、cinema4dなどの3Dソフトウェアによって生成されるFbxファイルとして付属しています。
このチュートリアルではこれらのツールでおこなうメッシュやアニメーションの作成については説明しませんが、自身のキャラクターやアニメーションを作成するためには必須の作業です。
この「Robot Kyle.fbx」は 「/Assets/Photon Unity Networking/Demos/Shared Assets/」にあります。

Kyle Robot Fbx Asset
Kyle Robot Fbxアセット

プレイヤー向けにKyle Robot.fbxの使用を開始する1つの方法:

1.「Project Browser」のどこかに、「Resources」という名前のフォルダを作成します。通常は、コンテンツを組織することを推奨しているので'DemoAnimator_tutorial/Resources/'というような形になります。
2. /PunBasics_tutorial/Scenes/ に新しい空のシーンを作成し、Kyle Testとして保存します。
「Kyle Test」シーンの目的は、プレハブを作成して設定することです。
これが完了すると、このシーンを削除することができます。
3.Robot Kyleを「Scene Hierarchy」にドラッグアンドドロップします。
4. Hierarchyで作成したGameObjectの名前をMy Robot Kyleに変更します。
5. My Robot Kyleを*/PunBasics_tutorial/Resources/* にドラッグアンドドロップします。

これで、Kyle RobotFbxアセットにもとづいたPrefabの作成が完了し、そのインスタンスがKyle TestシーンのHierarchyに作成できました。
それでは、作業を開始しましょう。

CharacterController

1.[プレハブ] に直接おこなうこともできますが、その場合は微調整をする必要が生じます。
このため、ここではより速い方法でおこないます。


このコンポーネントはAnimatorを使用してより速い動きのキャラクターを作成する、Unityが提供するStandard Assetです。この便利な機能を使用してみましょう。

2.My Kyle Robotをダブルクリックして、 Scene Viewをズームインします。"Capsule Collider"が足にセンタリングしていることを確認してください。
"Capsule Collider"を適切にキャラクターに合致させる必要があります。
3.CharacterController ComponentCenter.yプロパティを1に変更します (Heightプロパティの半分)。

  1. 加えた変更を反映させるため、「Apply」を押します。
    My Kyle Robotプレハブのインスタンスを編集しましたが、これらの変更はすべてのインスタンスに加える必要があるので、これは非常に重要なステップです。このため、「Apply」を押しました。

    Apply Prefab Changes
    プレハブ変更を適用

Animatorの設定

Animator Controllerの割り当て

Kyle Robot Fbxアセットは、Animator Graphによって制御する必要があります。
このチュートリアルではこのグラフの作成については説明しないため、このコントローラーが提供されています。これは、 Photon Unity Networking/Demos/PunBasics/Animator/ の中にKyle Robotという名前で用意されています。

AnimatorController
AnimatorController

[プレハブ]にこの Kyle Robotコントローラーを割り当てるには、Animator Componentのプロパティ コントローラーKyle Robotを指すようにプロパティのコントローラーを設定します。

Assigning AnimatorController
AnimatorControllerの割り当て

この設定をMy Kyle Robotのインスタンスでおこなう場合には、これらの変更を[プレハブ]自体に組み込むため、"Apply"を押す必要があります。

コントローラーパラメータと連携

Animator Controller に関して理解するすべき重要な機能は、スクリプト経由でアニメーションを制御する[Animator Parameters]です。
今回のケースではSpeedDirectionJumpHiなどのパラメータがあります。

[Animatorコンポーネント]の素晴らしい特徴の一つは、アニメーションにもとづいて実際にキャラクターを動かせることです。この機能はRoot Motionと呼ばれ、Animator ComponentにはApply Root Motionというプロパティがあります。これはデフォルトでtrueになっているので、そのまま利用できます。

つまり実際にキャラクターを歩かせるには、Speed Animation Parameterを正の値に設します。キャラクターが歩き始め、前に進みます。試してみましょう!

Animator Managerスクリプト

ユーザーの入力にもとづいて、文字を制御する新しいスクリプトを作成してみましょう。

  1. DemoAnimator/tutorial/Scripts/PlayerAnimatorManagerという新しいC#スクリプトを作成

  2. [プレハブ] My Robot Kyleにこのスクリプトを添付

  3. 以下のように、 NameSpaceのCom.MyCompany.MyGameでクラスを囲みます。

  4. 明確にするため、リージョンMONOBEHAVIOUR MESSAGESStart()Update() を囲みます。

    C#

    using UnityEngine;
    using System.Collections;
    
    namespace Com.MyCompany.MyGame
    {
        public class PlayerAnimatorManager : MonoBehaviour
        {
            #region MONOBEHAVIOUR MESSAGES
    
            // Use this for initialization
            void Start()
            {
    
            }
    
            // Update is called once per frame
            void Update()
            {
    
            }
    
            #endregion
        }
    }
    
  5. スクリプト PlayerAnimatorManagerを保存します。

Animator Manager:速度制御

最初にコーディングが必要なのは、Animator Componentを制御するためのコードです。

  1. スクリプトPlayerAnimatorManagerを編集している点を確認してください。

  2. Animator型のプライベート変数animatorを作成します。

  3. Animator Componentを、Start()メソッドでこの変数内に格納します。

    C#

    private Animator animator;
    // Use this for initialization
    void Start()
    {
        animator = GetComponent<Animator>();
        if (!animator)
        {
            Debug.LogError("PlayerAnimatorManager is Missing Animator Component",this);
        }
    }
    

    Animator Componentを必須とするため、取得しない場合は開発者がすぐに対処できるよう、エラーをログに記録します。
    コードを書くときは、常に他の誰かによって使用されることを想定するべきです。手間はかかりますが将来的に役立ちます。

  4. [ユーザー入力]にリッスンして、Speed Animation Parameterを制御してみましょう。そして、スクリプトPlayerAnimatorManagerを保存します。

    C#

    // Update is called once per frame
    void Update()
    {
        if (!animator)
        {
            return;
        }
    
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
    
        if (v < 0)
        {
            v = 0;
        }
    
        animator.SetFloat("Speed", h * h + v * v);
    }
    
  5. スクリプトPlayerAnimatorManagerを保存します。

このスクリプトが何をしているかを確認してみましょう:

ゲームは後方に進むことはできませんので、vを0未満にしてください。ユーザーはダウンキーまたは'S'キーを押しても、それを許可せず、値は強制的に0になります。

両方の入力を二乗しているのはなぜだと思いますか?これは、値を常に正の絶対値にして簡単にするためです。
これは良い秘訣です。Mathf.Abs()も問題なく使用出来ます。

左または右の入力を押した際、方向変換の時に加速できるよう、Speedを制御するために両方の入力を追加します。

これはすべて、キャラクターデザインに関することです。もちろん、ゲームロジックによって、キャラクターがその場で方向転換したり後方に進む場合などがあるので、Animation Parametersの制御は常に各ゲームに固有のものになります。

テスト、テスト、1 2 3...

ここまでおこなってきたことを検証してみましょう。
Kyle Testシーンが開かれていることを確認してください。現在、このシーンにはカメラとKyle Robotインスタンスしかありません。シーンにはロボットが立つ地表が無いので、もしKyle Robotが走ったら落ちてしまいます。
また、シーン内では照明などの詳細が省略されています。キャラクターをテストして、スクリプトが正常に動作しているか検証することが目的であるためです。

  1. シーンに"キューブ"を追加します。
    キューブにはデフォルトで"Box Collider"が付いているので、そのまま床で使用できます。
  2. キューブの高さが1なので、0,-0.5,0に配置します。キューブの上面が床に配置されるようにします。
  3. キューブを30,1,30にスケールし、実験の余地を残します。
  4. カメラを選択して、全体を確認するためにカメラの距離をとります。
    1つの良いトリックは、「Scene View」で好きなビューを取得し、カメラを選択して「GameObject/Align With View」メニューに進み、カメラをシーンビューに一致させることです。
  5. 最後のステップとして、My Robot Kyleを上に0.1移動します。そうしないと、衝突が抜けてしまい、キャラクターが床を通過してしまうので、シミュレーションが接触できるよう常にコライダーの間に物理的な空間を残してください。
  6. シーンを実行して、上矢印キーまたは 'a'を押すとキャラクターが歩きます!
    すべてのキーをテストして確認してください。

だいぶ進みましたが、まだ作業が必要です。まだカメラを追跡させる必要がありますし、方向転換ができません。

すぐにカメラの設定をしたい場合は、カメラの専用セクションを確認してください。このページでは、Animatorの制御や回転の実装について説明します。

Animator Managerスクリプト: 方向制御

回転の制御は少し複雑です。左右のキーを押した際にキャラクターが突然回転せず、滑らかに方向転換することが目標です。
ダンピングを使用してAnimation Parameterを設定することができます。

  1. スクリプトPlayerAnimatorManagerを編集していることを確認してください。
  2. 「PRIVATE PROPERTIES」リーションのすぐ上のスクリプトの、新しいリージョン「PUBLIC PROPERTIES」内に浮動小数変数DirectionDampTimeを作成します。

C#

//#region PUBLIC PROPERTIES
public float DirectionDampTime = .25f;
//#endregion
  1. Update()関数の最後に、以下を追加します:

    C#

    animator.SetFloat("Direction", h, DirectionDampTime, Time.deltaTime);
    

    animator.SetFloat() は異なる署名が存在します。
    Speedを制御する署名は簡単ですが、2つのパラメータを追加する必要があります。1つはdamping time、もう片方はdeltaTimeです。
    Damping timeは希望する値に到達するまでの時間です。 deltaTimeはフレームレートから独立してコードを書くことを可能にします。
    Update()はフレームレートに依存するのでdeltaTimeを使用します。
    このトピックについて、webなどで調べて理解を深めてください。
    コンセプトを理解するとUnityのアニメーションや制御機能を最大限に活用できます。

  2. スクリプトPlayerAnimatorManagerを保存します。

  3. シーンを実行して、すべての矢印を使用してキャラクターが歩き、方向転換することを確認してください。

  4. DirectionDampTimeの効果を試してください: たとえば1の後に5を試し、最大の回転能力に到達するまでの時間を確認します。
    回転の半径がDirectionDampTimeと共に大きくなることがわかります。

Animator Managerスクリプト:ジャンプ

ジャンプは、2つの理由からもう少し作業が必要です。
1つは、プレイヤーが走っていないときはジャンプするべきでないからです。もう1つは、ジャンプをループさせないためです。

  1. スクリプトPlayerAnimatorManagerを編集している点を確認してください。

  2. Update()メソッドでユーザー入力を取得する前に、以下を挿入します。

    C#

    // deal with Jumping
    AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);          
    // only allow jumping if we are running.
    if (stateInfo.IsName("Base Layer.Run"))
    {
        // When using trigger parameter
        if (Input.GetButtonDown("Fire2"))
        {
            animator.SetTrigger("Jump");
        }                
    }
    
  3. スクリプトPlayerAnimatorManagerを保存します。

  4. テストおこないます。実行を開始し、「Alt」キーを押すとKyleがジャンプします。

Animatorが実行しているかどうか確認するための方法について理解するには、まずstateInfo.IsName("Base Layer.Run")を使用します。
Animatorの現在のアクティブ状態がRunかどうかを確認します。Run状態は'Base Layer'にあるので、'Base Layer'を追加する必要があります。

Run状態にいる場合、 Fire2 Inputにリッスンして、必要に応じて Jumpトリガーを発生させます。

以下が、ここまでの PlayerAnimatorManagerスクリプトです:

C#

using UnityEngine;
using System.Collections;

namespace Com.MyCompany.MyGame
{
    public class PlayerAnimatorManager : MonoBehaviour
    {

        #region PRIVATE PROPERTIES

        public float DirectionDampTime = .25f;

        #endregion

        #region PRIVATE PROPERTIES

        private Animator animator;

        #endregion

        #region MONOBEHAVIOUR MESSAGES

        // Use this for initialization
        void Start()
        {
            animator = GetComponent<Animator>();
            if (!animator)
            {
                Debug.LogError("PlayerAnimatorManager is Missing Animator Component",this);
            }

        }

        // Update is called once per frame
        void Update()
        {

            if (!animator)
            {
                return;
            }

            // deal with Jumping
            AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);          
            // only allow jumping if we are running.
            if (stateInfo.IsName("Base Layer.Run"))
            {
                // When using trigger parameter
                if (Input.GetButtonDown("Fire2"))
                {
                    animator.SetTrigger("Jump");
                }                    
            }

            float h = Input.GetAxis("Horizontal");
            float v = Input.GetAxis("Vertical");

            if (v < 0)
            {
                v = 0;
            }

            animator.SetFloat("Speed", h * h + v * v);

            animator.SetFloat("Direction", h, DirectionDampTime, Time.deltaTime);
        }

        #endregion
    }
}

この数行のコードにより、シーンで多くのことを実現できます。
次に、カメラが追跡できるようにするためにカメラの設定を行いましょう。

カメラ設定

このセクションでは、作成プロセス中に「Player」プレハブに焦点を当て続けるため、CameraWorkスクリプトをそのままの状態で使用します。
一からCameraWorkを書きたい場合は、 次のセクション に進んでからこのセクションに戻ってください。

  1. My Kyle RobotプレハブにコンポーネントCameraWorkを追加します。
  2. プロパティFollow on Startをオンにすると、カメラが瞬時にキャラクターを追跡するようになります。
    ネットワーク実装を開始する際に、オフにします。
  3. プロパティCenter Offset0,4,0に設定して、カメラを高くします。こうすれば全体を映すことができ、カメラがプレイヤーをまっすぐ映した時のような無意味な地面の映しすぎを回避できます。
  4. Kyle Testシーンを再生し、カメラが適切にキャラクターを追跡することを確認するため、キャラクターを動かします。

PhotonView コンポーネント

プレハブにPhotonViewコンポーネントが必要です。
PhotonViewは、各コンピューター上のさまざまなインスタンスを接続し、監視するコンポーネントとこれらのコンポーネントの監視方法を定義するものです。

  1. My Robot KylePhotonViewコンポーネントを追加します。
  2. Observe OptionUnreliable On Changeに設定します。
  3. PhotonViewは、これを有効にするには何かを観察する必要があることを警告します。
    これらの観察されたコンポーネントはチュートリアルの後半で設定されるため、今は無視します。

ビームの設定

私達のロボットキャラクターには、まだ武器がありません。目から発射されるレーザービームを作成してみましょう。

ビームモデルの追加

簡素化するため、シンプルなキューブを使い、非常に細く長くなるようにスケールします。
これを速やかに行うトリックがあります:頭の子として直接キューブを追加するのではなく、作成、移動、スケールアップしてから頭に添付します。目にビームを合わせるため、適切な回転値を推測することを防ぎます。

もう1つの重要なトリックは、両方のビームで1つだけコライダーを使用することです。
これによって、物理エンジンがより効率的に機能します。薄いコライダーは信頼性が低く好ましくないので、確実にターゲットに当たるように大きなボックスコライダーを作ります。

  1. Kyle testシーンを開きます。
  2. シーンにキューブを追加し、Beam Leftと名付けます。
  3. 長いビームに見えるように変更し、左目に適切に配置します。
  4. Hierarchy内でMy Kyle Robotインスタンスを選択します。
  5. Headの子を確認します。
Kyle Robot Head Hierarchy
Kyle Robot Head Hierarchy
6. `Head` GameObjectの子として、空のゲームオブジェクトを追加して`Beams`と名付けます。 7. `Beams`内の`Beam Left`をドラッグアンドドロップします。 8. `Beams Left`を複製し、`Beams Right`と名付けます。 9. 右目に合うように配置します。 10. `Beams Right`からBox Colliderコンポーネントを削除します。 11. `Beams Left`の「Box Collider」の中心とサイズを調整して両方のビームをカプセル化するようにします。 12. `Beams Left`の「Box Collider」の`IsTrigger`プロパティを`True`に設定します。ビームが衝突した際ではなく、プレイヤーに接触した場合にのみ通知を受けるようにします。 13. 新しいマテリアルを作成し、`Red Beam`と名付けます。その後、'DemoAnimator_tutorial/Scenes/'に保存します。 14. 両方のビームに `Red Beam`マテリアルを割り当てます。 15. プレハブで、変更を適用します。

注:レーザービームは、自身を傷つけないようキャラクターのコライダーの外側に設定する必要があります。

以下のようになります:

Kyle Robot Beams
Kyle Robotヘッドビーム
Kyle Robot Updated Head Hierarchy
Kyle Robotの更新されたHead Hierarchy

ユーザー入力でビームを制御

これでビームがで完成しました。次に、それをトリガーするためのFire入力をつなぎましょう。

次に、PlayerManagerと呼ばれる新しいC#のスクリプトを作成します。
以下はビームを使えるようにするための完全なコードです:

C#

using UnityEngine;
using UnityEngine.EventSystems;

using System.Collections;

namespace Com.MyCompany.MyGame
{
    /// <summary>
    /// Player manager.
    /// Handles fire Input and Beams.
    /// </summary>
    public class PlayerManager : MonoBehaviour
    {

        #region Public Variables

        [Tooltip("The Beams GameObject to control")]
        public GameObject Beams;

        #endregion

        #region Private Variables

        //True, when the user is firing
        bool IsFiring;

        #endregion

        #region MonoBehaviour CallBacks

        /// <summary>
        /// MonoBehaviour method called on GameObject by Unity during early initialization phase.
        /// </summary>
        void Awake()
        {
            if (Beams == null)
            {
                Debug.LogError("<Color=Red><a>Missing</a></Color> Beams Reference.", this);
            }
            else
            {
                Beams.SetActive(false);
            }

        }

        /// <summary>
        /// MonoBehaviour method called on GameObject by Unity on every frame.
        /// </summary>
        void Update()
        {
            ProcessInputs ();

            // trigger Beams active state
            if (Beams != null && IsFiring != Beams.activeInHierarchy)
            {
                Beams.SetActive(IsFiring);
            }
        }

        #endregion

        #region Custom

        /// <summary>
        /// Processes the inputs. Maintain a flag representing when the user is pressing Fire.
        /// </summary>
        void ProcessInputs()
        {

            if (Input.GetButtonDown("Fire1"))
            {
                if (!IsFiring)
                {
                    IsFiring = true;
                }
            }

            if (Input.GetButtonUp("Fire1"))
            {
                if (IsFiring)
                {
                    IsFiring = false;
                }
            }
        }
        #endregion

    }
}

この段階では、このスクリプトの主な目的はビームを有効化または無効化することです。
有効化すると、他のモデルで衝突が発生したときにビームが効果的にトリガーします。このため、各キャラクターの体力に影響を与える目的で、後にこれらのトリガーを取得します。

My Kyle Robotプレハブの階層内でGameObjectを正確に参照できるパブリックプロパティBeamsを公開しました。
では、Beamsの接続方法を説明します。Assetsブラウザではプレハブは最初の子しか表示せず、サブチャイルドを表示しないのでBeamsがプレハブ階層で埋もれてしまいます。そのため、シーンのインスタンスから行い、プレハブ自体に適用して戻す必要があります。

  1. Kyle testシーンを開きます
  2. シーンHierarchy内でMy Kyle Robotを選択します。
  3. PlayerManagerコンポーネントを My Kyle Robotに追加します。
  4. My Kyle Robot/Root/Ribs/Neck/Head/Beamsをインスペクター内のPlayerManager Beamsプロパティにドラッグアンドドロップします。
  5. インスタンスの変更をプレハブに適用します。

Playを押して Fire1 Input を押すと(デフォルトではマウスの左クリックまたはCtrlキー)ビームが表示され、キーを離すとすぐに非表示になります。

体力の設定

ビームがプレイヤーに当たったときに体力が減少する非常に単純なシステムを実装してみましょう。
弾丸ではなく、一定のエネルギーの流れなので、二方向で体力への影響を考える必要があります。ビームが当たった時と、ビームが当たっている間のダメージです。

  1. PlayerManagerスクリプトを開きます。
  2. PlayerManagerをPhoton.PunBehaviourに変換し、PhotonViewコンポーネントを公開します。

C#

[Tooltip("The current Health of our player")]
public float Health = 1f;
  1. パブリックHealthプロパティをPublic Variablesリージョンに追加します。

C#

    /// <summary>
    /// MonoBehaviour method called when the Collider 'other' enters the trigger.
    /// Affect Health of the Player if the collider is a beam
    /// Note: when jumping and firing at the same, you'll find that the player's own beam intersects with itself
    /// One could move the collider further away to prevent this or check if the beam belongs to the player.
    /// </summary>
    void OnTriggerEnter(Collider other)
    {

        if (!photonView.isMine)
        {
            return;
        }


        // We are only interested in Beamers
        // we should be using tags but for the sake of distribution, let's simply check by name.
        if (!other.name.Contains("Beam"))
        {
            return;
        }

        Health -= 0.1f;
    }

    /// <summary>
    /// MonoBehaviour method called once per frame for every Collider 'other' that is touching the trigger.
    /// We're going to affect health while the beams are touching the player
    /// </summary>
    /// <param name="other">Other.</param>
    void OnTriggerStay(Collider other)
    {

        // we dont' do anything if we are not the local player.
        if (! photonView.isMine)
        {
            return;
        }

        // We are only interested in Beamers
        // we should be using tags but for the sake of distribution, let's simply check by name.
        if (!other.name.Contains("Beam"))
        {
            return;
        }

        // we slowly affect health when beam is constantly hitting us, so player has to move to prevent death.
        Health -= 0.1f*Time.deltaTime;
    }
  1. PlayerManager スクリプトを保存する。

2つのメソッドはほとんど同じですが、TriggerStayの場合はフレームレートに減少速度を依存させないよう、Deltatimeを使用して体力を減少させます。
これは通常アニメーションに適用する概念ですが、この場合はすべての端末で予測可能な方法で体力を減少させるために使用します。速いコンピュータで体力が速く減少してしまうのは公平ではないためです。
Deltatimeは一貫性を保証します。
DeltaTimeに関するご質問がありましたらお問い合わせください。また、概念を理解するためにUnityコミュニティを検索することをお勧めします。

理解するべきである二つ目の重要な側面は、ローカルプレイヤーの体力にのみ影響を与えるべきだということです。そのため、メソッドから早く出ます。PhotonViewはMineではありません。

最後に、プレイヤーに当たるObjectがビームである場合のみ体力に影響を与えるので、「beam」タグを使用して確認します。GameObjectsビームはそのようにタグしました。

デバッグを容易におこなうため、Health浮動小数はパブリック浮動小数となっています。これは、UIが構築されるのを待つ間に簡単に値を確認できるようにするためです。

だいぶ完成に近づきましたが、プレイヤーの体力がゼロになりゲームオーバー状態になるまで体力システムは完全ではありません。この設定をおこないましょう。

ゲームオーバーのための体力確認

単純化するため、プレイヤーの体力が0に達したときはルームから退室します。既にGameManagerスクリプトでルームを退出するメソッドを作成しています。
同じ機能のために再びコーディングをするのではなく、同じメソッドを利用できるのが理想的です。どのような場合も、同じ結果を生じるコードの重複は避けるべきです。
ここで、「Singleton」という便利なプログラミングの概念を紹介します。
詳細を説明すると長くなるので今は「Singleton」の最小限の実装をおこないます。
SingletonのUnityコンテキスト内での変化や、有効な機能を作成する方法などを理解すると非常に便利です。
このチュートリアルだけでなく、Singletonについて勉強することをお勧めします。

  1. GameManagerスクリプトを開きます

  2. Publicプロパティリージョンに、この変数を追加します。

    C#

        static public GameManager Instance;
    
  3. このコードをStart()メソッドに追加します。

    C#

    Instance = this;
    
  4. GameManagerスクリプトを保存します。

Instance変数に[静的な]キーワードを実装した点に留意してください。
つまり、GameManagerのインスタンスにポインタを保持しなくても、この変数を使用することができます。
結果としてコード内のどこからでも GameManager.instance.xxx()を実行でき、非常に効率的です。
上記が、このゲームのロジック管理の点にどのように合致するかをみてみましょう。

  1. PlayerManager スクリプトを開く。
  2. Update()メソッドで入力を処理した後、これを追加してPlayerManagerスクリプトを保存します

    C#

    if (photonView.isMine)
    {
        ProcessInputs();
        if (Health <= 0f)
        {
            GameManager.Instance.LeaveRoom();
        }
    }
    
  3. PlayerManagerスクリプトを保存します
  • レーザービームによるダメージの強度は一定ではないので、体力が負の数値になり得ることを考慮します。
  • 実際にコンポーネントなどを入手することなく、GameManagerインスタンスの LeaveRoom()パブリックメソッドに到達します。
    現在のシーンで、GameObjectにGameManagerコンポーネントが存在するという仮定にもとづいています。

次に、ネットワークに進みましょう!

次に進む.
前に戻る.

Back to top