おはよう。ここでは何度かUnityの最適化について触れている。
検索の多い「他スクリプトの参照と使い方」を中心に、
参照していかに使うかについて、色々書いていきたい。
最適化のおさらい:定義(キャッシュ)せよ

まずはキャッシュだ。Start関数の前にint,float,stringなど、
次々と型番と変数、値があれば入力していく。
特にstring系の参照型はキャッシュするかどうかで、Unityの効率化が大きくはかどる。
stringはColissionやCompareTagなどいたるところで使うので、
面倒くさくてもキャッシュしていこう。
またGameObject,Transformもキャッシュしておくと、早く動く。
こちらにキャッシュについて詳しい情報を書いている。
他スクリプト参照の基本:インスペクターアタッチ
[SerializeField] BGManager bgms;
[SerializeField] protected SoundManager ses;
public CanonBall canons;
他スクリプト参照の基本はアタッチだ。
三つのどれかを使うと、インスペクター上から直接アタッチできる。
ただしアタッチできる対象はヒエラルキーにあるゲームオブジェクトや
Assetsに貼るゲームオブジェクトファイルのみだ。
ゲームオブジェクトをドラッグし直接入力するか、
◎部分をクリックして対象のオブジェクトを探すか。

アタッチ以外にもやり方はある(後述)。
アタッチは直接取得できるので最も楽なやり方だ。
ただしアタッチがちょいと面倒くさい。
別の方法1:FindWithTag
GameObject gb = GameObject.FindWithTag("Finish");
GameObject[] gbt = GameObject.FindGameObjectsWithTag("Player");
別の方法として該当タグから検索する方法がある。
ヒエラルキーに同じタグがあるものにおいて、普通は一つのみ取得する。
スクリプトを参照する場合、
private Weapons weapon;
weapon = gb.GetComponent<Weapons>();
GetComponentを使わなければ取得できない。
別の方法2:子や孫のGetComponent
private Weapons weapons;
weapon = GetComponentInChildren<Weapons>();
自分の子オブジェクトにスクリプトをつけている場合、
上記の形で親スクリプトから参照できる。
反対に子から親を取得するときは
weapon = transform.parent.gameObject.GetComponent<Weapons>();
parentを使って取得すればいい。一気に取得する場合は配列を使う。
GameObject[] doj = GameObject.FindGameObjectsWithTag(objTag);//ヒエラルキーから
for(int i1 = 0; i1 < doj.Length; i1 ++){
GameObject obj = doj[i1];//配列を一個ずつ取り出す
}
他のやり方もある。
静的staticを使う
//GameManager.csにて
public static int hp = 5;//publicをつけると別スクリプトでも参照可能
praivate static int mp = 6;//praivateだと他スクリプト参照不可能。
//一方でこれをつけたスクリプトのみ、至る関数で自由に扱える
//別スクリプトにて
int gran;
gran = GameManager.hp;
staticはほかのスクリプトアタッチをやらずとも直接代入できる。
さらにstaticはintやstringといった個数だけでなく、関数も扱える。
public static bool saveon;
public static void AutoSave(){ //シーン移動後の保存
saveon = true;
int x = 3;
}
関数の場合、中身をpublic staticにしないと使えない。
static関数を使う時、privateは使えないので注意してほしい。
私はstaticを使って目的のboolのみを判定し、
Update関数にて目的のbool=trueなら起動する。
起動先の関数はpublic void XXX(){//起動時のプログラム}を使えばいい。
参照はpublicしか使えない
public int arrangeID = 1;
[System.NonSerialized]public int enemyIDs = 10;
public void Erase(){//特定のファイルをすべて消す
save = new SaveLists();
string jsonData = JsonUtility.ToJson(save);//このstringはprivate修飾子
StreamWriter streamWriter = new StreamWriter(PathS, false); //falseは上書き、trueは追記
streamWriter.WriteLine(jsonData);
streamWriter.Flush();
streamWriter.Close();
return;
}
参照先はpublicのついたものしかできない。
privateでも使いたいなと思ったら関数を利用しよう。
public void XY(){//ここならprivate変数を入れてもOK}
別のスクリプトで使う場合、インスペクター上にアタッチしたうえで、
//BgmManager.cs
public void PlayBGM(int clipNo){//Stageが違う時のBGM
clip = clipNo; //clipはprivate int変数
clipold = clip; //clipoldは private static int変数
bgms = bgmData.bgm[clip];
audioC = bgms.BgmClip;
sameMiddleStart = 0;//初期化
if(!loopOn) audioB.loop = !audioB.loop;//Loop停止にチェックを変える
audioB.clip = audioC;//GameManagerプレハブをoffにしてたらエラーが起きる
audioB.time = middleStart;
if (audioB.time < audioB.clip.length && audioC != null)audioB.Play();
}
//----------------------
//別スクリプトで
[SerializeField] BgmManager bgm;
void Start(){
bgm.PlayBGM(2);
}
上記のやり方を参考にしながらやれば、いくらでも参照できる。
他スクリプトの参照はpublicをつけた関数が一番簡単かもしれない。
