質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

1421閲覧

Unity 自身の参照を持つ、バッキングフィールドについて

ramune

総合スコア11

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2019/03/04 05:35

前提

Unityにてゲーム開発をしたいと思い勉強中です。
一応Javaの資格は持っていますが、UnityはもちろんJavaでの開発経験もないに等しいです。
プログラムの概念や、わからない事に関して調べる方法等の知識が少しあるぐらいです。

なので現在、ゲームがどのように作られているのかをUnityの公式ホームページにあるチュートリアルの3DGameKitというプロジェクトを落とし込んで勉強しているところです。

わからない事柄

3DGameKitのプロジェクト内にあります、
3DGameKit->Scripts->Game->Player->PlayerController.csにて、表題にあるように自身を参照するソース、バッキングフィールド(そもそもバッキングフィールドとは何かが解らない)をしているソースがあるのですがこれが何の為にしているのかわからずにいます。

該当のソースコード(一部抜粋)

public class PlayerController : MonoBehaviour, IMessageReceiver {   //なぜ自身を参照するのか protected static PlayerController s_Instance;   //なぜ自身のプレハブをインスタンス???   //はたまた自身を参照したものをgetする?何をgetする??? public static PlayerController instance { get { return s_Instance; } }

詳細のソースは下部に載せておきます。

質問

ググって見ても上記ソースについて、いまいち理解ができず何をしているのか・何がしたいのかがわかりません。

該当ソースをする・しないではどのように変わってくるのでしょうか。
するメリットとして何が挙げられるのでしょうか。

これらに関してどなたかご教授の程お願いします。
また、蛇足ですがゲーム開発能力やプログラミング能力(アルゴリズム関連等)の向上方法に関してもご教示いただけますと幸いです。

該当のソースコード(詳細ソース)

using UnityEngine; using Gamekit3D.Message; using System.Collections; using UnityEngine.XR.WSA; namespace Gamekit3D { [RequireComponent(typeof(CharacterController))] [RequireComponent(typeof(Animator))] public class PlayerController : MonoBehaviour, IMessageReceiver { protected static PlayerController s_Instance; public static PlayerController instance { get { return s_Instance; } } public bool respawning { get { return m_Respawning; } } public float maxForwardSpeed = 8f; // How fast Ellen can run. public float gravity = 20f; // How fast Ellen accelerates downwards when airborne. public float jumpSpeed = 10f; // How fast Ellen takes off when jumping. public float minTurnSpeed = 400f; // How fast Ellen turns when moving at maximum speed. public float maxTurnSpeed = 1200f; // How fast Ellen turns when stationary. public float idleTimeout = 5f; // How long before Ellen starts considering random idles. public bool canAttack; // Whether or not Ellen can swing her staff. public CameraSettings cameraSettings; // Reference used to determine the camera's direction. public MeleeWeapon meleeWeapon; // Reference used to (de)activate the staff when attacking. public RandomAudioPlayer footstepPlayer; // Random Audio Players used for various situations. public RandomAudioPlayer hurtAudioPlayer; public RandomAudioPlayer landingPlayer; public RandomAudioPlayer emoteLandingPlayer; public RandomAudioPlayer emoteDeathPlayer; public RandomAudioPlayer emoteAttackPlayer; public RandomAudioPlayer emoteJumpPlayer;  ~略~ protected bool IsMoveInput { get { return !Mathf.Approximately(m_Input.MoveInput.sqrMagnitude, 0f); } } public void SetCanAttack(bool canAttack) { this.canAttack = canAttack; } // Called automatically by Unity when the script is first added to a gameobject or is reset from the context menu. void Reset() { meleeWeapon = GetComponentInChildren<MeleeWeapon>(); Transform footStepSource = transform.Find("FootstepSource"); if (footStepSource != null) footstepPlayer = footStepSource.GetComponent<RandomAudioPlayer>(); Transform hurtSource = transform.Find("HurtSource"); if (hurtSource != null) hurtAudioPlayer = hurtSource.GetComponent<RandomAudioPlayer>(); Transform landingSource = transform.Find("LandingSource"); if (landingSource != null) landingPlayer = landingSource.GetComponent<RandomAudioPlayer>(); cameraSettings = FindObjectOfType<CameraSettings>(); if (cameraSettings != null) { if (cameraSettings.follow == null) cameraSettings.follow = transform; if (cameraSettings.lookAt == null) cameraSettings.follow = transform.Find("HeadTarget"); } } // Called automatically by Unity when the script first exists in the scene. void Awake() { m_Input = GetComponent<PlayerInput>(); m_Animator = GetComponent<Animator>(); m_CharCtrl = GetComponent<CharacterController>(); meleeWeapon.SetOwner(gameObject); s_Instance = this; }  ~以下略~

補足情報

拝見したブログ等

『プレハブに自身の参照を持たせた時にハマった挙動』
http://sukiaraba.hatenablog.jp/entry/2016/12/25/132334

『インスペクターで値も設定したいけど,プロパティを使いたい。めんどくさいのも嫌!』
https://qiita.com/RyotaMurohoshi/items/b64b36009ba652b21e2c

『C# 7.3から自動実装プロパティのバッキングフィールドに属性をつけられる ...』
https://qiita.com/RyotaMurohoshi/items/bf078f890473d6b5568b

『実行時のプレハブのインスタンス化 - Unity マニュアル - Unity - Manual』
https://docs.unity3d.com/ja/current/Manual/InstantiatingPrefabs.html

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

//なぜ自身を参照するのか

protected static PlayerController s_Instance;

他のスクリプトから一意のPlayerControllerを簡単に取得するための変数です。
PlayerControllerクラス自身が使うためではなく他のスクリプトから簡単にインスタンスを取得するためにあります。
今回のスクリプトではPlayerControllerはシーン上に一つしか存在しない・させないという前提で作られているっぽいので実質的にシングルトン的な機能を提供するための変数といえます。
ただしアクセス修飾子がprotectedなのでこれだけでは外からアクセスできません。その為に下記のプロパティという機能を用います。

 //なぜ自身のプレハブをインスタンス???

  //はたまた自身を参照したものをgetする?何をgetする???
public static PlayerController instance { get { return s_Instance; } }

こちらはC#のプロパティという機能を使用しています。
s_Instanceはprotectedなので他のクラスからアクセスできません。
それを外部に公開するためにgetプロパティを定義して外からinstanceという名前でs_Instanceにアクセスできるようにしているのです。
(setプロパティは実装していないのでs_Instanceに外から代入することはできません)

使用例 : var controller = PlayerController.instance;

投稿2019/03/04 06:06

MMashiro

総合スコア2378

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ramune

2019/03/04 10:42

ご回答ありがとうございます! 自身に使用するためではなく、外部からのアクセスにてプロパティ情報を取得しやすいようにしている為という事がが理解できました。 他のスクリプトにて使用している箇所がないか探してみた所、使用例にて提示してくれたように、 PlayerController.instanceでプロパティ情報を取得している箇所がありました。 instanceは変数名だったのですね。 何か関数を呼び出しているのかと勘違いしておりました。 しかし、まだ少し解らない所があるのですが、アクセス制限を用いてまでなぜ二つに分けるのでしょうか。 アクセス制限をしないで一つだけではダメなのでしょうか。 そこがまだ引っ掛かりを感じる所でして、 アクセス制限をする理由として、ここではsetプロパティが実装されていないように、外部からの値変更を防ぎ、値変更する場合はこのPlayerController.cs内だけにして、どこで値変更したか等の混乱を防ぐといった可読性を高める為なのでしょうか。 すみませんがまた一つご教授頂けると幸いです。
MMashiro

2019/03/04 12:40

> アクセス制限をする理由として、ここではsetプロパティが実装されていないように、外部からの値変更を防ぎ、値変更する場合はこのPlayerController.cs内だけにして、どこで値変更したか等の混乱を防ぐといった可読性を高める為なのでしょうか。 そうですね、プロパティを用いればset中に値の範囲チェックができたり、get時に計算結果を渡したりなど仕様変化にも十分に対応出来たりして便利です
ramune

2019/03/05 23:02

またのご回答ありがとうございます! 可読性を高めつつ柔軟な対応が出来るように制御をしていたのですね。 ものすごく勉強になりました! ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問