using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; using UnityEngine.UI; // Optimise theory - Since the world generates as 1 pixel = a block, optimise by only loading in blocks that are currently visible to the player camera // Or, use multiple pixels to load blocks instead of 1 pixel per block public class ReadImage : MonoBehaviour { [SerializeField] private Texture2D[] _images; private Texture2D _image; [SerializeField] private GameObject _wall; [SerializeField] private GameObject _ground; private string _imagesDir = "/LevelImages"; [SerializeField] private Text _levelText; [SerializeField] private float _scale; private List groundObjectsToCombine = new List(); private List wallObjectsToCombine = new List(); public GameObject[] groundObjects; public GameObject[] wallObjects; private void Start() { string dataPath = Application.persistentDataPath; _imagesDir = dataPath + _imagesDir; if(Directory.Exists(_imagesDir)) { Debug.Log("Dir exists!"); string[] filesFound = Directory.GetFiles(_imagesDir); if(filesFound.Length > 0) { _images = new Texture2D[filesFound.Length]; int counter = 0; foreach(string fileAndPath in filesFound) { string fileName = fileAndPath.Substring(fileAndPath.LastIndexOf("\\") + 1); // Returns name of the file string filePath = _imagesDir + "/" + fileName; // Returns full location of file plus it's name if (File.Exists(filePath)) { Debug.Log("File exists!"); byte[] imageData = File.ReadAllBytes(filePath); // Input all image data into bytes array Texture2D levelTex = new Texture2D(1, 1); // Create a new texture file levelTex.LoadImage(imageData); // Load byte array (image data) into texture file _images[counter] = levelTex; // Set current image in array position to = current texture counter++; // Increase array position counter //_levelText.text = filePath.ToString(); } else { Debug.Log("File not found: " + filePath); } } GenerateImage(_images[Random.Range(0, _images.Length)]); // Run GenerateImage function from random texture in images array } else { Debug.LogWarning("No files found in directory! Looking for files at dir: " + _imagesDir); // Warning log - No files in directory } } else { Debug.LogError("Dir does not exist! Trying to find: " + _imagesDir); // Error log - Directory does not exist } } private void GenerateImage(Texture2D _image) { Color[] pixel = _image.GetPixels(); // Set color array for all pixels in image int mapX = _image.width; // Set map size by image width and height int mapZ = _image.height; Vector3[] spawnPositions = new Vector3[(pixel.Length)]; // Set Vector3 array for spawn positions to = how many pixels exist Debug.Log("Amount of pixels = " + pixel.Length); Vector3 startSpawnPosition = new Vector3(-Mathf.Round(mapX / 2), 0, -Mathf.Round(mapZ / 2) * _scale); // Set start position Vector3 currentSpawnPosition = startSpawnPosition; // Ensure current position is the start position int counter = 0; for (int z = 0; z < mapZ; z++) { for (int x = 0; x < mapX; x++) { spawnPositions[counter] = currentSpawnPosition; // Moves position of image generator along in a left to right then up 'S pattern' counter++; currentSpawnPosition.x+= _scale; } currentSpawnPosition.x = startSpawnPosition.x; currentSpawnPosition.z+= _scale; } foreach (Vector3 pos in spawnPositions) // For each spawn position { counter = 1; int arraycounter = 0; Color colour = pixel[counter]; // Check colour of pixel at counter position if (colour.Equals(Color.white)) // If colour of pixel is white { Transform spawnedTransform = Instantiate(_wall, pos, Quaternion.identity).transform; // Spawn wall for white pixel spawnedTransform.localScale = Vector3.one * _scale; spawnedTransform.localScale = new Vector3(_scale, 3, _scale); //spawnedTransform.transform.parent = gameObject.transform; groundObjectsToCombine.Add(spawnedTransform.gameObject); // Add object to list for wall objects to be mesh combined Debug.Log(arraycounter); groundObjects[arraycounter] = spawnedTransform.gameObject; spawnedTransform.transform.SetParent(groundObjects[arraycounter].transform); } else if (colour.Equals(Color.black)) // If colour of pixel is black { Transform spawnedTransform = Instantiate(_ground, pos, Quaternion.identity).transform; // Spawn ground for black pixel spawnedTransform.localScale = Vector3.one * _scale; //spawnedTransform.transform.parent = gameObject.transform; groundObjectsToCombine.Add(spawnedTransform.gameObject); // Add object to list for ground objects to be mesh combined Debug.Log(arraycounter); groundObjects[arraycounter] = spawnedTransform.gameObject; spawnedTransform.transform.SetParent(groundObjects[arraycounter].transform); } else { Transform spawnedTransform = Instantiate(_ground, pos, Quaternion.identity).transform; // Spawn ground for undefined pixel spawnedTransform.localScale = Vector3.one * _scale; //spawnedTransform.transform.parent = gameObject.transform; groundObjectsToCombine.Add(spawnedTransform.gameObject); // Add object to list for ground objects to be mesh combined Debug.Log(arraycounter); groundObjects[arraycounter] = spawnedTransform.gameObject; spawnedTransform.transform.SetParent(groundObjects[arraycounter].transform); } counter++; // Increase counter arraycounter++; } for (int i = 0; i < groundObjects.Length; i++) { CombineGroundMeshes(groundObjects[i]); } // BELOW IS A DEBUG FUNCTION AND IS NOT REQUIRED FOR IMAGE GENERATOR - THIS FUNCTION COUNTS BLACK AND WHITE PIXELS IN INPUT IMAGE int black = 0; int white = 1; foreach (Color colour in pixel) { if (colour.Equals(Color.white)) { white++; } else if (colour.Equals(Color.black)) { black++; } } Debug.Log("White = " + white); Debug.Log("Black = " + black); } private void CombineGroundMeshes(GameObject groundobj) { Debug.Log("I got here"); Vector3 position = groundobj.transform.position; groundobj.transform.position = Vector3.zero; MeshFilter[] meshfilters = groundobj.GetComponentsInChildren(); CombineInstance[] combine = new CombineInstance[meshfilters.Length]; int amt = 1; while(amt < meshfilters.Length) { combine[amt].mesh = meshfilters[amt].sharedMesh; combine[amt].transform = meshfilters[amt].transform.localToWorldMatrix; meshfilters[amt].gameObject.SetActive(false); amt++; } groundobj.transform.GetComponent().mesh = new Mesh(); groundobj.transform.GetComponent().mesh.CombineMeshes(combine, true, true); groundobj.transform.gameObject.SetActive(true); groundobj.transform.position = position; groundobj.AddComponent(); } }