2016-12-27 10 views
2

私の小さな2Dゲームでプレイヤーの相続に少し助けが必要です。 実際、新しいプレーヤーを作成してリストに追加する方法がわかりません。Unity 2Dプロジェクトの構造:スクリプトに基づいてPlayerを動的に作成する方法

これは私のプロジェクト構造である: enter image description here

あなたが見ることができるように、私のスクリプトでは、私はGameBaseスクリプトを持っている、とPlayerBaseスクリプトPlayerLife、PlayerControllerとPlayerAimManagerとPlayerBaseの子として。

私のプレハブには、私のカメラにはGameBaseスクリプト、PlayerPrefabにはプレイヤースクリプトがあります。

マイPlayerBaseが...スクリプトの魔女は彼の人生、スピード、色などのように、プレイヤーを定義している:

public class PlayerBase : MonoBehaviour 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    protected float Life { get; set; } 
    public Color Color { get; set; } 
    protected WeaponBase PrimaryWeapon { get; set; } 
    protected WeaponBase SecondaryWeapon { get; set; } 
    protected WeaponBase SelectedWeapon { get; set; } 
    protected ScoreBase Score { get; set; } 
    protected bool IsDead { get; set; } 
    protected float Speed { get; set; } 
    protected float JumpForce { get; set; } 

    protected virtual void Start() 
    { 
     IsDead = false; 

     //Reset rotation 
     transform.rotation = Quaternion.identity; 

     Life = 100; 
     Speed = 20; 
     JumpForce = 4000; 

     PrimaryWeapon = gameObject.AddComponent<SMG>(); 
     SecondaryWeapon = gameObject.AddComponent<Shotgun>(); 

     SelectedWeapon = PrimaryWeapon; 
    } 
} 

(そして、私の子供がこのように動作します:)

public class PlayerLife : PlayerBase 
{ 
    // Use this for initialization 
    protected override void Start() 
    { 
     base.Start(); 
     var color = base.Color(); 
    } 
} 

[OK]をこれは私の問題です:

新しいプレーヤーをインスタンス化してリストに保存するにはどうすればよいですか?私GameBaseで

私はこのような何か:

public class GameBase : MonoBehaviour 
{ 
    public List<PlayerBase> Players { get; set; } 

    void Start() 
    { 
     var playerObj1 = Instantiate(Resources.Load("Prefabs/Players/PlayerPrefab")) as GameObject; 
     PlayerBase player1 = playerObj1.GetComponent<PlayerBase>(); 
     player1.Color = Color.red; 
     player1.Name = "Naografix Red"; 

     var playerObj2 = Instantiate(Resources.Load("Prefabs/Players/PlayerPrefab")) as GameObject; 
     PlayerBase player2 = playerObj2.GetComponent<PlayerBase>(); 
     player2.Color = Color.blue; 
     player2.Name = "Foo Blue"; 

     Players = new List<PlayerBase>{ 
      player1, 
      player2 
     } 
    } 
} 

私はこれを行う場合は、静的ではないので、私の子供のプレイヤースクリプトの私の色は私の色を表示できません。しかし、私がColorを静的な小道具に置くと、自分の色を私のGameBaseで変更することはできません。

私の相続が良いかどうかわかりません。

自分の変数を取得するために、PlayerBaseに基づく子スクリプトを使用して動的にプレーヤーを作成したいだけです。

EDIT

実際に、私は私が動的にカスタムプロパティを持つプレーヤーを作成することができるのか分かりません。 私はこれをしたい:

PlayerBase player1 = new PlayerBase(); 
player1.Name = "Nao"; 
player.Color = Color.Red; 

をそして、私のPlayerListに保管してください。しかし、私はこれを行うことはできません。なぜなら、プレハブは作られていないからです。

私はPlayerPrefabで新しいGameObjectをインスタンス化します。 - クール、私のプレーヤーが産んだ、私はいくつかのプロパティを適用するつもりです。ハァッ? PlayerBaseスクリプトはどのように入手できますか?

次に、GetComponentを使用してPlayerBaseを取得しますが、私の子供がいるためPlayerBaseは取得できません(私はPlayerPaseをPlayerPrefabに持っていません)。 PlayerBaseを置くと、すべての子はそれぞれPlayerBaseのインスタンスが異なります。

結論:PlayerBaseに基づいて新しいPlayerを作成し、すべてのプロパティを自分の子に共有し、プロパティでPlayerPrefabを生成するにはどうすればよいですか?簡単な例では

ENDEDIT

EDIT

