This commit is contained in:
brausjonas
2022-05-12 11:02:58 +02:00
parent c147e5baea
commit 1429a95243
109 changed files with 9123 additions and 0 deletions
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1c5d2a5e24ad1b248a221c6b97f0911b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,137 @@
using System.Collections;
using System.Collections.Generic;
using System.Data.Common;
using UnityEngine;
public class Chunk
{
//basic
private Material material;
private ChunkCoord chunkPosition;
private World world;
//rendering
public GameObject gameObject;
private MeshFilter meshFilter;
private MeshRenderer meshRenderer;
//data
private List<Vector3> vertices = new List<Vector3>();
private List<Vector2> uv = new List<Vector2>();
private List<int> triangles = new List<int>();
public byte[,,] blocks;
private int triangleIndex = 0;
//physics
private MeshCollider collider;
public Chunk(Material material, ChunkCoord chunkPosition, World world, byte[,,] blocks)
{
this.blocks = blocks;
this.material = material;
this.chunkPosition = chunkPosition;
this.world = world;
}
//initializes the chunks components
public void Initialize()
{
gameObject = new GameObject(chunkPosition.x + ", " + chunkPosition.z);
gameObject.transform.position =
new Vector3(chunkPosition.x * Data.chunkWidth, 0, chunkPosition.z * Data.chunkWidth);
meshFilter = gameObject.AddComponent<MeshFilter>();
meshRenderer = gameObject.AddComponent<MeshRenderer>();
collider = gameObject.AddComponent<MeshCollider>();
}
public void AddBlocks()
{
for (int y = 0; y < Data.chunkHeight; y++)
{
for (int x = 0; x < Data.chunkWidth; x++)
{
for (int z = 0; z < Data.chunkWidth; z++)
{
AddBlock(x, y, z);
}
}
}
}
//adds the data of a single block
private void AddBlock(int x, int y, int z)
{
byte[] textures = world.GetTextures(blocks[x, y, z]);
//only draw solid blocks
if(blocks[x, y, z] != 0)
{
for (int f = 0; f < 6; f++)
{
//check for connecting faces
if (!world.CheckBlock(new Vector3(x + Data.faceChecks[f].x + chunkPosition.x * Data.chunkWidth,
y + Data.faceChecks[f].y,
z + Data.faceChecks[f].z + chunkPosition.z * Data.chunkWidth)))
{
for (int v = 0; v < 6; v++)
{
vertices.Add(Data.vertices[Data.triangles[f, v]] + new Vector3(x, y, z));
triangles.Add(triangleIndex);
triangleIndex++;
}
AddUV(textures[f]);
}
}
}
}
//add uv to a face
private void AddUV(byte textureID)
{
float y = (int)(textureID / Data.textureAtlasSize);
float x = (int)(textureID - (y * Data.textureAtlasSize));
float textureSize = 1f / Data.textureAtlasSize;
y /= Data.textureAtlasSize;
x /= Data.textureAtlasSize;
y = 1 - y;
uv.Add(new Vector2(x, y - textureSize));
uv.Add(new Vector2(x, y));
uv.Add(new Vector2(x + textureSize, y - textureSize));
uv.Add(new Vector2(x + textureSize, y - textureSize));
uv.Add(new Vector2(x, y));
uv.Add(new Vector2(x + textureSize, y));
}
//creates the final mesh
public void CreateMesh()
{
Mesh mesh = new Mesh();
mesh.vertices = vertices.ToArray();
mesh.triangles = triangles.ToArray();
mesh.uv = uv.ToArray();
mesh.RecalculateNormals();
meshFilter.mesh = mesh;
meshRenderer.material = material;
collider.sharedMesh = mesh;
}
public void Edit(byte x, byte y, byte z, byte blockID)
{
blocks[x, y, z] = blockID;
}
public void Update()
{
vertices.Clear();
triangles.Clear();
uv.Clear();
triangleIndex = 0;
AddBlocks();
CreateMesh();
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a5d27935c6d501a41a2d972b8ff6cc7c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,17 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[Serializable]
public class ChunkCoord
{
public ChunkCoord(int x, int z)
{
this.x = x;
this.z = z;
}
public int x;
public int z;
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9b0ff680cf7becd4a905cd0f219efa91
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,159 @@
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
public class Client
{
//game
private World world;
private string name;
//network
private UdpClient client;
private int port;
private Thread receiveThread;
public Client(string hostname, int port, World world, string name)
{
this.port = port;
this.world = world;
this.name = name;
//setup client
client = new UdpClient();
client.DontFragment = false;
IPAddress address;
if (IPAddress.TryParse(hostname, out address))
{
address = IPAddress.Parse(hostname);
client.Connect(address, port);
}
else
{
client.Connect(hostname, port);
}
//get world size
List<byte> sendList = new List<byte>();
sendList.Add(2);
byte[] asciiName = Encoding.ASCII.GetBytes(name);
foreach (byte b in asciiName)
{
sendList.Add(b);
}
Send(sendList.ToArray());
IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 0);
byte[] data = client.Receive(ref endPoint);
if (data[0] == 2)
{
world.worldSize = data[1];
world.CreateChunkArray();
}
//send init message
Send(new byte[]{0});
byte xChunk = 0;
byte zChunk = 0;
while (true)
{
endPoint = new IPEndPoint(IPAddress.Any, 0);
data = client.Receive(ref endPoint);
if (data[0] == 1)
{
if (data[1] == 1)
{
break;
}
//in world transfer
byte[,,] blocks = new byte[Data.chunkWidth, Data.chunkHeight, Data.chunkWidth];
int i = 2;
for (int y = 0; y < Data.chunkHeight; y++)
{
for (int x = 0; x < Data.chunkWidth; x++)
{
for (int z = 0; z < Data.chunkWidth; z++)
{
blocks[x, y, z] = data[i];
i++;
}
}
}
world.InitChunk(xChunk, zChunk, blocks);
zChunk++;
xChunk += (byte)(zChunk / world.worldSize);
if (zChunk / world.worldSize == 1)
{
zChunk = 0;
}
}
Send(new byte[]{5});
}
world.CreateChunks();
//world transfer finished
//start listening
receiveThread = new Thread(Receive);
receiveThread.Start();
}
private void Receive()
{
while(true)
{
IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 0);
byte[] data = client.Receive(ref endPoint);
if (data[0] == 3)
{
ChunkCoord chunk = new ChunkCoord(data[1], data[2]);
Vector3 positionInChunk = new Vector3(data[3], data[4], data[5]);
byte blockID = data[6];
world.EditBlock(chunk, positionInChunk, blockID);
}
}
}
public void EditBlock(Vector3 positionInWorld, byte blockID)
{
ChunkCoord chunk = new ChunkCoord((int)(positionInWorld.x / Data.chunkWidth),
(int)(positionInWorld.z / Data.chunkWidth));
byte xInChunk = (byte)(positionInWorld.x - chunk.x * Data.chunkWidth);
byte yInChunk = (byte)positionInWorld.y;
byte zInChunk = (byte)(positionInWorld.z - chunk.z * Data.chunkWidth);
//send Chunk with position in Chunk
Send(new byte[] { 3, (byte)chunk.x, (byte)chunk.z, xInChunk, yInChunk, zInChunk, blockID });
}
private void Send(byte[] data)
{
client.Send(data, data.Length);
}
public void Disconnect()
{
Send(new byte[] { 4 });
receiveThread.Abort();
client.Close();
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7ca7d1e5089330a4392f77344cf27891
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,53 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Data
{
public static int chunkWidth = 15, chunkHeight = 250;
public static int textureAtlasSize = 16;
public static readonly Vector3[] vertices =
{
new Vector3(0, 0, 0),
new Vector3(1, 0, 0),
new Vector3(1, 1, 0),
new Vector3(0, 1, 0),
new Vector3(1, 0, 1),
new Vector3(0, 0, 1),
new Vector3(0, 1, 1),
new Vector3(1, 1, 1)
};
public static readonly int[,] triangles =
{
//front
{0, 3, 1, 1, 3, 2},
//back
{4, 7, 5, 5, 7, 6},
//top
{3, 6, 2, 2, 6, 7},
//bottom
{5, 0, 4, 4, 0, 1},
//left
{5, 6, 0, 0, 6, 3},
//right
{1, 2, 4, 4, 2, 7},
};
public static readonly Vector3[] faceChecks =
{
//front
new Vector3(0, 0, -1),
//back
new Vector3(0, 0, 1),
//top
new Vector3(0, 1, 0),
//bottom
new Vector3(0, -1, 0),
//left
new Vector3(-1, 0, 0),
//right
new Vector3(1, 0, 0),
};
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 643914e5a873de34baea75d649800005
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,63 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
//game
[SerializeField] private float mouseSpeed;
[SerializeField] private float moveSpeed;
[SerializeField] private World world;
private Camera camera = null;
//network
private Client client = null;
private void Start()
{
client = world.GetClient();
Cursor.lockState = CursorLockMode.Locked;
camera = GetComponentInChildren<Camera>();
}
private void Update()
{
transform.Rotate(0, Input.GetAxis("Mouse X") * mouseSpeed, 0);
camera.transform.Rotate(-Input.GetAxis("Mouse Y") * mouseSpeed, 0, 0);
float up = 0;
if (Input.GetKey(KeyCode.Space))
{
up = 1;
}
if (Input.GetKey(KeyCode.LeftShift))
{
up = -1;
}
transform.Translate(Input.GetAxis("Horizontal") * moveSpeed * Time.deltaTime, up * moveSpeed * Time.deltaTime,
Input.GetAxis("Vertical") * moveSpeed * Time.deltaTime);
if (Input.GetMouseButtonDown(0))
{
RaycastHit hit;
if (Physics.Raycast(camera.transform.position, camera.transform.forward, out hit))
{
hit.point += camera.transform.forward / 10;
client.EditBlock(hit.point, 0);
}
}
if (Input.GetMouseButtonDown(1))
{
RaycastHit hit;
if (Physics.Raycast(camera.transform.position, camera.transform.forward, out hit))
{
hit.point -= camera.transform.forward / 10;
client.EditBlock(hit.point, 4);
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 68efa1f8faa15f54b905841d23d36864
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,209 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class World : MonoBehaviour
{
//basic
[SerializeField] private Material material;
public int worldSize;
private string name;
private string ip;
private int port;
//chunks
private Chunk[,] chunks;
private Queue<ChunkCoord> chunksToUpdate = new Queue<ChunkCoord>();
//blocks
[SerializeField] private BlockData[] blockData;
//network
private Client client;
private void Start()
{
name = PlayerPrefs.GetString("userName");
ip = PlayerPrefs.GetString("serverIP");
port = int.Parse(PlayerPrefs.GetString("port"));
client = new Client(ip, port, this, name);
}
private void Update()
{
if (chunksToUpdate.Count > 0)
{
ChunkCoord chunk = chunksToUpdate.Dequeue();
chunks[chunk.x, chunk.z].Update();
}
}
public void CreateChunkArray()
{
chunks = new Chunk[worldSize, worldSize];
}
public void InitChunk(int x, int z, byte[,,] blocks)
{
chunks[x, z] = new Chunk(material, new ChunkCoord(x, z), this, blocks);
}
//creates an array of chunks
public void CreateChunks()
{
for (int x = 0; x < worldSize; x++)
{
for (int z = 0; z < worldSize; z++)
{
chunks[x, z].Initialize();
chunks[x, z].gameObject.transform.SetParent(gameObject.transform);
chunks[x, z].AddBlocks();
chunks[x, z].CreateMesh();
}
}
}
//return the ID of a block
public byte GetBlockID(Vector3 positionInWorld)
{
byte height = GetHeight((int)positionInWorld.x, (int)positionInWorld.z);
//world pass
if (positionInWorld.x < 0 || positionInWorld.y < 0 || positionInWorld.z < 0 ||
positionInWorld.x >= worldSize * Data.chunkWidth || positionInWorld.y > height ||
positionInWorld.z >= worldSize * Data.chunkWidth)
{
return 0;
}
//chunk pass
if ((int)positionInWorld.y == height)
{
return 3;
}
if ((int)positionInWorld.y == 0)
{
return 1;
}
if ((int)positionInWorld.y > height - 3)
{
return 2;
}
if ((int)positionInWorld.y < height)
{
return 4;
}
return 0;
}
//returns if a block is on the position
public bool CheckBlock(Vector3 positionInWorld)
{
if (positionInWorld.x < -1 || positionInWorld.z < -1 ||
positionInWorld.x > worldSize * Data.chunkWidth ||
positionInWorld.z > worldSize * Data.chunkWidth)
{
return false;
}
if (positionInWorld.x < 0 || positionInWorld.y < 0 || positionInWorld.z < 0 ||
positionInWorld.x >= worldSize * Data.chunkWidth || positionInWorld.y >= Data.chunkHeight ||
positionInWorld.z >= worldSize * Data.chunkWidth)
{
return true;
}
ChunkCoord chunk = new ChunkCoord((int)(positionInWorld.x / Data.chunkWidth),
(int)(positionInWorld.z / Data.chunkWidth));
int xInChunk = (int)(positionInWorld.x - chunk.x * Data.chunkWidth);
int yInChunk = (int)positionInWorld.y;
int zInChunk = (int)(positionInWorld.z - chunk.z * Data.chunkWidth);
if (chunks[chunk.x, chunk.z] != null)
{
if (chunks[chunk.x, chunk.z].blocks[xInChunk, yInChunk, zInChunk] == 0)
{
return false;
}
}
return true;
}
//return textures array of a block
public byte[] GetTextures(byte blockID)
{
return blockData[blockID].textures;
}
private byte GetHeight(int x, int z)
{
float scale = 0.025f;
byte perlinHeight = 10;
byte groundHeight = 10;
byte height = (byte)(Mathf.PerlinNoise((x) * scale + 0.1f, (z) * scale + 0.1f) * perlinHeight + groundHeight);
return height;
}
public void EditBlock(ChunkCoord chunk, Vector3 positionInChunk, byte blockID)
{
byte xInChunk = (byte)(positionInChunk.x);
byte yInChunk = (byte)positionInChunk.y;
byte zInChunk = (byte)(positionInChunk.z);
//edit block in chunk
if(chunks[chunk.x, chunk.z].blocks[xInChunk, yInChunk, zInChunk] != 1)
{
chunks[chunk.x, chunk.z].Edit(xInChunk, yInChunk, zInChunk, blockID);
chunksToUpdate.Enqueue(new ChunkCoord(chunk.x, chunk.z));
//update surrounding chunks
if (chunk.x - 1 >= 0)
{
chunksToUpdate.Enqueue(new ChunkCoord(chunk.x - 1, chunk.z));
}
if (chunk.x + 1 < worldSize)
{
chunksToUpdate.Enqueue(new ChunkCoord(chunk.x + 1, chunk.z));
}
if (chunk.z - 1 >= 0)
{
chunksToUpdate.Enqueue(new ChunkCoord(chunk.x, chunk.z - 1));
}
if (chunk.z + 1 < worldSize)
{
chunksToUpdate.Enqueue(new ChunkCoord(chunk.x, chunk.z + 1));
}
}
}
private void OnApplicationQuit()
{
client.Disconnect();
}
public Client GetClient()
{
return client;
}
[Serializable]
public class BlockData
{
public string name;
public byte[] textures = new byte[6];
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5457f26f725053d46bffb9885acfd7d8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8ce3777e92c3fce48ae215f4f1576933
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,40 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class Login : MonoBehaviour
{
[SerializeField] private InputField userName;
[SerializeField] private InputField serverIP;
[SerializeField] private InputField port;
private void Start()
{
if (PlayerPrefs.HasKey("userName"))
{
userName.text = PlayerPrefs.GetString("userName");
}
if (PlayerPrefs.HasKey("serverIP"))
{
serverIP.text = PlayerPrefs.GetString("serverIP");
}
if (PlayerPrefs.HasKey("port"))
{
port.text = PlayerPrefs.GetString("port");
}
}
public void ButtonSend()
{
PlayerPrefs.SetString("userName", userName.text);
PlayerPrefs.SetString("serverIP", serverIP.text);
PlayerPrefs.SetString("port", port.text);
PlayerPrefs.Save();
SceneManager.LoadScene("Scenes/Game", LoadSceneMode.Single);
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: db3663bcb190ea64f93d6089e1021f58
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: