在Unity C#中,从另一个脚本向列表中添加数据

3

第一次使用Stackoverflow,非常感谢您提供的任何帮助或示例。目标是从另一个脚本中填充名为“playerList”的列表,其中包含“PlayerTank”对象。

我在名为“PlayerList”的脚本中创建了一个名为“playerList”的列表

在此过程中,我创建了子类“PlayerTank”及其构造函数。目标是使用“PlayerTank”对象填充“playerList”。以下是代码:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class PlayerList : MonoBehaviour {

    public List<PlayerTank> playerList;

    public class PlayerTank { // Here is my class for PlayerTank

        public int playerNumber;
        public int playerPadNumber;
        public string playerName;
        public string playerColour;


        // This is a constructor to make an instance of my class. 

        public PlayerTank (int newPlayerNumber, int newPlayerPadNumber, string newPlayerName, string newPlayerColour) 
        {
            playerNumber = newPlayerNumber;
            playerPadNumber = newPlayerPadNumber;
            playerName = newPlayerName;
            playerColour = newPlayerColour;
        }


    }


void Start () {

        playerList = new List<PlayerTank>();

    }

    }
}

上述内容很好地运作了。
然而,在一个完全独立的名为“Test”的脚本中,我现在正在尝试将playerTank对象添加到此列表中。
以下任何一项都无法正常工作,但我包含它以便能够给出我的思维过程!
using UnityEngine;
using System.Collections;
using System.Collections.Generic;


public class Test : MonoBehaviour {

    public GameObject playerData;
    PlayerList playerList;
    PlayerTank playerTank;



    // Use this for initialization
    void Start () {
        playerList = playerData.GetComponent<PlayerList> ();
        playerTank = PlayerList.PlayerTank;

        playerList.playerList.Add (new playerTank.playerTank(1,2,"a player name", "black")); 
    }

}

当然,以上所有方法都行不通!非常感谢您的帮助!
1个回答

3
首先,欢迎来到StackOverflow。为了实现您想要的功能,您需要将这些脚本附加到层次结构中的游戏对象上(最好是两个)。有两种解决方案:第一种是将PlayerList声明为Test的公共字段,并通过UI进行赋值(将持有PlayerList脚本的GameObject拖放到Test GameObject中字段定义中):

enter image description here

using UnityEngine;
using System.Collections;
using System.Collections.Generic;


public class Test : MonoBehaviour {

    public PlayerList playerList; //replace GameObject with PlayerList 

    // Use this for initialization
    void Start () {

        var playerTankList = playerList.PlayerTankList; // You can access it directly

        playerTankList .Add (new PlayerList.PlayerTank(1,2,"a player name", "black")); 
    }

}

请务必在PlayerList类上添加[Serializable]属性,以便在UI中查看Test中声明的字段。

第二种解决方案更加直接。您只需使用一个Unity函数来检索与层次结构中存在的GameObject相关联的特定类型。该函数称为FindObjectOfType(); 在这个第二种解决方案中,您的Test类将如下所示:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;


public class Test : MonoBehaviour
{ 
    // Use this for initialization
    void Start()
    {
        var playerList = FindObjectOfType<PlayerList>();

        playerList.PlayerTankList.Add(new PlayerList.PlayerTank(1, 2, "a player name", "black"));
    }

}

编辑:

我在下面重新编写并添加了你的原始PlayerList类。我使用Awake替换了Start函数,在Unity事件链中,它在Start之前被调用。你仍然看到NullReferenceException的原因是因为Start事件没有按任何特定的顺序调用。所以Test类中的Start事件可能会在PlayerList类中的Start事件之前发生。但是,我测试过了,如果你正确地关联游戏对象,它可以正常工作:

正确设置的PlayerList游戏对象

using System;
using UnityEngine; 
using System.Collections.Generic;

[Serializable]
public class PlayerList : MonoBehaviour
{
    public List<PlayerTank> PlayerTankList;

    public class PlayerTank
    { // Here is my class for PlayerTank

        public int playerNumber;
        public int playerPadNumber;
        public string playerName;
        public string playerColour;


        // This is a constructor to make an instance of my class. 

        public PlayerTank(int newPlayerNumber, int newPlayerPadNumber, string newPlayerName, string newPlayerColour)
        {
            playerNumber = newPlayerNumber;
            playerPadNumber = newPlayerPadNumber;
            playerName = newPlayerName;
            playerColour = newPlayerColour;
        }
    }


    void Awake()
    {
        PlayerTankList = new List<PlayerTank>();
    }

}

希望这能有所帮助。

1
谢谢回复!我尝试了你的解决方案,但它们似乎没有起作用。第二个解决方案出现了如下错误:error CS1061: Type PlayerList' does not contain a definition for Add' and no extension method Add' of type PlayerList' could be found (are you missing a using directive or an assembly reference?)看起来它没有识别为列表。 - Jim
我对我的和你的帖子进行了编辑。我将playerList重命名为PlayerTankList,并相应地在我的帖子上进行了编辑。 - codingadventures
哎呀,抱歉。第一种解决方案仍然会产生这个错误:NullReferenceException: Object reference not set to an instance of an object。 - Jim
使用Awake函数来初始化你的对象playerlist,而不是使用Start函数。无论如何,第一个解决方案假设你通过UI在测试脚本中分配了player list字段。 - codingadventures
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接