【问题标题】:Copying a string into a list isn't working - C#, Unity3D将字符串复制到列表中不起作用 - C#,Unity3D
【发布时间】:2019-09-08 16:08:00
【问题描述】:

我有一个对话系统和一个日志系统,应该允许玩家将刚刚说过的对话行复制到他们的日志中,但是,将字符串复制到列表中不起作用。

我一直在使用string.Copy 来复制字符串的值而不是引用,但它根本没有复制任何内容。剪切string.Copy 并复制参考似乎也不起作用。我要复制的行确实有一个值,我打印了一个debug.log 来打印它的值,然后再打印列表项的值(见下文)(编辑以包含完整的脚本)。

public class JournalTester : MonoBehaviour
{
    public List<DiaEntryClass> diaJournal = new List<DiaEntryClass>();

    GameObject diaSysObject;
    private DialogueSystem diaSysScript;
    string testLine = "inital value for testline";
    string testName = "Initial NPC name value";

    private void Update()
    {
        if (Input.GetKey("k"))
        {
            Debug.Log("K");
            diaSysObject = GameObject.Find("DialogueSystem");
            diaSysScript = diaSysObject.GetComponent<DialogueSystem>();
            testLine = diaSysScript.justSaid;
            testName = diaSysScript.justSpoke;

            Debug.Log("testLine post copy: " + testLine);


            diaJournal.Add(new DiaEntryClass(string.Copy(testLine), "Bernard's Apartment", string.Copy(testName)));
            Debug.Log("Using the string.Copy method.....................................................");
            Debug.Log("Dialogue Journal, Entry 0, Line: " + diaJournal[0].line);
            Debug.Log("Dialogue Journal, Entry 0, Character: " + diaJournal[0].character);
            Debug.Log("Dialogue Journal, Entry 0, Location: " + diaJournal[0].location);

            diaJournal.Add(new DiaEntryClass(testLine, "Bernard's Apartment", testName));
            Debug.Log("Not using the string.Copy method..................................................");
            Debug.Log("Dialogue Journal, Entry 1, Line: " + diaJournal[1].line);
            Debug.Log("Dialogue Journal, Entry 1, Character: " + diaJournal[1].character);
            Debug.Log("Dialogue Journal, Entry 1, Location: " + diaJournal[1].location);
        }
      }
    }


public class DiaEntryClass
{
    public string line;
    public string location;
    public string character;

    public DiaEntryClass (string line, string location, string character)
    {
        line = "initial line";
        location = "initial location";
        character = "character";
    }
}

上面是我用于对话条目的自定义类。 但无论我做什么,它似乎都不是那样工作的。以下是我的Debug.Log 行:

testLine 后文:您好!我的名字是 John Doe 使用 string.Copy 方法................................................. .... 对话 日记,条目 0,行:对话日记,条目 0,字符: 对话日志,条目 0,位置:不使用字符串。复制 方法................................................. . 对话 日记,条目 1,行:对话日记,条目 1,人物对话 日记,条目 1,位置:

字符串应打印为“John”。 Line 字符串应打印为“你好!我的名字是 John Doe”。 Location 字符串应打印为“Bernard's Apartment”。 所以testLine 确实有正确的值,因为它确实成功地打印了我正在使用的测试行,但是该值没有转移到列表中,我不知道为什么。我在 Unity 文档中找不到任何关于 String.Copy 的信息,所以我担心我用错了什么?我不确定。

【问题讨论】:

  • 想展示更多你的剧本?在调用 add 两次之后,您实际上是在打印索引 0 处的内容,我们不知道您之前添加了多少次。 (因此,在您的第二种情况下,您不想打印相同的索引,因为您添加了一个新条目。)
  • 另外,我建议添加debug.log(diaJournal.length) 或计算适合您的日记类型。
  • 还包括DiaEntryClass的定义
  • 我添加了更多脚本,但这是唯一一次创建和添加此列表。为了清楚起见,我专门添加了两次相同的索引,以测试是否使用 String.Copy 尝试复制值是否有效,或者如果不使用 String.Copy 复制引用是否有效。它在任何一种情况下都不起作用,所以我觉得留下它会很有用,以防有人提出建议。我认为默认情况下列表没有设定长度,但我可能错了。我包括了 DiaEntryClass,但它只包含三个字符串,没有什么疯狂的
  • 您的 DiaEntryClass 构造函数实际上并未将值设置为您传入的值。所以这是 1 个问题。

标签: c# visual-studio unity3d


【解决方案1】:

我对您的脚本进行了一些更新,希望您可以查看这些更改并尝试使用它们来找出您的脚本存在的问题,顺便说一句,复制和非复制方法都适用于我:

对 DiaEntryClass 的更改

[System.Serializable] // Makes it so you can view this classes data members in the inspector, so you should see your public list now.
public class DiaEntryClass
{
    public string line;
    public string location;
    public string character;

    public DiaEntryClass(string inLine, string inLocation, string inCharacter)
    {
        // Actually setting my variables to the values passed in...
        line = inLine;
        location = inLocation;
        character = inCharacter;
    }
}

更新的更改

// Update is called once per frame
void Update()
{
    // Using GetKeyDown so it runs only once, GetKey runs for every frame the key is held
    if (Input.GetKeyDown("k"))
    {
        Debug.Log("K");
        diaSysObject = GameObject.Find("DialogueSystem");
        diaSysScript = diaSysObject.GetComponent<DialogueSystem>();
        testLine = diaSysScript.justSaid;
        testName = diaSysScript.justSpoke;
        Debug.Log("testLine post copy: " + testLine);

        diaJournal.Add(new DiaEntryClass(string.Copy(testLine), "Bernard's Apartment + copy Method", string.Copy(testName)));
        diaJournal.Add(new DiaEntryClass(testLine, "Bernard's Apartment + non-copy method", testName));

        int index = 0;
        // Foreach to just loop through every entry
        foreach (DiaEntryClass dec in diaJournal)
        {
            Debug.Log("Dialogue Journal, Entry " + index + ", Line: " + dec.line);
            Debug.Log("Dialogue Journal, Entry " + index + ", Character: " + dec.character);
            Debug.Log("Dialogue Journal, Entry " + index + ", Location: " + dec.location);

            index++;
        }
    }
}

【讨论】:

  • 这对我有用!!非常感谢您耐心地指导我,我真的很感激!
  • @TaylorBazhaw, diaSysObject = GameObject.Find("DialogueSystem"); diaSysScript = diaSysObject.GetComponent&lt;DialogueSystem&gt;(); 应替换为在检查器中分配的缓存实例或在Start() 中使用FindObjectOfType&lt;DialogueSystem&gt;() 找到。 --- 原因:由于魔术字符串,按对象名称/标签查找不好。在Update() 和其他重复方法中应避免依赖管理。分别容易出错和性能关键。 --- 另外,如果 Eddge 的回答对您有帮助,请点赞,如果您认为这是对您问题的正确答案,请将其标记为已接受。
  • 你不应该使用string.Copy 在所有 ..它是遗留来自string是一个引用类型的时间。 .. 现在每个string 分配都等于一个副本,并且在某些情况下使用stromg.Copy 甚至会失败.. 而只是简单地传入string 本身。
  • @derHugo 我什至不知道谢谢我学到了一些新东西! tbh,我以前从未见过 string.copy 使用过。 TaylorBazhaw derHugo 和 XenoRo 的建议都是值得遵循的极好点。
猜你喜欢
  • 2020-08-02
  • 2019-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-14
  • 1970-01-01
  • 2018-08-26
  • 2013-09-14
相关资源
最近更新 更多