2017-12-20 7 views
0

私は3つのタイプのボール(A、B、C)すべてがMotherBallを継承しています。実際にタイプがわからずに名前付きGetComponentを使用して関数を呼び出す

私はballtypeでボールを取得することができ、それはそれは、スクリプト(AScript、BScriptまたはます。CScript)だ含まれていますObjectPool

は状況が私がランダムにオブジェクトプールからボールを​​取るだろう、と私は私がすることを願っているがありますそれを別の関数で扱わないでください。 以下のコードのような設定機能を呼び出す方法はありますか?私は多分一般的であると思っています、あるいは代議員がそれをぶつけることができます、あるいは私は3つの機能を書く必要があります。 ありがとうございます。 P.S申し訳ありませんが私の英語は貧しいです、私は私の問題を正確に記述することはできません。

public void OneBallFire(string ballType){ 
    GameObject ball = ballPool.GetObjectFromPool (ballType); 

    //I can't cast AScript, BScript or Motherball. 
    MotherBall ballScript = ball.transform.GetComponent (ballType) as MotherBall; 
    ballScript.Setting(); 
} 

public class MotherBall : MonoBehaviour{ 
    public virtual void Setting() { 
     //Do nothing 
    } 
} 

public class AScript : MotherBall { 
    public void Setting(){ 
     Debug.Log("Do A plan"); 
    } 
} 

public class BScript : MotherBall { 
    public void Setting(){ 
     Debug.Log("Do B plan"); 
    } 
} 

OneBallFire(RandomGetAorBorC()); 
string RandomGetAorBorC(){ 
    //random return "AScript, BScript or CString" string. 
} 
+0

は、なぜあなたはMotherBallにオブジェクトをキャストしていますか? – PMerlet

+0

キャストが間違っています。 '_ball'が**ではない場合、' MotherBall'は 'NullReferenceException'を取得します。 '_ball'が常に' MotherBall'ならば、なぜそれをキャストするのですか? – BanksySan

+0

私はキャストが間違っていることを知っていますが、私のプログラムでOneBallFire()のパラメータがランダム(いつかはいつかa、ある時はb)なので、AScriptまたはBScriptにキャストできません。すべての設定機能は別のことを行います。そして、私はそれをスローするために1つの機能を使いたいだけです。 –

答えて

0

私は、これはあなたのシナリオで動作するかどうかわからないが、私は実際のスクリプトを取得するために古典的なisasとなるだろう:

var component = ball.transform.GetComponent(customScript); 
if (component is AScript) 
{ 
    (component as AScript).Setting(); 
} 
else if (component is BScript) 
{ 
    (component as BScript).Setting(); 
} 
else 
{ 
    (component as MotherBall).Setting(); 
} 

をUPDATE:

ますサブタイプと型キャストを気にする必要がないように、BallPoolコンテナの実装を更新する必要があります。

私はあなたがリストにボールゲームオブジェクトを格納していると想像:

は、ここで簡単な例です。私が最初にすることは、コンテナとしてList<MotherBall>を使用することです。

public class BallPool : Monobehaviour 
{ 
    public List<MotherBall> ballPrefabs = new List<MotherBall>(); 
    ... 
} 

がインスペクタから、このリストにボールプレハブのすべての種類を追加します。

次に、あなたの方法は、次のようになります。

public MotherBall GetObjectFromPool() 
{ 
    return Instantiate(ballPrefabs[Random.Range(0,ballPrefabs.Count)); 
} 

次に、あなたの他のスクリプトに:今

public BallPool ballPool; // assign from the inspector 

void Start() // or whatever other method 
{ 
    var ball = ballPool.GetObjectFromPool(); 
    ball.Setting(); 
} 

ball.Setting()を選択したものをオブジェクトに応じて、AScriptまたはBScriptのいずれかからオーバーライドされたメソッドを使用します。すべてのプレハブがMotherBallから継承したスクリプトを持つようにタイプについて心配する必要はないので、このメソッドがオーバーライドされていない場合はすべてSetting()でなければなりません。MotherBall.Setting()と呼ばれる。


・ホープこのことができます:)あなたはballTypeの設定()関数を使用したい場合は

+0

解決策は少しブルートフォースと思われるが、それは私の問題を解決することができます、ありがとう。 –

+0

これは本当に良い解決策ではありません。コードは 'Motherball'から継承するすべての型を知る必要があります。 – BanksySan

+0

明らかに、OPが持つこの種の多態性の実装で作業したいときは、コードはすべての型を知る必要があります。これは、実際のタイプではなく文字列を再生するときに得られるオートメーションの中で最も優れています。したがって、OPの問題を解決する最も簡単なソリューションです。 –

1

いいえ、あなたはoverridingです。基本クラスのメソッドと同じシグネチャを持つメソッドが必要な場合は、overrideキーワードを削除し、newに置き換える必要があります。今度は、お互いに無関係の2つのメソッドがあります。Motherballオブジェクトのオブジェクトにアクセスするには、Motherballにキャストします。私はあなたががやりたい疑う何

public class AScript : MotherBall { 
    public new void Setting(){ 
     //Do something 
    } 
} 

var _ball = new AScript(); 
_ball.Setting() // calls Setting on AScript 
((MotherBall) _ball).Setting(); // Calls Setting on MotherBall 

あなたはAScriptクラスにSetting()を呼び出すときに基本メソッドを呼び出すです。ここには2つのオプションがあります。

  1. だけAScript.Setting()への呼び出しが基本クラスのSetting()メソッドを呼び出します、完全AScript方法を削除します。
  2. AScriptクラスメソッドから基底クラスのSetting()メソッドを呼び出します。これを行うには、baseキーワードを使用します。 base.Setting()
+0

貧しい私の英語のため、私の以前の質問のタイトルは間違っています。私は本当に親の機能を呼びたくありません。私はボールを動かすことを望んでいます。この答えが何であれ、私にもたくさん助けてくれて、感謝します。 –

関連する問題