C#-更改函数内的数组值
在我的场景中,我在NPC的触发器上附加了一个C#脚本。基本上我只是试着让我的NPC和玩家“交谈”。如果玩家在NPC的触发器内并按下“E”键,则NPC应说出第一条未说出的消息,在我的数组C#-更改函数内的数组值,c#,arrays,pointers,unity3d,unity5,C#,Arrays,Pointers,Unity3d,Unity5,在我的场景中,我在NPC的触发器上附加了一个C#脚本。基本上我只是试着让我的NPC和玩家“交谈”。如果玩家在NPC的触发器内并按下“E”键,则NPC应说出第一条未说出的消息,在我的数组消息中定义 消息在3秒钟后消失,然后用户可以再次激活NPC,并且应选择并返回阵列中的下一条消息 为了解决这个问题,我创建了一个bool数组messageStatus,它保存消息已告知的状态 因此消息的索引0对应于消息状态的索引0 我编写了一个名为selectMessage的函数,在该函数中,我传递两个数组,然后获
消息中定义
消息在3秒钟后消失,然后用户可以再次激活NPC,并且应选择并返回阵列中的下一条消息
为了解决这个问题,我创建了一个bool数组messageStatus
,它保存消息已告知的状态
因此消息
的索引0对应于消息状态
的索引0
我编写了一个名为selectMessage
的函数,在该函数中,我传递两个数组,然后获取状态数组的第一个索引位置,其中值为false
,然后返回带有该索引的消息。然后我将该索引上的状态设置为true
,因为消息已被告知
但是,初始化(status[i]=true;
)似乎并没有改变原始数组,只是改变了参数。因为我的NPC总是告诉最后一条消息
我想我必须将数组作为指针传递,但我不确定这是如何工作的,我的尝试到目前为止都失败了
我怎样才能解决这个问题
string selectMessage(string[] messages, bool[] status)
{
for (int i = 0; i <= status.Length-1; i++) {
if (status[i] == false) {
status[i] = true; //<-- problem
return messages[i];
}
}
return "Is everything ok?";
}
string selectMessage(string[]消息,bool[]状态)
{
对于(int i=0;i
//第一个可能的解决方案
string selectMessage(string[] messages,ref bool[] status)
{
for (int i = 0; i <= status.Length-1; i++) {
if (status[i] == false) {
status[i] = true;
return messages[i];
}
}
return "Is everything ok?";
}
我发现问题出在其他地方,甚至不需要使用ref
或指针将数组作为引用传递。但我很高兴你们推荐了它,并感谢你们提供的非常有用的提示
这是一个逻辑错误。我认为最后一条消息总是显示出来,因为OnGUI每帧都执行一次(afaik)
我根据@Everts的建议更改了逻辑,这显然要好得多。我删除了根本不需要的状态数组
固定脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TalkMalon : MonoBehaviour {
public float displayTime = 3;
public bool showMessage = false;
public string[] messages = {
"Hello, my name is Heinrich.",
"I have nothing more to say."
};
public bool[] messageStatus = {
false,
false
};
void Update()
{
if (showMessage) {
displayTime -= Time.deltaTime;
if (displayTime <= 0.0) {
showMessage = false;
displayTime = 3;
}
}
}
void OnTriggerStay()
{
if (Input.GetKeyDown(KeyCode.E)) {
showMessage = true;
}
}
void OnGUI()
{
if (showMessage) {
GUI.Label(new Rect(Screen.width / 2, Screen.height / 2, 200f+100f, 200f), selectMessage(messages, messageStatus));
}
}
string selectMessage(string[] messages, bool[] status)
{
for (int i = 0; i <= status.Length-1; i++) {
if (status[i] == false) {
status[i] = true;
return messages[i];
}
}
return "Is everything ok?";
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TalkMalon : MonoBehaviour
{
private int index = 0;
private string currentMessage = "";
private float displayTime = 3;
private bool showMessage = false;
private bool selectNextMessage = false;
public string[] messages = {
"Hello, my name is Heinrich.",
"I have nothing more to say."
};
void Update()
{
if (showMessage) {
displayTime -= Time.deltaTime;
if (displayTime <= 0.0) {
showMessage = false;
displayTime = 3;
Debug.Log(messages.Length);
if (index != messages.Length - 1) {
index++;
}
}
}
}
void OnTriggerStay()
{
if (Input.GetKeyDown(KeyCode.E)) {
showMessage = true;
}
}
void OnGUI()
{
if (showMessage) {
GUI.Label(new Rect(Screen.width / 2, Screen.height / 2, 200f, 200f), messages[index]);
}
}
}
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
公共课堂谈话马龙:单一行为
{
私有整数指数=0;
私有字符串currentMessage=“”;
私有浮动显示时间=3;
private bool showMessage=false;
private bool selectNextMessage=false;
公共字符串[]消息={
“你好,我叫海因里希。”,
“我没什么可说的了。”
};
无效更新()
{
如果(显示消息){
displayTime-=Time.deltaTime;
if(displayTime我真的不认为需要两个数组。在您显示的逻辑中,您使用消息数组是为了将它们添加到集合中。因此,您可以只使用索引:
int index = 0;
string[] messages;
string GetNextMessage()
{
return (++index < messages.Length) ? messages[index] : "Is everything ok?";
}
int索引=0;
字符串[]消息;
字符串GetNextMessage()
{
return(++index
这实际上更好,因为您不必迭代集合来查找下一条消息。在算法中,您的解决方案是O(n),这意味着最坏的情况是集合的大小。我的解决方案是O(1)这意味着最坏的情况是一个动作。使用C#的ref
参数支持。与您的问题稍有关联,但为什么不创建一个包含消息和bool的小类,描述是否已告知。然后您就拥有了这些集合,而不是两个集合?使用上面Dave的建议或使用KeyValuePair
。这里到底有什么问题?谢谢你的提示,我真的很感激:)问题是我的NPC总是告诉最后一条消息为什么这里需要ref?他影响的是数组的内容而不是数组引用。为什么建议静态?也不需要。您将得到一些越界异常。在OnTiggerStay中,showMessage=(indexshowMessage=(index
。我测试了代码,没有预期结果。如果你继续去NPC,按E键,因为索引永远不会设置回0,它会不断增加。你需要防止索引超过消息。长度。如果索引太大,我给出的行将阻止你运行代码。@Everts,我已经用行阻止了它(index!=messages.Length-1){
int index = 0;
string[] messages;
string GetNextMessage()
{
return (++index < messages.Length) ? messages[index] : "Is everything ok?";
}