徒然エンジニアブログ

徒然エンジニアブログ

理系東大生がプログラミングを中心に様々なことについて情報発信していきます!

【Unity】よく出てくるprivate, public, static,[SerializeField]についてまとめてみた!

はじめに

unityに限りませんが変数宣言の時にintなどの前にprivateやpublicをつけますよね?
これらはアクセス修飾子というものです。

unityでつまづくポイントで言ったら割と上位にくると思います。
他にややこしいものとしてFind関数がありますがそれはこちらの記事で詳しく紹介してるのでみて行ってください。
turedureengineer.hatenablog.com


私も学びはじめたての頃はとても苦労したので今回はアクセス修飾子について説明していきたいと思います。

そもそもアクセス修飾子とは何か?

アクセス修飾子とは名前の通りアクセスについてのものです。
具体的にはクラスの外からアクセスしてもいいかダメかということについてのものです。


publicをつけた変数やメソッドはクラスの外から使うことができます。
一方でprivateがついているものや、そもそも何もつけていない場合はクラスの外からはアクセスできません。
何もついていないものはprivate変数として扱われるからです。


実際のコードで見てみよう!

以下にSample1というクラスのコードがあります。ここにはa,b,cという変数がpublicやpublic stataicなどがついた状態で宣言されています。
この変数をSample2というクラスから取得していきましょう!

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

public class Sample1 : MonoBehaviour {

    public int a;
    public static int b;
    [SerializeField] private int c;

    public int C{
        get{
            return c;
        }
    }
}

publicだけがついた変数を取得する

public Sample1 s1;
//publicをつけた変数をそのまま取得
int a = s1.a; 

まず Sample1クラスのインスタンスs1を宣言します。
そしてインスペクタのs1のところにSample1をアタッチしたゲームオブジェクトをドラッグして代入します。
するとpublicがついているつまりクラスの外からアクセスできるので(インスタンス名).(変数名)で取得できます。


unityではpublicだけをつけた変数はインスペクタから値を代入できるということも覚えておきましょう

public staticをつけた場合

さていきなりstaticなんて聞いてないものが出てきて混乱したのではないでしょうか?実際私もこの辺りでよくわからなくなっしまいました。


staticをつけたものはクラスに一つのものとなります。staticがついていない上の例ではインスタンスごとに値を持つことができます。
インスタンスに依らないということでpublic staticのついた変数はより簡単に取得できます。

//public staticをつけた変数を取得
int min = Sample1.b;

このようにpublic staticのついた変数は(クラス名).(変数名)で取得できます。

そしてpublic staticのついた変数はインスペクタに表示されません。
これは各インスタンスで共通したものであるからです。

privateだけをつけた場合

publicの場合とは違ってprivateがついた変数はクラス外からはアクセスできません。
そのためバグがおこりにくく保守性が高くなります。

ではpraivateをつけた変数はクラス外から取得できないのしょうか?
答えは「プロパティ」を使うとできます。
プロパティとは

public int C{
        get{
            return c;
        }
    }

ここの部分のことです。

このようにプロパティにpublicをつけることでprivateがついた変数も取得できます。
実際のコードは以下です。

public Sample1 s1;
//privateをつけた変数をプロパティを介して取得
int max = s1.C;

インスタンスを宣言するのはpublicの場合と同じです。
上の例を見てわかるように(インスタンス名).(プロパティ名)で取得することができます。

また今はprivateな変数の値を取得するだけでしたが、下のように変更すると代入することもできます。

public int C{
        get{
            return c;
        }
        set{
           c = value;
       }
    }

上のようにしておくと、クラス外から出会っても

s1.C = 3;

とすることでprivateな変数に代入することができます。

[SerializeField]は何か?

これをprivateな変数の前につけておくとインスペクタ上から操作できるようになります。
ただそれだけです。

privateにしておきたいけどインスペクタ上で手軽に値を確認したい時やドラッグアンドドロップで最初に値を設定しておきたい時などに使います。


クラス外からはあくまでもprivateなものになっているので操作できません。

終わりに

アクセス修飾子の話にはクラスの概念が絡んできて難しいと思いますが頑張っていきましょう!!