public class Game : MonoBehaviour 
{ 
    private List<PlayerBase> _players; 
    public GameObject Player; 

    void Start() { 
     _players = new List<PlayerBase>(); 

     var obj = Instantiate(Player); 
     var playerBase = obj.GetComponent<PlayerBase>(); 
     playerBase.Color = Color.blue; 
    } 

    void Update() { 

    } 
} 


public class PlayerBase : MonoBehaviour { 

    public Color Color { get; set; } 

    // Use this for initialization 
    protected virtual void Start() { 
     gameObject.GetComponent<Renderer>().material.SetColor("_Color", Color); 
    } 
    // Update is called once per frame 
    protected virtual void Update() { 

    } 
} 


public class PlayerLife : PlayerBase { 

    // Use this for initialization 
    protected override void Start() { 
     gameObject.GetComponent<Renderer>().material.SetColor("_Color", Color); 
    } 

    // Update is called once per frame 
    void Update() { 

    } 
} 

マイplayerLife色はnullです。これが私の最初の問題です。

enter image description here

ENDEDIT

あなたは詳細が必要な場合は掲載していません。あなたはMonoBehaviourの公共メンバー(ないプロパティ)を定義するとき

おかげ

+0

しかし...カラーカラーに名前を付ける、あなたはそれを変更したい場合があります。それが失敗する理由さえあります。 – Everts

答えて

2

は、検査員によって設定された値は、そのゲームオブジェクトに対して自動的に直列化されます。そのゲームオブジェクトからインスタンス化すると、自動的にインスタンス化されたゲームオブジェクトに復元されます。

これは、publicアクセサーと[SerializeField]属性なしでも実行できます。

PlayerLifeスクリプトのみがPlayerBaseから継承されていることを確認してください。残りのスクリプト(PlayerControllerとPlayerAimManager)はMonoBehaviourから継承する必要があります。

player2.Color = Color.blue;の場合は、コピーではないstructを修正するため、色の問題として表示されません。その色を手動でgameObject.GetComponent<Renderer>().material.SetColorに割り当てる必要があります。

新しいPlayerBaseスクリプト:

public class PlayerBase : MonoBehaviour 
{ 
    public Color Color; 

    public Color matColor 
    { 
     get 
     { 
      Color = gameObject.GetComponent<Renderer>().material.GetColor("_Color"); 
      return Color; 
     } 
     set 
     { 
      Color = value; 
      gameObject.GetComponent<Renderer>().material.SetColor("_Color", Color); 
     } 
    } 


    // Use this for initialization 
    protected virtual void Start() 
    { 
     matColor = Color; 
    } 

    // Update is called once per frame 
    protected virtual void Update() 
    { 

    } 
} 

PlayerLife:

public class PlayerLife : PlayerBase 
{ 
    public PlayerBase pBase; 

    void Awake() 
    { 
     pBase = this; 
    } 

    // Use this for initialization 
    protected override void Start() 
    { 
     matColor = Color; 
    } 

    // Update is called once per frame 
    protected override void Update() 
    { 

    } 
} 

があなたのゲームscriotからそれを使用するには:あなたがからPlayerBaseにアクセスすることを決定した場合、今

public class Game : MonoBehaviour 
{ 
    private List<PlayerLife> _players; 
    public GameObject Player; 

    void Start() 
    { 
     _players = new List<PlayerLife>(); 

     GameObject obj = Instantiate(Player); 
     PlayerLife playerLife = obj.GetComponent<PlayerLife>(); 
     playerLife.matColor = Color.blue; 
     _players.Add(playerLife); 

     GameObject obj2 = Instantiate(Player) as GameObject; 
     PlayerLife playerLife2 = obj2.GetComponent<PlayerLife>(); 
     playerLife2.Color = Color.red; 
     _players.Add(playerLife2); 
    } 

    void Update() 
    { 

    } 
} 

あなたPlayerControllerおよびPlayerAimManagerスクリプト

PlayerBase playerBase = gameObject.GetComponent<PlayerBase>(); 

OR

PlayerBase playerBase = gameObject.GetComponent<PlayerLife>().pBase; 
+0

"私の色はヌル"という意味のOPは分かりません。エディターに表示されないのは彼でしょうか?それが正しいとすれば、 "set {} get {}"というプロパティが正しく編集されていない理由です。 – Programmer

+0

@Programmer correct私は非プロパティを強調しましたが、OPではフィールドの直列化それは自動的に処理することができるからです。 – Bijan

+0

@Naografixは、すべての必要な色を保持する静的配列を追加するという意味ですか? – Bijan

関連する問題