Мне нужна небольшая помощь для унаследования моего игрока в моей маленькой 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 равен нулю. Это моя первая проблема.
< Сильный > EndEdit
Спросите меня, хотите ли вы подробностей.
Благодарность
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;
Похожие вопросы
Новые вопросы
c#
C# (произносится как «see Sharp») — это высокоуровневый мультипарадигменный язык программирования со статической типизацией, разработанный Microsoft. Код C# обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, которое включает в себя .NET, .NET Framework, .NET MAUI и Xamarin среди прочих. Используйте этот тег для ответов на вопросы о коде, написанном на C#, или о формальной спецификации C#.