//
// 「管理者」と「被管理者」と言う考え方の、単純な管理構造サンプル
//
// ・透過的にボールを管理するマネージャと
// ・その対象となるボール用のインタフェース
// この二つを利用して、簡単に楽チン管理。
//
// 以下のサンプルでは、次々にプレハブから生成する(つもり)の「ボール」に対して
// メインループから一斉に一発でアクセスする手法をアドリブで書いた。
// 間に挟まっているマネージャが Singleton になっているのがイマイチだけど、
// その辺はUnity環境の事情と言う事で一つ。
//
// 話の要点を簡単に言うなら、「複数のオブジェクトが参照する、共通の何かが間に挟まればいい」って事。
// それの具体的な「点と点をつなぐ線」の実装例。応用はお好きに。
//
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
// 例えばボールを管理するマネージャクラス
// MonoBehaviour と関係ないので AssemblyCSharp名前空間 に置いとく
// 意味的に違和感無ければデフォルトでもいい
namespace AssemblyCSharp
{
// 生成されるボールを管理するクラス
public class BallManager {
// 唯一のインスタンス
private static BallManager manager = new BallManager();
// インスタンス取得メソッド
public static BallManager getInstance()
{
return manager;
}
// ------------------------------------------------------------------
// 生成したボールのインスタンス参照を持っておくリスト…
// だが、MonoBehaviour や GameObject でなく、
// 自前のインタフェース
private List<IBallProc> listBalls = null;
// ここで行っているのはいわゆる Singleton なので privateコンストラクタ
// 別に(どうせスレッド・アンセーフなんだから)全部 public static でも良いかもしれないが
// 気持ち悪いのでシンプルにこう
private BallManager()
{
listBalls = new List<IBallProc>();
}
// 外部からマネージャにボールを登録する
public void register(IBallProc go)
{
this.listBalls.Add(go);
}
// このマネージャに登録されているボール全てに通知
// この例で言えば、スケールの変更
public void scaleChange(float r)
{
foreach(IBallProc mb in listBalls)
{
mb.scaleChange(r);
}
}
// 以下2つはベタなおまけなので説明略。lengthをpropertyにしないのはなんとなく
public int length() { return this.listBalls.Count; }
public IBallProc this[int index] { get { return this.listBalls[index]; } }
}
}
-----------------------------------------
using System;
// 肝心のインタフェース
// これも MonoBehaviour と関係ないので AssemblyCSharp名前空間 に置いとくが、どちらでもいい
namespace AssemblyCSharp
{
public interface IBallProc
{
// スケールチェンジの機能(のつもり)の約束
void scaleChange(float r);
}
}
-----------------------------------------
using UnityEngine;
using System.Collections;
// 実際の プレハブに割り当てるボールコントローラ
// 通常の MonoBehaviour のほか、上で定義している
// AssemblyCSharp.IBallProc インタフェースもインプリメント
//
public class BallCtrl
: MonoBehaviour, AssemblyCSharp.IBallProc
{
private AssemblyCSharp.BallManager man = AssemblyCSharp.BallManager.getInstance();
void Start () { /* 略 */ }
void Update () { /* 略 */ }
// 初動時に自分をマネージャに登録
void Awake()
{
man.register(this);
}
// このメソッドは、「マネージャが叩いてくる」メソッド。そして…
public void scaleChange(float r)
{
this.gameObject.transform.localScale *= r;
}
}
-----------------------------------------
~~~ Main Loop 処理などで ~~~
private AssemblyCSharp.BallManager ballManager;
private float test = 1.0f;
void Awake()
{
ballManager = AssemblyCSharp.BallManager.getInstance();
}
if(Input.GetKeyDown(KeyCode.Space))
{
Instantiate(goBlit, goPlayer.transform.position, goPlayer.transform.rotation);
// 生成されている全てに通知はこれだけ
// メインループは、マネージャを叩く → マネージャは自分のリストを全て叩く
// ただこれだけ
ballManager.scaleChange(test);
test *= 1.2f;
}