Мне нужна небольшая помощь для унаследования моего игрока в моей маленькой 2D-игре. На самом деле, я не знаю, как создать нового игрока и добавить его в список.

Это моя структура проекта: введите описание изображения здесь

Как видите, в моих сценариях есть сценарий GameBase и сценарий PlayerBase с PlayerLife, PlayerController и PlayerAimManager в качестве дочерних для PlayerBase.

В моих префабах есть камера со скриптом GameBase и PlayerPrefab со скриптами игрока.

My 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();
    }
}

Хорошо, теперь это моя проблема:

Как я могу создать нового игрока и сохранить его в списке.

В моей 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, чтобы получить свою собственную переменную.

ИЗМЕНИТЬ

Фактически, я не знаю, как динамически создать проигрыватель с настраиваемыми свойствами. Я хочу сделать это :

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

И сохраните его в моем PlayerList. Но я не могу этого сделать, потому что не создается префаб.

Итак, я создаю новый GameObject с помощью PlayerPrefab. -Ок, круто, мой плеер появился, я собираюсь применить некоторые свойства. Хм? Как я могу получить свой скрипт PlayerBase?

Затем я получаю свой PlayerBase с помощью GetComponent, но все еще не работаю, потому что у меня есть ребенок (у меня нет PlayerBase в моем PlayerPrefab). И если я добавлю к нему PlayerBase, у каждого потомка будет свой экземпляр моей PlayerBase.

В заключение: как я могу создать нового Player на основе PlayerBase, поделиться всеми свойствами с моими дочерними элементами и создать PlayerPrefab с их свойствами?

< Сильный > EndEdit

ИЗМЕНИТЬ на простом примере

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 равен нулю. Это моя первая проблема.

enter image description here

< Сильный > EndEdit

Спросите меня, хотите ли вы подробностей.

Благодарность

2
Naografix 27 Дек 2016 в 11:40
Но это название ... Цвет Цвет, возможно, вы захотите это изменить. Возможно, это даже причина того, почему это не удается.
 – 
Everts
27 Дек 2016 в 13:47

1 ответ

Лучший ответ

Когда вы определяете публичный член (не свойство) в MonoBehaviour, значение, установленное инспектором, автоматически сериализуется для этого игрового объекта. Таким образом, когда вы создаете экземпляр этого игрового объекта, он будет автоматически восстановлен в созданный экземпляр игрового объекта.

Это также можно сделать без средства доступа 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()
    {

    }
}

Чтобы использовать его из своего игрового скрипта:

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()
    {

    }
}

Теперь, если вы решите получить доступ к PlayerBase из своих скриптов PlayerController и PlayerAimManager,

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

ИЛИ

PlayerBase playerBase = gameObject.GetComponent<PlayerLife>().pBase;
2
Programmer 27 Дек 2016 в 17:51
Я не знаю, что имел в виду OP, говоря «Мой цвет равен нулю». Может он что в редакторе не появляется? Если это так, то вы правы насчет свойства "set {} get {}", поэтому оно не отображается в редакторе.
 – 
Programmer
27 Дек 2016 в 15:36
Правильно Я сделал акцент на том, что не является свойством, однако я думаю, что OP не знает о сериализации полей, поскольку она может быть обработана автоматически.
 – 
Bizhan
27 Дек 2016 в 15:38
Вы имеете в виду, как добавить статический массив, содержащий все необходимые цвета?
 – 
Bizhan
27 Дек 2016 в 15:43
Нет-нет, просто свойство Color, у игроков разные цвета. Например, Life, Speed ​​и т. Д. Посмотрите мой простой пример. Как видите, мой верхний куб черный. Однако мой base.Color установлен, но не в моем PlayerLife
 – 
Naografix
27 Дек 2016 в 15:48
1
Вы можете скачать мой простой пример здесь: sentpace.com/file/55pbwa Я просто хочу создать плеер с другим цветом.
 – 
Naografix
27 Дек 2016 в 15:51