我在Unity中开发的C#游戏遇到问题。在编辑器中,带有动画的文本通知会被触发,但在我构建和运行时不会触发。
我检查了输出日志并得到了它。
NullReferenceException: Object reference not set to an instance of an object
at NarrativeLocation+<InitializePanel>c__Iterator0.MoveNext () [0x00000]
in <filename unknown>:0
at UnityEngine.SetupCoroutine.InvokeMoveNext (IEnumerator enumerator,
IntPtr returnValueAddress) [0x00000] in <filename unknown>:0
UnityEngine.MonoBehaviour:StartCoroutine_Auto_Internal(IEnumerator)
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
NarrativeLocation:Update()
NarrativeLocation.Update的代码
void Update()
{
if (!popupIsPlaying && GameState.popupQueue.Count != 0)
{
int temp = GameState.popupQueue.Dequeue();
StartCoroutine(InitializePanel(temp));
}
int num = 1;
while(inZone)
{
if (this.gameObject.tag == "NarrativeEvent" + num)
{
if (Input.GetKeyDown(KeyCode.E))
{
Destroy(GameObject.FindGameObjectWithTag("Notification"));
Destroy(GameObject.FindGameObjectWithTag("NarrativeEvent" + num));
Constants.GameState.popupQueue.Enqueue(num);
}
return;
}
num++;
}
}
InitializePanel代码
IEnumerator InitializePanel(int num)
{
popupIsPlaying = true;
panel = GameObject.Find("Panel").GetComponent<PanelConfig>();
currentEvent = JSONAssembly.RunJSONFactoryForScene(1);
StartCoroutine(IntroAnimation());
panel.characterIsTalking = true;
panel.Configure(currentEvent.dialogues[num - 1]);
yield return new WaitForSeconds(6f);
StartCoroutine(ExitAnimation());
Debug.Log("Event " + num + " destroyed");
popupIsPlaying = false;
}
public IEnumerator IntroAnimation()
{
panelAnimator.SetBool("IntroAnimationIn", true);
yield break;
}
public IEnumerator ExitAnimation()
{
panelAnimator.SetBool("IntroAnimationIn", false);
yield break;
}
运行游戏时,面板弹出,没有任何文字。退出动画似乎也没有被调用。
JSON汇编类。
namespace JSONFactory {
class JSONAssembly {
private static Dictionary<int, string> _resourceList = new Dictionary<int, string>
{
{1, "/Resources/GameScript.json"}
};
public static NarrativeEvent RunJSONFactoryForScene(int sceneNumber)
{
string resourcePath = PathForScene(sceneNumber);
if (isValidJSON(resourcePath) == true)
{
string jsonString = File.ReadAllText(Application.dataPath + resourcePath);
NarrativeEvent narrativeEvent = JsonMapper.ToObject<NarrativeEvent>(jsonString);
return narrativeEvent;
}
else
{
throw new Exception("JSON is not valid");
}
}
private static string PathForScene(int sceneNumber)
{
string resourcePathResult;
if (_resourceList.TryGetValue(sceneNumber, out resourcePathResult))
{
return _resourceList[sceneNumber];
}
else
{
throw new Exception("Scene not in resource list");
}
}
private static bool isValidJSON(string path)
{
return (Path.GetExtension(path) == ".json") ? true : false;
}
}
}
答案 0 :(得分:2)
在编辑器中触发带有动画的文本通知时, 但是在我构建和运行时没有。
我可以找到一些可能的原因,为什么您的代码无法在构建中工作。我可能想念的还有更多,但请在下面查看它们:
1 。您尝试从以下位置加载json文件的地方:
{1, "/Resources/GameScript.json"}
A 。从资源文件夹中读取时,路径中不要包含“资源”。该路径是相对于Resource文件夹的。
B 。请勿在路径中包含文件扩展名,例如.txt,.jpeg,.mp3。
要解决这两个问题,请替换:
{1, "/Resources/GameScript.json"}
使用
{1, "GameScript"}
2 。您当前如何读取文件:
string jsonString = File.ReadAllText(Application.dataPath + resourcePath);
您当前正在使用File.ReadAllText
读取文件。这将在编辑器中起作用,但在构建中不起作用,因为这不是读取Resources文件夹中文件的方式。
使用Resources API读取Resources文件夹中的文件。
要解决此问题,请替换:
string jsonString = File.ReadAllText(Application.dataPath + resourcePath);
使用
TextAsset txtAsset = Resources.Load<TextAsset>(resourcePath);
string jsonString = txtAsset.text;
确保将json文件放在项目中名为“ Resources”的文件夹中,并且必须正确拼写。
其他问题可能会在以后出现:
无限循环:
while(inZone)
代码无法退出,如果遇到这种情况,则可能会导致程序冻结,因为在该循环中没有代码会使inZone
变为false 。您必须找到一种方法来重写该代码。
答案 1 :(得分:0)
在内部版本中,不能在运行时使用File.ReadAllText使用资源路径加载文件。在构建过程中,Resources /目录中的文件将打包成专有的打包资产格式,并且无法通过这种方式在路径中进行检索。
如果要以这种方式加载文件,则必须使用Resources api。
但是,以这种方式在运行时读取位于Application.streamingAssetsPath
(又名/Assets/StreamingAssets
) CAN 中的文件。该文件夹中的文件将保留原样。可以通过
System.IO.Path.Combine(
Application.streamingAssetsPath, "/Path/To/file.json");
// assuming path is:
// /Assets/StreamingAssets/Path/To/file.json
资源可能更接近您想要的资源。
或者,Unity将json文件(或与此相关的任何其他文本文件)导入为TextAssets
。您可以像其他任何类型的资产一样在检查器中引用这些TextAsset
文件。
public class MyMono : MonoBehaviour
{
public TextAsset json;
void Start() {
Debug.Log(json.text);
}