Saving a 2D array as JSON - c#
I Have problem to save my simulation into JSON File.
the basics I make a moving ship. in the world space there will be a probe button that will provide information about the ship. I want to save that information into JSON.
Anyone know how to do that. I am new in Unity.
In button () I want to save the ship information (eg. position, depthsea, windspeed, temperature,flow
public class test : MonoBehaviour
{
// Start is called before the first frame update
public GameObject Ship;
public GameObject hole;
public GameObject turtle;
public GameObject panelhole;
public GameObject panelturtle;
public RectTransform shipvalue;
//public RectTransform flowvalue;
//public RectTransform windspeedvalue;
//public RectTransform temperaturevalue;
//public RectTransform depthvalue;
public Vector3 offset;
public RectTransform Basicobject; //parent
//public static bool captureAllKeyboardInput = false;
private bool paneloff = false;
public float duration = 1;
public int[,] grid = new int[10, 16];
public float[,] depth = new float[4, 3]
{{1.6f, 2.3f, 3.5f },
{4, 5, 6.5f},
{7, 8, 6.5f},
{7, 8, 6.5f}};
public float[,] temperaturedata = new float[10, 16]
{{0, 0, 0, 0, 0, 0, 0, 22.5f, 22.7f, 23, 23.9f, 24, 26.3f, 26.4f, 26.4f, 26.3f},
{0, 0, 0, 0, 0, 0, 22.8f, 23.2f, 23.8f, 24.4f, 25, 24.3f, 26.5f, 26.5f, 26.5f, 26.6f},
{0, 0, 0, 0, 0, 22.5f, 23.1f, 24.8f, 25.3f, 25.7f, 0, 0, 26.7f, 26.3f, 26.2f, 26.6f},
{0, 0, 0, 0, 23.2f, 23.8f, 25.1f, 25.4f, 25.9f, 0, 0, 26.8f, 26.9f, 26.5f, 26.3f, 26.3f},
{0, 0, 24.5f, 23.3f, 23.9f, 24.5f, 25.7f, 25.6f, 26.8f, 0, 0, 26.9f, 27.1f, 26.6f, 26.4f, 26.4f},
{0, 24.1f, 23.9f, 24.9f, 25.4f, 25.5f, 25.9f, 27.4f, 27.2f, 0, 0, 27, 27.2f, 26.8f, 26.4f, 26 },
{27.4f, 27.7f, 27.3f, 26.2f, 26.2f, 25.9f, 27.5f, 27.7f, 27.3f, 0, 26.8f, 27.2f, 27.2f, 26.9f, 26.4f, 26.2f},
{28.5f, 29, 27.5f, 27.3f, 27.3f, 27.5f, 27.7f, 27.7f, 27.5f, 27.2f, 27.2f, 27.4f, 27.4f, 26.9f, 26.3f, 26.7f},
{28.5f, 27.6f, 27.1f, 27, 26.5f, 27.6f, 27.6f, 27.6f, 27.7f, 27.4f, 27.8f, 27.7f, 27.7f, 27, 27, 26.6f},
{28.5f, 27.6f, 25, 27.3f, 26.8f, 27.8f, 27.3f, 27.5f, 28.1f, 27.9f, 28, 27.6f, 27.7f, 26.9f, 27.1f, 26.8f}};
public float[,] flowdata = new float[10, 16]
{{0, 0, 0, 0, 0, 0, 0, 0.4f, 0.4f, 0.6f, 0.8f, 0.6f, 0.7f, 0.4f, 0.4f, 0.4f},
{0, 0, 0, 0, 0, 0, 0.3f, 0.5f, 0.5f, 0.8f, 0.8f, 0.8f, 0.6f, 0.6f, 0.5f, 0.5f},
{0, 0, 0, 0, 0, 0.4f, 0.7f, 0.7f, 0.7f, 0.7f, 0, 0, 0.9f, 0.6f, 0.4f, 0.4f},
{0, 0, 0, 0, 0.5f, 0.5f, 0.6f, 0.7f, 0.6f, 0, 0, 0.8f, 0.8f, 0.4f, 0.3f, 0.3f},
{0, 0, 000, 0.7f, 0.6f, 0.5f, 0.7f, 1, 0.8f, 0, 0, 0.9f, 0.5f, 0.3f, 0.1f, 0.3f},
{0, 0.5f, 0.7f, 0.6f, 0.8f, 0.8f, 1.3f, 0.9f, 0.5f, 0, 0, 0.8f, 0.3f, 0.1f, 0.2f, 0.2f},
{0.6f, 0.6f, 0.6f, 0.7f, 1.1f, 0.9f, 0.8f, 0.4f, 0.3f, 0, 0.9f, 0.6f, 0.2f, 0.2f, 0.2f, 0.2f},
{0.4f, 0.4f, 0.5f, 0.5f, 0.3f, 0.4f, 0.3f, 0.2f, 0.4f, 0.2f, 0.8f, 0.3f, 0.2f, 0.2f, 0.2f, 0.1f},
{000, 0.3f, 0.5f, 0.2f, 0.2f, 0.2f, 0.2f, 0.1f, 0.2f, 0.6f, 0.6f, 0.3f, 0.3f, 0.2f, 0.2f, 0.2f},
{000, 000, 0.1f, 0.4f, 0.3f, 0.3f, 0.2f, 0.2f, 0.1f, 0.2f, 0.3f, 0.1f, 0.2f, 0.2f, 0.2f, 0.2f}};
public float[,] windspeeddata = new float[10, 12]
{{0,0,0,0,0,0,0,4,4,4,3,3},
{0,0,0,0,0,0,4,5,4,3,3,3},
{0,0,0,0,0,5,5,5,5,3,0,0},
{0,0,0,0,4,4,4,4,4,0,0,3},
{0,0,3,0,4,4,4,4,4,0,0,3},
{0,4,4,4,4,4,4,4,3,0,0,3},
{4,4,4,4,4,4,4,3,3,0,3,4},
{5,4,4,4,4,4,3,3,3,3,4,4},
{4,4,4,4,4,4,3,3,3,3,4,4},
{5,4,4,4,4,4,4,4,4,3,3,3}};
int row, column, num1, num2;
int p1;
int p2;
int[] grid2 = new int[5];
public Text shiposition = null;
public Text depthtext = null;
public Text windspeedtext = null;
public Text temperaturetext = null;
public Text flowtext = null;
//direction = Ship.transform.rotation.z;
float LastMove;
float timeIn = 0.5f;
public Vector3 direction;
float zvalue;
[Serializable]
public class ShipData
{
public int grid;
public float depth;
public float windspeed;
public float temperature;
}
[SerializeField]
private ShipData JSON_ShipData = new ShipData();
public void SaveintoJson()
{
string data = JsonUtility.ToJson(JSON_ShipData);
System.IO.File.WriteAllText(Application.persistentDataPath + "/DataCenter.json", data);
Debug.Log("Saving as JSON" + JSON_ShipData);
Debug.Log(Application.persistentDataPath);
}
void Start()
{
p1 = 9;
p2 = 0;
grid[p1, p2] = 1;
panelhole.SetActive(false);
panelturtle.SetActive(false);
Debug.Log(grid[p1, p2]);
Debug.Log(shiposition.transform.position);
}
// Update is called once per frame
void Update()
{
//Debug.Log(Ship.transform.localEulerAngles.z);
zvalue = Ship.transform.localEulerAngles.z;
if (Input.GetKeyDown(KeyCode.RightArrow))
{
StartCoroutine(Forward());
}
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
StartCoroutine(Backward());
}
if (Input.GetKeyDown(KeyCode.DownArrow))
{
StartCoroutine(Rotate(Vector3.forward, -90, 1.0f));
Debug.Log(transform.rotation.eulerAngles.z);
}
if (Input.GetKeyDown(KeyCode.UpArrow))
{
StartCoroutine(Rotate(Vector3.forward, 90, 1.0f));
Debug.Log(transform.rotation.eulerAngles.z);
}
if (Time.time - LastMove > timeIn)
{
LastMove = Time.time;
}
if (Input.GetKeyDown(KeyCode.W))
{
StartCoroutine(Rotate(Vector3.forward, 90, 1.0f));
// position(grid);
// depthsea(depth);
}
if (Input.GetKeyDown(KeyCode.A))
{
if (p2 >= 0)
{
StartCoroutine(Backward());
grid[p1, p2] = 0;
grid[p1, --p2] = 1;
//position(grid);
//depthsea(depth);
}
else
{
Debug.Log("You can't move left!!");
}
}
if (Input.GetKeyDown(KeyCode.D))
{
// z = 0
if (p2 <= 12 && zvalue == 0)
{
StartCoroutine(Forward());
grid[p1, p2] = 0;
grid[p1, ++p2] = 1;
//position(grid);
//depthsea(depth);
Debug.Log(zvalue);
}
// z = 270
else if (p2 <= 12 && zvalue == 270)
{
StartCoroutine(Forward());
grid[p1, p2] = 0;
grid[++p1, p2] = 1;
// position(grid);
//depthsea(depth);
Debug.Log(zvalue);
}
//// z = 180
else if (p2 <= 12 && zvalue == 180)
{
StartCoroutine(Forward());
grid[p1, p2] = 0;
grid[p1, --p2] = 1;
// position(grid);
//depthsea(depth);
Debug.Log(zvalue);
}
//// z = 90
else if (p2 <= 12 && zvalue == 90)
{
StartCoroutine(Forward());
grid[p1, p2] = 0;
grid[--p1, p2] = 1;
// position(grid);
//depthsea(depth);
Debug.Log(zvalue);
}
else
{
Debug.Log("You can't move right any further!!");
Debug.Log(Ship.transform.localEulerAngles.z);
}
}
if (Input.GetKeyDown(KeyCode.S))
{
StartCoroutine(Rotate(Vector3.forward, -90, 1.0f));
//position(grid);
//depthsea(depth);
}
//WebGLInput.captureAllKeyboardInput = false;
}
private void position(int[,] grid)
{
for (int i = 0; i < grid.GetLength(0); i++)
{
for (int j = 0; j < grid.GetLength(1); j++)
{
if (grid[i, j] == 1)
{
// Debug.Log("x: " + i + " y: " + j + " Grid: " + grid[i, j]);
shiposition.text = "X : " + i + " " + "Y : " + j;
shiposition.text.ToString();
PlayerPrefs.SetString("position", shiposition.text);
PlayerPrefs.Save();
Debug.Log(shiposition.text);
}
}
}
}
public void windspeed(float[,] windspeeddata)
{
for (int x = 0; x < windspeeddata.GetLength(0); x++)
{
for (int y = 0; y < windspeeddata.GetLength(1); y++)
{
if (grid[x, y] == 1)
{
windspeedtext.text = "Windspeed Level :" + windspeeddata[x, y];
}
}
}
}
public void temperature(float[,] temperaturedata)
{
for (int x = 0; x < temperaturedata.GetLength(0); x++)
{
for (int y = 0; y < temperaturedata.GetLength(1); y++)
{
if (grid[x, y] == 1)
{
//Debug.Log(temperaturedata[x, y]);
temperaturetext.text = "Temperature :" + temperaturedata[x, y] + "C";
}
}
}
}
public void flow(float[,] flowdata)
{
for (int x = 0; x < flowdata.GetLength(0); x++)
{
for (int y = 0; y < flowdata.GetLength(1); y++)
{
if (grid[x, y] == 1)
{
flowtext.text = "Flow :" + flowdata[x, y];
}
}
}
}
public void depthsea(float[,] depth)
{
for (int x = 0; x < depth.GetLength(0); x++)
{
for (int y = 0; y < depth.GetLength(1); y++)
{
if (grid[x, y] == 1)
{
depthtext.text = "Depth :" + depth[x, y];
Debug.Log(depth[x, y]);
}
}
}
}
public void moveobject()
{
shipvalue.transform.position = Ship.transform.position;
//shipvalue.transform.position.y + 0.5f;
//flowvalue.transform.position = Ship.transform.position;
//windspeedvalue.transform.position = Ship.transform.position;
//temperaturevalue.transform.position = Ship.transform.position;
//depthvalue.transform.position = Ship.transform.position;
}
public void button()
{
position(grid);
depthsea(depth);
windspeed(windspeeddata);
temperature(temperaturedata);
flow(flowdata);
moveobject();
//value.transform.position = Ship.transform.position;
//string newposition = JsonUtility.ToJson(shiposition.text);
//System.IO.File.WriteAllText(Application.persistentDataPath + "PositionData.json", newposition);
//Debug.Log(shiposition.text);
}
The JSON export itself should work that way
However, never use + "/" for system file paths. Rather use Path.Combine which inserts the correct path separator automatically
System.IO.File.WriteAllText(Path.Combine(Application.persistentDataPath, "DataCenter.json", data);
Main Problem
You are never assigning any values into the JSON_ShipData so you will always export a JSON with default values!
So first what you want is to store a Vector2Int for the position
[Serializable]
public class ShipData
{
public Vector2Int position;
public float depth;
public float windspeed;
public float temperature;
}
Then you probably would want to update the content at certain places like e.g.
private bool TryGetPosition(int[,] grid, out Vector2Int position)
{
position = default;
for (int x = 0; x < grid.GetLength(0); i++)
{
for (int y = 0; y < grid.GetLength(1); j++)
{
if (grid[x, y] == 1)
{
// store into the returned out value
position = new Vector2Int(x, y);
shiposition.text = $"X : {x} Y : {y}";
shiposition.text.ToString();
PlayerPrefs.SetInt("positionX", position.x);
PlayerPrefs.SetInt("positionY", position.y);
PlayerPrefs.Save();
Debug.Log(shiposition.text);
return true;
}
}
}
return false;
}
Note that this is also more efficient since it doesn't iterate through the rest of your grid if it already has found the position
Repeat the same for your other methods and then use them like e.g.
public void button()
{
// Check if a position is found and if yes update the json data
if(TryGetPosition(grid, out var position)
{
JSON_ShipData.position = position;
}
// Repeat the same for your other values
SaveintoJson();
}
General notes:
Before doing stuff like
grid[p1, --p2] = 1;
You should always check if your are maybe getting out of bounds e.g. like
private bool TryGoToPosition(int[,] grid, Vector2Int from, Vector2Int to)
{
if(to.x >= 0 && to.x < grid.GetLength(0) - 1 && to.y >= 0 && to.y < grid.GetLength(1) - 1)
{
grid[from.x, from.y] = 0;
grid[to.x, to.x] = 1;
}
else
{
Debug.LogWarning("Reached grid border! -> Ignored");
}
}
Then I would simply work with a Vector2Int in general instead of setting some value in a grid to 0 or 1 like
Vector2Int gridDimensions = new Vector2Int(10, 16);
public ShipData currentShipData;
public ShipData JSON_ShipData;
private bool CanGoToPosition(Vector2Int to)
{
return to.x >= 0 && to.x < gridDimensions.x - 1 && to.y >= 0 && to.y < gridDimensions.y - 1;
}
void Start()
{
currentShipData.position = new Vector2Int(9, 0);
panelhole.SetActive(false);
panelturtle.SetActive(false);
Debug.Log(JSON_ShipData.position);
Debug.Log(shiposition.transform.position);
}
void Update()
{
......
if (Input.GetKeyDown(KeyCode.A))
{
if (CanGoToPosition(JSON_ShipData.position + Vector2Int.down))
{
currentShipData.position += Vector2Int.down;
}
else
{
Debug.Log("You can't move left!!");
}
}
...
// Then after you handled user input for movement update the other data
currentShipData.windspeed = windspeedData[JSON_ShipData.position.x, JSON_ShipData.position.y];
currentShipData.flow = flowData[JSON_ShipData.position.x, JSON_ShipData.position.y];
...
}
Then for the button press you simply only copy over the current values
public void button()
{
JSON_ShipData.position = currentShipData.position;
...
SaveintoJson();
}
Related
How to correct weird projection flickering? c#
I have created a spinning cube and it's working fine except the weird flickering caused by clearing the picturebox. This is my first 3D project and I have 0 experience in this. I have recreated javidx9's code in c# c# Code: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Threading; using static System.Math; using static _3DTutorial1.Form1.Tools1; namespace _3DTutorial1 { public partial class Form1 : Form { private static PictureBox pictureBox1 = new PictureBox(); private static mesh meshCube; //Projection Matrix private static matrix4x4 matrixProjection; private static float fNear = 0.1f; private static float fFar = 1000; private static float fFov = 90; private static float fAspectRatio = (float)1000 / 1000;//Height / Width; private static float fFovRad = 1 / (float)Tan(fFov * 0.5 / 180 * PI); //Rotation private static float fTheta = 0; private static matrix4x4 matrixRotationZ; private static matrix4x4 matrixRotationX; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { Width = 1000; Height = 1000; pictureBox1.Dock = DockStyle.Fill; pictureBox1.BackColor = Color.Black; Controls.Add(pictureBox1); timer1.Interval = 20; meshCube = Create_mesh( //SOUTH Create_triangle(Create_vector3d(0, 0, 0), Create_vector3d(0, 1, 0), Create_vector3d(1, 1, 0)), Create_triangle(Create_vector3d(0, 0, 0), Create_vector3d(1, 1, 0), Create_vector3d(1, 0, 0)), //EAST Create_triangle(Create_vector3d(1, 0, 0), Create_vector3d(1, 1, 0), Create_vector3d(1, 1, 1)), Create_triangle(Create_vector3d(1, 0, 0), Create_vector3d(1, 1, 1), Create_vector3d(1, 0, 1)), //NORTH Create_triangle(Create_vector3d(1, 0, 1), Create_vector3d(1, 1, 1), Create_vector3d(0, 1, 1)), Create_triangle(Create_vector3d(1, 0, 1), Create_vector3d(0, 1, 1), Create_vector3d(0, 0, 1)), //WEST Create_triangle(Create_vector3d(0, 0, 1), Create_vector3d(0, 1, 1), Create_vector3d(0, 1, 0)), Create_triangle(Create_vector3d(0, 0, 1), Create_vector3d(0, 1, 0), Create_vector3d(0, 0, 0)), //TOP Create_triangle(Create_vector3d(0, 1, 0), Create_vector3d(0, 1, 1), Create_vector3d(1, 1, 1)), Create_triangle(Create_vector3d(0, 1, 0), Create_vector3d(1, 1, 1), Create_vector3d(1, 1, 0)), //BOTTOM Create_triangle(Create_vector3d(1, 0, 1), Create_vector3d(0, 0, 1), Create_vector3d(0, 0, 0)), Create_triangle(Create_vector3d(1, 0, 1), Create_vector3d(0, 0, 0), Create_vector3d(1, 0, 0)) ); //Projection Matrix matrixProjection = Create_matrix4x4( (0, 0, fAspectRatio * fFovRad), (1, 1, fFovRad), (2, 2, fFar / (fFar - fNear)), (3, 2, (-fFar * fNear) / (fFar - fNear)), (2, 3, 1), (3, 3, 0) ); } private void Form1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) { if (e.KeyCode == Keys.X) { timer1.Start(); } } private void timer1_Tick(object sender, EventArgs e) { Graphics g = pictureBox1.CreateGraphics(); //Rotation fTheta += 0.01f; matrixRotationZ = Create_matrix4x4( (0, 0, (float)Cos(fTheta)), (0, 1, (float)Sin(fTheta)), (1, 0, (float)-Sin(fTheta)), (1, 1, (float)Cos(fTheta)), (2, 2, 1), (3, 3, 1) ); matrixRotationX = Create_matrix4x4( (0, 0, 1), (1, 1, (float)Cos(fTheta)), (1, 2, (float)Sin(fTheta)), (2, 1, (float)-Sin(fTheta)), (2, 2, (float)Cos(fTheta)), (3, 3, 1) ); //Clear / Draw List<triangle> Ready2DrawCube = new List<triangle>(); //Calculate Draw foreach (var item in meshCube.tris) { triangle triangleProjected, triangleTranslated, triangleRotatedZ, triangleRotatedZX; triangleRotatedZ = Create_triangle(Create_vector3d(), Create_vector3d(), Create_vector3d()); triangleRotatedZX = Create_triangle(Create_vector3d(), Create_vector3d(), Create_vector3d()); triangleProjected = Create_triangle(Create_vector3d(), Create_vector3d(), Create_vector3d()); triangleRotatedZ.p[0] = MultiplyMatrixVector(item.p[0], matrixRotationZ); triangleRotatedZ.p[1] = MultiplyMatrixVector(item.p[1], matrixRotationZ); triangleRotatedZ.p[2] = MultiplyMatrixVector(item.p[2], matrixRotationZ); triangleRotatedZX.p[0] = MultiplyMatrixVector(triangleRotatedZ.p[0], matrixRotationX); triangleRotatedZX.p[1] = MultiplyMatrixVector(triangleRotatedZ.p[1], matrixRotationX); triangleRotatedZX.p[2] = MultiplyMatrixVector(triangleRotatedZ.p[2], matrixRotationX); triangleTranslated = triangleRotatedZX; triangleTranslated.p[0].z = triangleRotatedZX.p[0].z + 3.0f; triangleTranslated.p[1].z = triangleRotatedZX.p[1].z + 3.0f; triangleTranslated.p[2].z = triangleRotatedZX.p[2].z + 3.0f; triangleProjected.p[0] = MultiplyMatrixVector(triangleTranslated.p[0], matrixProjection); triangleProjected.p[1] = MultiplyMatrixVector(triangleTranslated.p[1], matrixProjection); triangleProjected.p[2] = MultiplyMatrixVector(triangleTranslated.p[2], matrixProjection); //Scale into view triangleProjected.p[0].x += 1; triangleProjected.p[0].y += 1; triangleProjected.p[1].x += 1; triangleProjected.p[1].y += 1; triangleProjected.p[2].x += 1; triangleProjected.p[2].y += 1; triangleProjected.p[0].x *= 0.5f * Width; triangleProjected.p[0].y *= 0.5f * Width; triangleProjected.p[1].x *= 0.5f * Width; triangleProjected.p[1].y *= 0.5f * Width; triangleProjected.p[2].x *= 0.5f * Width; triangleProjected.p[2].y *= 0.5f * Width; //Done Ready2DrawCube.Add(triangleProjected); } //Draw Triangles g.Clear(Color.Black); foreach (var item in Ready2DrawCube) { DrawTriangle( (int)item.p[0].x, (int)item.p[0].y, (int)item.p[1].x, (int)item.p[1].y, (int)item.p[2].x, (int)item.p[2].y, Pens.White ); } } public class Tools1 { private static Graphics g = pictureBox1.CreateGraphics(); public static void DrawTriangle(int x1, int y1, int x2, int y2, int x3, int y3, Pen p) { g.DrawLine(p, new Point(x1, y1), new Point(x2, y2)); g.DrawLine(p, new Point(x2, y2), new Point(x3, y3)); g.DrawLine(p, new Point(x3, y3), new Point(x1, y1)); } public static vector3d MultiplyMatrixVector(vector3d _i, matrix4x4 _m) { vector3d o_ = Create_vector3d(); o_.x = _i.x * _m.m[0, 0] + _i.y * _m.m[1, 0] + _i.z * _m.m[2, 0] + _m.m[3, 0]; o_.y = _i.x * _m.m[0, 1] + _i.y * _m.m[1, 1] + _i.z * _m.m[2, 1] + _m.m[3, 1]; o_.z = _i.x * _m.m[0, 2] + _i.y * _m.m[1, 2] + _i.z * _m.m[2, 2] + _m.m[3, 2]; float w = _i.x * _m.m[0, 3] + _i.y * _m.m[1, 3] + _i.z * _m.m[2, 3] + _m.m[3, 3]; if (w != 0) { o_.x /= w; o_.y /= w; o_.z /= w; } return o_; } public static vector3d Create_vector3d(float _x = 0, float _y = 0, float _z = 0) { vector3d v_ = new vector3d(); v_.x = _x; v_.y = _y; v_.z = _z; return v_; } public static triangle Create_triangle(params vector3d[] _p) { triangle t_ = new triangle(); t_.p = _p; return t_; } public static mesh Create_mesh(params triangle[] _t) { mesh m_ = new mesh(); m_.tris = _t.ToList(); return m_; } public static matrix4x4 Create_matrix4x4(params (int x, int y, float value)[] inputs) { matrix4x4 m_ = new matrix4x4(); m_.m = new float[4, 4]; foreach (var item in inputs) { m_.m[item.x, item.y] = item.value; } return m_; } public struct vector3d { public float x, y, z; } public struct triangle { public vector3d[] p; } public struct mesh { public List<triangle> tris; } public struct matrix4x4 { public float[,] m; }; } } } I tried storing the cube with the calculated parameters, so I could draw it at once. This was my only idea..
error CS1031: Type expected and error CS1001: Identifier expected
I'm new here and can't understand many things.I'm writing my fist c# code for a Unity game. I saw a tutorial on YouTube of this code and tried as hard as I could to write it correctly.I checked it many times but can't understand how to solve this problem. What's wrong? /tmp/aTDELDegvF.cs(73,40): error CS1031: Type expected /tmp/aTDELDegvF.cs(73,40): error CS1001: Identifier expected using UnityEngine; using System; using System.Collections; using System.Collections.Generic; public class GameController : MonoBehaviour { private CubePos nowCube = new CubePos(0, 1, 0); public float cubeChangePlacespeed = 0.5f; public Transform cubeToPlace; private List<Vector3> allCubesPositions = new List<Vector3>{ new Vector3(0, 0, 0), new Vector3(1, 0, 0), new Vector3(-1, 0, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1), new Vector3(0, 0, -1), new Vector3(1, 0, 1), new Vector3(-1, 0, -1), new Vector3(-1, 0, 1), new Vector3(1, 0, -1), }; private void Start(){ StartCoroutine(ShowCubePlace()); } IEnumerator ShowCubePlace(){ while(true){ SpawnPositions(); yield return new WaitForSeconds(cubeChangePlacespeed); } } private void SpawnPositions(){ List<Vector3> positions = new List<Vector3>(); if(IsPositionEmpty(new Vector3(nowCube.x + 1, nowCube.y, nowCube.z))) positions.Add(new Vector3(nowCube.x + 1, nowCube.y, nowCube.z)); if(IsPositionEmpty(new Vector3(nowCube.x - 1, nowCube.y, nowCube.z))) positions.Add(new Vector3(nowCube.x - 1, nowCube.y, nowCube.z)); if(IsPositionEmpty(new Vector3(nowCube.x, nowCube.y + 1, nowCube.z))) positions.Add(new Vector3(nowCube.x, nowCube.y + 1, nowCube.z)); if(IsPositionEmpty(new Vector3(nowCube.x, nowCube.y - 1, nowCube.z))) positions.Add(new Vector3(nowCube.x, nowCube.y - 1, nowCube.z)); if(IsPositionEmpty(new Vector3(nowCube.x, nowCube.y, nowCube.z - 1))) positions.Add(new Vector3(nowCube.x, nowCube.y, nowCube.z - 1)); cubeToPlace.position =positions [UnityEngine.Random.Range(0, positions.Count)]; } private bool IsPositionEmpty(Vector3 targetPos){ if(targetPos.y = 0) return false; foreach(Vector3 pos in allCubesPositions){ if(pos.x == targetPos.x && pos.y == targetPos.y && pos.z == targetPos.z) return false; } return true; } } struct CubePos{ public int x, y, z; public CubePos(int x, int y, int z,){ this.x = x; this.y = y; this.z = z; } public Vector3 getVector(){ return new Vector3(x, y, z); } public void setVector(Vector3 pos){ x = Convert.ToInt32(pos.x); y = Convert.ToInt32(pos.y); z = Convert.ToInt32(pos.z); } }
Rotation Matrix to Euler Angles in Degrees
I have this function to convert Euler Angles to a rotation matrix but I would like to reverse it and get the Euler Angles when I only have the rotation matrix. The reason for it is I want to be able to set an objects transform using a transform matrix then I would like to update that objects Euler rotation variable that is in degrees. (I have a function that calculate the rotation matrix from the transform matrix) public static Mat4 RotMat(Vec3 _rot) { double rx = Math2.degToRad(_rot.x); double[,] trmx = new double[4, 4] { { 1, 0, 0, 0 }, { 0, Math.Cos(rx), Math.Sin(rx), 0 }, { 0, -Math.Sin(rx), Math.Cos(rx), 0 }, { 0, 0, 0, 1 } }; Mat4 rmx = new Mat4(trmx); double ry = Math2.degToRad(_rot.y); double[,] trmy = new double[4, 4] { { Math.Cos(ry), 0, -Math.Sin(ry), 0 }, { 0, 1, 0, 0 }, { Math.Sin(ry), 0, Math.Cos(ry), 0 }, { 0, 0, 0, 1 } }; Mat4 rmy = new Mat4(trmy); double rz = Math2.degToRad(_rot.z); double[,] trmz = new double[4, 4] { { Math.Cos(rz), Math.Sin(rz), 0, 0 }, { -Math.Sin(rz), Math.Cos(rz), 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } }; Mat4 rmz = new Mat4(trmz); return (rmx * rmy * rmz); } This is an attempt based on some code I found but does not always give me the expected result, it works sometimes (I know there is the gimbal lock issue with euler angles so maybe this is a futile attempt ). public static Vec3 GetRot(Mat4 _tm) { Mat4 rm = GetRotMat(_tm); double sy = Math.Sqrt(rm[0, 0] * rm[0, 0] + rm[1, 0] * rm[1, 0]); bool singular = sy < 1e-6; // If double x, y, z; if (!singular) { x = Math.Atan2(rm[2, 1], rm[2, 2]); y = Math.Atan2(-rm[2, 0], sy); z = Math.Atan2(rm[1, 0], rm[0, 0]); } else { x = Math.Atan2(-rm[1, 2], rm[1, 1]); y = Math.Atan2(-rm[2, 0], sy); z = 0; } x = Math2.radToDeg(x); y = Math2.radToDeg(y); z = Math2.radToDeg(z); return new Vec3(x, y, z) * -1; }
Unity Planet Generator Colors not working
I am following this tutorial: https://www.youtube.com/watch?v=LyV7cEQyZMk to generate a planet for my game. I have gotten up to 6:08 For some reason, the color of the planet won't change depending on the type like it should, it is only white. using System.Collections; using System.Collections.Generic; using UnityEngine; public enum Type { Water, Ice, Volcano, Snow, Grass, Forest, Desert, Rocky } [CreateAssetMenu()] public class PlanetSettings : ScriptableObject { public float Size; public Type type; } public class TerrainFace { Mesh mesh; int resolution; Vector3 localUp; Vector3 axisA; Vector3 axisB; Vector3[] vertices; int[] triangles; PlanetSettings settings; Vector3 CalculatePointOnPlanet(Vector3 p) { return p * settings.Size; } public TerrainFace(Mesh mesh, int resolution, Vector3 localUp, PlanetSettings settings) { this.mesh = mesh; this.resolution = resolution; this.localUp = localUp; this.settings = settings; axisA = new Vector3(localUp.y, localUp.z, localUp.x); axisB = Vector3.Cross(localUp, axisA); } public void ConstructMesh() { vertices = new Vector3[resolution * resolution]; triangles = new int[(resolution - 1) * (resolution - 1) * 6]; int triIndex = 0; for (int y = 0; y < resolution; y++) { for (int x = 0; x < resolution; x++) { int index = x + y * resolution; Vector2 percent = new Vector2(x, y) / (resolution - 1); Vector3 pointOnUnitCube = localUp + (percent.x - 0.5f) * 2 * axisA + (percent.y - 0.5f) * 2 * axisB; Vector3 pointOnUnitSphere = pointOnUnitCube.normalized; vertices[index] = CalculatePointOnPlanet(pointOnUnitSphere); if (x != resolution - 1 && y != resolution - 1) { triangles[triIndex] = index; triangles[triIndex + 1] = index + resolution + 1; triangles[triIndex + 2] = index + resolution; triangles[triIndex + 3] = index; triangles[triIndex + 4] = index + 1; triangles[triIndex + 5] = index + resolution + 1; triIndex += 6; } } } mesh.Clear(); mesh.vertices = vertices; mesh.triangles = triangles; mesh.RecalculateNormals(); } } public class PlanetGenerator : MonoBehaviour { [Range(2, 256)] public int Resolution = 10; public PlanetSettings Settings; [SerializeField, HideInInspector] MeshFilter[] meshFilters; TerrainFace[] terrainFaces; Color c; private void OnValidate() { GeneratePlanet(); } void Initialize() { switch (Settings.type) { case Type.Desert: c = new Color(244, 176, 66, 255); break; case Type.Forest: c = new Color(9, 119, 22, 255); break; case Type.Grass: c = new Color(21, 193, 41, 255); break; case Type.Ice: c = new Color(105, 206, 239, 255); break; case Type.Rocky: c = new Color(104, 65, 6, 255); break; case Type.Snow: c = new Color(204, 226, 229, 255); break; case Type.Volcano: c = new Color(160, 16, 16, 255); break; case Type.Water: c = new Color(26, 69, 178, 255); break; default: c = new Color(); break; } if (meshFilters == null || meshFilters.Length == 0) meshFilters = new MeshFilter[6]; terrainFaces = new TerrainFace[6]; Vector3[] directions = { Vector3.up, Vector3.down, Vector3.left, Vector3.right, Vector3.forward, Vector3.back }; for (int i = 0; i < 6; i++) { if (meshFilters[i] == null) { GameObject meshObj = new GameObject("mesh"); meshObj.transform.parent = transform; meshObj.AddComponent<MeshRenderer>().sharedMaterial = new Material(Shader.Find("Standard")); meshFilters[i] = meshObj.AddComponent<MeshFilter>(); meshFilters[i].sharedMesh = new Mesh(); } terrainFaces[i] = new TerrainFace(meshFilters[i].sharedMesh, Resolution, directions[i], Settings); } } public void GeneratePlanet() { Initialize(); GenerateMesh(); GenerateColor(); } void GenerateMesh() { foreach (TerrainFace face in terrainFaces) { face.ConstructMesh(); } } void GenerateColor() { foreach (MeshFilter m in meshFilters) { m.GetComponent<MeshRenderer>().sharedMaterial.color = c; } } } The size part works, it's just the color that doesn't. I should see a dark red colored sphere. I have been trying different things to identify the problem, I think i have narrowed it down to sharedmaterial.color but I don't know for sure.
Well you don't have the code he talks about at around the 5 min mark where he changed the TerrainFace object and it's constructor.
Marching Cubes generating holes in mesh
I'm working on a Marching Cubes implementation in Unity. My code is based on Paul Bourke's code actually with a lot of modifications, but anyway i'm checking if a block at a position is null if it is than a debug texture will be placed on it. This is my MC script public class MarchingCubes { private World world; private Chunk chunk; private List<Vector3> vertices = new List<Vector3> (); private List<Vector3> normals = new List<Vector3> (); private Vector3[] ns; private List<int> triangles = new List<int> (); private List<Vector2> uvs = new List<Vector2> (); private Vector3[] positions = new Vector3[8]; private float[] corners = new float[8]; private Vector3i size = new Vector3i (16, 128, 16); Vector3[] vertlist = new Vector3[12]; private float isolevel = 1f; private float Corner (Vector3i pos) { int x = pos.x; int y = pos.y; int z = pos.z; if (x < size.x && z < size.z) { return chunk.GetValue (x, y, z); } else { int ix = chunk.X, iz = chunk.Z; int rx = chunk.region.x, rz = chunk.region.z; if (x >= size.x) { ix++; x = 0; } if (z >= size.z) { iz++; z = 0; } return chunk.region.GetChunk (ix, iz).GetValue (x, y, z); } } Block block; public Mesh MarchChunk (World world, Chunk chunk, Mesh mesh) { this.world = world; this.chunk = chunk; vertices.Clear (); triangles.Clear (); uvs.Clear (); for (int x = 0; x < size.x; x++) { for (int y = 1; y < size.y - 2; y++) { for (int z = 0; z < size.z; z++) { block = chunk.GetBlock (x, y, z); int cubeIndex = 0; for (int i = 0; i < corners.Length; i++) { corners [i] = Corner (new Vector3i (x, y, z) + offset [i]); positions [i] = (new Vector3i (x, y, z) + offset [i]).ToVector3 (); if (corners [i] < isolevel) cubeIndex |= (1 << i); } if (eTable [cubeIndex] == 0) continue; for (int i = 0; i < vertlist.Length; i++) { if ((eTable [cubeIndex] & 1 << i) == 1 << i) vertlist [i] = LinearInt (positions [eCons [i, 0]], positions [eCons [i, 1]], corners [eCons [i, 0]], corners [eCons [i, 1]]); } for (int i = 0; triTable [cubeIndex, i] != -1; i += 3) { int index = vertices.Count; vertices.Add (vertlist [triTable [cubeIndex, i]]); vertices.Add (vertlist [triTable [cubeIndex, i + 1]]); vertices.Add (vertlist [triTable [cubeIndex, i + 2]]); float tec = (0.125f); Vector2 uvBase = block != null ? block.UV : new Vector2 (); uvs.Add (uvBase); uvs.Add (uvBase + new Vector2 (0, tec)); uvs.Add (uvBase + new Vector2 (tec, tec)); triangles.Add (index + 0); triangles.Add (index + 1); triangles.Add (index + 2); } } } } if (mesh == null) mesh = new Mesh (); mesh.Clear (); mesh.vertices = vertices.ToArray (); mesh.triangles = triangles.ToArray (); mesh.uv = uvs.ToArray (); mesh.RecalculateNormals (); return mesh; } bool IsBitSet (int b, int pos) { return ((b & pos) == pos); } Vector3 LinearInt (Vector3 p1, Vector3 p2, float v1, float v2) { Vector3 p; p.x = p1.x + (isolevel - v1) * (p2.x - p1.x) / (v2 - v1); p.y = p1.y + (isolevel - v1) * (p2.y - p1.y) / (v2 - v1); p.z = p1.z + (isolevel - v1) * (p2.z - p1.z) / (v2 - v1); return p; } private static int[,] eCons = new int[12, 2] { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 4 }, { 0, 4 }, { 1, 5 }, { 2, 6 }, { 3, 7 } }; private static Vector3i[] offset = new Vector3i[8] { new Vector3i (0, 0, 1), new Vector3i (1, 0, 1), new Vector3i (1, 0, 0), new Vector3i (0, 0, 0), new Vector3i (0, 1, 1), new Vector3i (1, 1, 1), new Vector3i (1, 1, 0), new Vector3i (0, 1, 0) }; } I didn't put the tables in the sample, because they are the same as the ones in Bourke's code. EDIT: What I figured out yet is that the cell's value at the blue triangles are 0 so they don't have to be triangulated, but the cell's value under them is 1 and because of this a top triangle is created to complete the mesh.