这是我的第一个统一项目,也是我的第一篇文章,因此,如果我需要提供更多信息或类似信息,请发表评论。
我目前正在尝试制作一个小型游戏,该游戏中的所有信息都将自动保存,并在GrowthScore方法内调用Save方法之后且场景自动更改之前将其附加到一个csv文件中。 保存我的分数,并在其他单元格中填充诸如currentLevel之类的信息,即可顺利获得分数。但是现在我需要从另一个类中保存最终的坐标变量,该类会在其Update方法中不断更新,而我陷入了困境。重要的是每个变量的最终更新值,因为坐标变量基于HTC Vive左手的左手控制位置,因此我需要计算总运动量。 显然,我对创建另一个类/更新方法的实例的理解太差,因为我无法从其他文章中找到如何解决它的方法。 以下是我的代码和收到的错误消息,非常感谢您提供的任何帮助。
错误消息: “ NullReferenceException:对象引用未设置为对象的实例 GameManager.IncreaseScore(Int32量)(在Assets / Scripts / GameManager.cs:159) SwordCutter.OnCollisionEnter(UnityEngine.Collision碰撞)(位于Assets / Scripts / SwordCutter.cs:53)“
我了解我需要以某种方式创建LeftControllerTracking类的实例,但是我不确定如何以及在何处创建实例。下面提供的LeftControllerTracking脚本已附加到检查器中的GameObject ControllerLeft。 我还通过检查器视图中的GameManager脚本将ControllerLeft GameObject拖动到GameManager对象。
我的GameManager类:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Text;
public class GameManager : MonoBehaviour
{
//the new part
public GameObject leftposition;
LeftControllerTracking leftController;
public List<string[]> rowData = new List<string[]>();
// Player score
public int score = 0;
// High score
public int highScore = 0;
// Static instance of the Game Manager,
// can be access from anywhere
public static GameManager instance = null;
// Level, starting in level 1
public int currentLevel = 1;
// Highest level available in the game
public int highestLevel = 3;
// Called when the object is initialized
void Awake()
{
// if it doesn't exist
if (instance == null)
{
print("assigning GameManager instance");
// Set the instance to the current object (this)
instance = this;
}
// There can only be a single instance of the game manager
else if (instance != this)
{
print("GameManager instance already exists");
// Destroy the current object, so there is just one manager
Destroy(gameObject);
return;
}
// Don't destroy this object when loading scenes
DontDestroyOnLoad(gameObject);
}
private void Update()
{
//new part that is missplaced and can't be accessed anyway it seems
//leftX = leftController.finalMovementX;
//leftY = leftController.finalMovementY;
//leftZ = leftController.finalMovementZ;
}
// Need the finalMovement variables as argument here
public void Save(int score, int currentLevel, float leftX, float leftY, float leftZ)
{
// Creating First row of titles manually the first time i use the script
string[] rowDataTemp = new string[7];
rowDataTemp[0] = "Name";
rowDataTemp[1] = "ID";
rowDataTemp[2] = "Lvl";
rowDataTemp[3] = "Score";
rowDataTemp[4] = "X Movement";
rowDataTemp[5] = "Y Movement";
rowDataTemp[6] = "Z Movement";
//rowDataTemp[3] = "Total Movement";
rowData.Add(rowDataTemp);
// You can add up the values in as many cells as you want.
for (int i = 0; i < 1; i++)
{
rowDataTemp = new string[7];
rowDataTemp[0] = "Andreas"; // name
rowDataTemp[1] = "1"; // ID
rowDataTemp[2] = "" + currentLevel; // Score
rowDataTemp[3] = "" + score; // Score
rowDataTemp[4] = "" + leftX; // X Movement
rowDataTemp[5] = "" + leftY; // Y Movement
rowDataTemp[6] = "" + leftZ; // Z Movement
rowData.Add(rowDataTemp);
}
string[][] output = new string[rowData.Count][];
for (int i = 0; i < output.Length; i++)
{
output[i] = rowData[i];
}
int length = output.GetLength(0);
string delimiter = ",";
StringBuilder sb = new StringBuilder();
for (int index = 0; index < length; index++)
sb.AppendLine(string.Join(delimiter, output[index]));
string filePath = getPath();
//switch to System.IO.File.AppendText(filePath); the second time you use the script
StreamWriter outStream = System.IO.File.CreateText(filePath);
outStream.WriteLine(sb);
outStream.Close();
}
// Following method is used to retrive the relative path as device platform
private string getPath()
{
#if UNITY_EDITOR
return Application.dataPath + "/CSV/" + "Saved_data.csv";
#elif UNITY_ANDROID
return Application.persistentDataPath+"Saved_data.csv";
#elif UNITY_IPHONE
return Application.persistentDataPath+"/"+"Saved_data.csv";
#else
return Application.dataPath +"/"+"Saved_data.csv";
#endif
}
// Increase score
public void IncreaseScore(int amount)
{
// Increase the score by the given amount
score += amount;
// Show the new score in the console
print("New Score: " + score.ToString());
if (score > highScore)
{
highScore = score;
print("New high score: " + highScore);
}
if (score > 24)
{
// Increase level
Save(score, currentLevel, leftController.finalMovementX, leftController.finalMovementY, leftController.finalMovementZ);
GameManager.instance.IncreaseLevel();
}
}
// Restart game. Refresh previous score and send back to level 1
public void Reset()
{
// Reset the score
score = 0;
// Set the current level to 1
currentLevel = 1;
// Load corresponding scene (level 1 or "splash screen" scene)
SceneManager.LoadScene("Level" + currentLevel);
}
// Go to the next level
public void IncreaseLevel()
{
if (currentLevel < highestLevel)
{
currentLevel++;
}
else
{
currentLevel = 3;
}
SceneManager.LoadScene("Level" + currentLevel);
}
}
附加到我的ControllerLeft游戏对象的我的LeftControllerTracking:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LeftControllerTracking : MonoBehaviour {
public Transform track;
public Transform cachedTransform;
public Vector3 cachedPosition;
public float finalMovementX = 0;
public float finalMovementY = 0;
public float finalMovementZ = 0;
void Start()
{
if (track)
{
cachedPosition = track.position;
}
}
public void Update()
{
if (track && cachedPosition != track.position)
{
finalMovementX = (finalMovementX + (track.position.x - cachedPosition.x));
finalMovementY = (finalMovementY + (track.position.y - cachedPosition.y));
finalMovementZ = (finalMovementZ + (track.position.z - cachedPosition.z));
print("New Total Left Katana X cordinate: " + finalMovementX);
print("New Total Left Katana Y cordinate: " + finalMovementY);
print("New Total Left Katana Z cordinate: " + finalMovementZ);
cachedPosition = track.position;
transform.position = cachedPosition;
}
}
}
答案 0 :(得分:0)
最简单的解决方案是公开展示
public LeftControllerTracking leftController;
然后您可以在编辑器中分配文件,对于您的用例来说,这应该足够了,因为对象的实例已经存在,所以您没有对其的引用
答案 1 :(得分:0)
以下是将字段公开给Unity中其他类的一些方法:
另外,将帖子标记为重复可能很有意义,但是新的stackoverflowers需要积分。