Browse Source

Procedural Generation v1

Myval5773 3 tuần trước cách đây
mục cha
commit
9564382220
24 tập tin đã thay đổi với 1657 bổ sung4 xóa
  1. 8 0
      GAMEN3_FinalProject/Assets/Editor.meta
  2. 24 0
      GAMEN3_FinalProject/Assets/Editor/MapGeneratorEditor.cs
  3. 2 0
      GAMEN3_FinalProject/Assets/Editor/MapGeneratorEditor.cs.meta
  4. 8 0
      GAMEN3_FinalProject/Assets/Materials.meta
  5. 137 0
      GAMEN3_FinalProject/Assets/Materials/MapMaterial.mat
  6. 8 0
      GAMEN3_FinalProject/Assets/Materials/MapMaterial.mat.meta
  7. 136 0
      GAMEN3_FinalProject/Assets/Materials/MeshMaterial.mat
  8. 8 0
      GAMEN3_FinalProject/Assets/Materials/MeshMaterial.mat.meta
  9. 786 0
      GAMEN3_FinalProject/Assets/Scenes/MainMap.unity
  10. 7 0
      GAMEN3_FinalProject/Assets/Scenes/MainMap.unity.meta
  11. 4 4
      GAMEN3_FinalProject/Assets/Scenes/MainMenu.unity
  12. 8 0
      GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration.meta
  13. 123 0
      GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration/EndlessTerrain.cs
  14. 2 0
      GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration/EndlessTerrain.cs.meta
  15. 21 0
      GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration/MapDisplay.cs
  16. 2 0
      GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration/MapDisplay.cs.meta
  17. 180 0
      GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration/MapGenerator.cs
  18. 2 0
      GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration/MapGenerator.cs.meta
  19. 75 0
      GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration/MeshGenerator.cs
  20. 2 0
      GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration/MeshGenerator.cs.meta
  21. 74 0
      GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration/Noise.cs
  22. 2 0
      GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration/Noise.cs.meta
  23. 36 0
      GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration/TextureGenerator.cs
  24. 2 0
      GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration/TextureGenerator.cs.meta

+ 8 - 0
GAMEN3_FinalProject/Assets/Editor.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 69649f5ca77bb1f4595fdb6ceb5833c4
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 24 - 0
GAMEN3_FinalProject/Assets/Editor/MapGeneratorEditor.cs

@@ -0,0 +1,24 @@
+using UnityEngine;
+using UnityEditor;
+
+[CustomEditor(typeof(MapGenerator))]
+public class MapGeneratorEditor : Editor
+{
+    public override void OnInspectorGUI()
+    {
+        MapGenerator mapGen = (MapGenerator)target;
+
+        if (DrawDefaultInspector())
+        {
+            if (mapGen.autoUpdate)
+            {
+                mapGen.DrawMapInEditor();
+            }
+        }
+
+        if (GUILayout.Button("Generate"))
+        {
+            mapGen.DrawMapInEditor();
+        }
+    }
+}

+ 2 - 0
GAMEN3_FinalProject/Assets/Editor/MapGeneratorEditor.cs.meta

@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 6fe55b2f7f7cb9843987257eda0d42ca

+ 8 - 0
GAMEN3_FinalProject/Assets/Materials.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 7cc13c54553c5774f9bf0a18614f75c9
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 137 - 0
GAMEN3_FinalProject/Assets/Materials/MapMaterial.mat

@@ -0,0 +1,137 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+  serializedVersion: 8
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: MapMaterial
+  m_Shader: {fileID: 10752, guid: 0000000000000000f000000000000000, type: 0}
+  m_Parent: {fileID: 0}
+  m_ModifiedSerializedProperties: 0
+  m_ValidKeywords: []
+  m_InvalidKeywords: []
+  m_LightmapFlags: 4
+  m_EnableInstancingVariants: 0
+  m_DoubleSidedGI: 0
+  m_CustomRenderQueue: -1
+  stringTagMap: {}
+  disabledShaderPasses:
+  - MOTIONVECTORS
+  m_LockedProperties: 
+  m_SavedProperties:
+    serializedVersion: 3
+    m_TexEnvs:
+    - _BaseMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _BumpMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailAlbedoMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailMask:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailNormalMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _EmissionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MainTex:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MetallicGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _OcclusionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _ParallaxMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _SpecGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_Lightmaps:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_LightmapsInd:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_ShadowMasks:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    m_Ints: []
+    m_Floats:
+    - _AddPrecomputedVelocity: 0
+    - _AlphaClip: 0
+    - _AlphaToMask: 0
+    - _Blend: 0
+    - _BlendModePreserveSpecular: 1
+    - _BlendOp: 0
+    - _BumpScale: 1
+    - _ClearCoatMask: 0
+    - _ClearCoatSmoothness: 0
+    - _Cull: 2
+    - _Cutoff: 0.5
+    - _DetailAlbedoMapScale: 1
+    - _DetailNormalMapScale: 1
+    - _DstBlend: 0
+    - _DstBlendAlpha: 0
+    - _EnvironmentReflections: 1
+    - _GlossMapScale: 0
+    - _Glossiness: 0
+    - _GlossyReflections: 0
+    - _Metallic: 0
+    - _OcclusionStrength: 1
+    - _Parallax: 0.005
+    - _QueueOffset: 0
+    - _ReceiveShadows: 1
+    - _SampleGI: 0
+    - _Smoothness: 0.5
+    - _SmoothnessTextureChannel: 0
+    - _SpecularHighlights: 1
+    - _SrcBlend: 1
+    - _SrcBlendAlpha: 1
+    - _Surface: 0
+    - _WorkflowMode: 1
+    - _ZWrite: 1
+    m_Colors:
+    - _BaseColor: {r: 1, g: 1, b: 1, a: 1}
+    - _Color: {r: 1, g: 1, b: 1, a: 1}
+    - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
+    - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
+  m_BuildTextureStacks: []
+  m_AllowLocking: 1
+--- !u!114 &209142324782217317
+MonoBehaviour:
+  m_ObjectHideFlags: 11
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  version: 10

+ 8 - 0
GAMEN3_FinalProject/Assets/Materials/MapMaterial.mat.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 815a84fb69a151f49b17497489e27727
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 2100000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 136 - 0
GAMEN3_FinalProject/Assets/Materials/MeshMaterial.mat

@@ -0,0 +1,136 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &-4628544967791815965
+MonoBehaviour:
+  m_ObjectHideFlags: 11
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  version: 10
+--- !u!21 &2100000
+Material:
+  serializedVersion: 8
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: MeshMaterial
+  m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
+  m_Parent: {fileID: 0}
+  m_ModifiedSerializedProperties: 0
+  m_ValidKeywords: []
+  m_InvalidKeywords: []
+  m_LightmapFlags: 4
+  m_EnableInstancingVariants: 0
+  m_DoubleSidedGI: 0
+  m_CustomRenderQueue: -1
+  stringTagMap:
+    RenderType: Opaque
+  disabledShaderPasses:
+  - MOTIONVECTORS
+  m_LockedProperties: 
+  m_SavedProperties:
+    serializedVersion: 3
+    m_TexEnvs:
+    - _BaseMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _BumpMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailAlbedoMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailMask:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailNormalMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _EmissionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MainTex:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MetallicGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _OcclusionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _ParallaxMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _SpecGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_Lightmaps:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_LightmapsInd:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_ShadowMasks:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    m_Ints: []
+    m_Floats:
+    - _AddPrecomputedVelocity: 0
+    - _AlphaClip: 0
+    - _AlphaToMask: 0
+    - _Blend: 0
+    - _BlendModePreserveSpecular: 1
+    - _BumpScale: 1
+    - _ClearCoatMask: 0
+    - _ClearCoatSmoothness: 0
+    - _Cull: 2
+    - _Cutoff: 0.5
+    - _DetailAlbedoMapScale: 1
+    - _DetailNormalMapScale: 1
+    - _DstBlend: 0
+    - _DstBlendAlpha: 0
+    - _EnvironmentReflections: 1
+    - _GlossMapScale: 0
+    - _Glossiness: 0
+    - _GlossyReflections: 0
+    - _Metallic: 0
+    - _OcclusionStrength: 1
+    - _Parallax: 0.005
+    - _QueueOffset: 0
+    - _ReceiveShadows: 1
+    - _Smoothness: 0
+    - _SmoothnessTextureChannel: 0
+    - _SpecularHighlights: 1
+    - _SrcBlend: 1
+    - _SrcBlendAlpha: 1
+    - _Surface: 0
+    - _WorkflowMode: 1
+    - _ZWrite: 1
+    m_Colors:
+    - _BaseColor: {r: 1, g: 1, b: 1, a: 1}
+    - _Color: {r: 1, g: 1, b: 1, a: 1}
+    - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
+    - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
+  m_BuildTextureStacks: []
+  m_AllowLocking: 1

+ 8 - 0
GAMEN3_FinalProject/Assets/Materials/MeshMaterial.mat.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 8bf955528acdb5f44a372c44f7300dda
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 2100000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 786 - 0
GAMEN3_FinalProject/Assets/Scenes/MainMap.unity


+ 7 - 0
GAMEN3_FinalProject/Assets/Scenes/MainMap.unity.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: c6fd845ee7caaa547a19f84b317666c1
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 4 - 4
GAMEN3_FinalProject/Assets/Scenes/MainMenu.unity

@@ -199,9 +199,9 @@ RectTransform:
   m_Children: []
   m_Father: {fileID: 1377351668}
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
-  m_AnchorMin: {x: 0.5, y: 0.5}
-  m_AnchorMax: {x: 0.5, y: 0.5}
-  m_AnchoredPosition: {x: 0, y: 107.5}
+  m_AnchorMin: {x: 0.5, y: 1}
+  m_AnchorMax: {x: 0.5, y: 1}
+  m_AnchoredPosition: {x: 0, y: -251.69}
   m_SizeDelta: {x: 1070.7, y: 50}
   m_Pivot: {x: 0.5, y: 0.5}
 --- !u!114 &221809532
@@ -871,7 +871,7 @@ RectTransform:
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
   m_AnchorMin: {x: 0.5, y: 0.5}
   m_AnchorMax: {x: 0.5, y: 0.5}
-  m_AnchoredPosition: {x: -180, y: -130}
+  m_AnchoredPosition: {x: 0, y: -85.2}
   m_SizeDelta: {x: 180, y: 50}
   m_Pivot: {x: 0.5, y: 0.5}
 --- !u!114 &1529804920

+ 8 - 0
GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 0262aed7d18b17342879b7fb08000cec
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 123 - 0
GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration/EndlessTerrain.cs

@@ -0,0 +1,123 @@
+using UnityEngine;
+using System.Collections;
+using System.Collections.Generic;
+
+public class EndlessTerrain : MonoBehaviour
+{
+    public const float maxViewDist = 450;
+    public Transform viewer;
+    public Material mapMaterial;
+
+    public static Vector2 viewerPosition;
+    static MapGenerator mapGenerator;
+
+
+    int chunkSize;
+    int chunksVisibleInViewDst;
+
+    Dictionary<Vector2, TerrainChunk> terrainChunkDictionary = new Dictionary<Vector2, TerrainChunk>();
+    List<TerrainChunk> terrainChunksVisibleLastUpdate = new List<TerrainChunk>();
+
+    private void Start()
+    {
+        mapGenerator = FindFirstObjectByType<MapGenerator>();
+        chunkSize = MapGenerator.mapChunkSize - 1;
+        chunksVisibleInViewDst = Mathf.RoundToInt(maxViewDist / chunkSize);
+    }
+
+    private void Update()
+    {
+        viewerPosition = new Vector2(viewer.position.x, viewer.position.z);
+        UpdateVisibleChunks();
+    }
+
+    void UpdateVisibleChunks()
+    {
+        for (int i = 0; i < terrainChunksVisibleLastUpdate.Count; i++)
+        {
+            terrainChunksVisibleLastUpdate[i].SetVisible(false);
+        }
+        terrainChunksVisibleLastUpdate.Clear();
+
+        int currentChunkCoordX = Mathf.RoundToInt(viewerPosition.x / chunkSize);
+        int currentChunkCoordY = Mathf.RoundToInt(viewerPosition.y / chunkSize);
+
+        for (int yOffset = -chunksVisibleInViewDst; yOffset <= chunksVisibleInViewDst; yOffset++)
+        {
+            for (int xOffset = -chunksVisibleInViewDst; xOffset <= chunksVisibleInViewDst; xOffset++)
+            {
+                Vector2 viewedChunkCoord = new Vector2(currentChunkCoordX + xOffset, currentChunkCoordY + yOffset);
+
+                if (terrainChunkDictionary.ContainsKey(viewedChunkCoord))
+                {
+                    terrainChunkDictionary[viewedChunkCoord].UpdateTerrainChunk();
+                    if (terrainChunkDictionary[viewedChunkCoord].IsVisible())
+                    {
+                        terrainChunksVisibleLastUpdate.Add(terrainChunkDictionary[viewedChunkCoord]);
+                    }
+                }
+                else
+                {
+                    terrainChunkDictionary.Add(viewedChunkCoord, new TerrainChunk(viewedChunkCoord, chunkSize, transform, mapMaterial));
+                }
+            }
+        }
+    }
+
+    public class TerrainChunk
+    {
+        GameObject meshObject;
+        Vector2 position;
+        Bounds bounds;
+
+        MapData mapData;
+
+        MeshRenderer meshRenderer;
+        MeshFilter meshFilter;
+
+        public TerrainChunk(Vector2 coord, int size, Transform parent, Material material)
+        {
+            position = coord * size;
+            bounds = new Bounds(position, Vector2.one * size);
+            Vector3 positionV3 = new Vector3(position.x, 0, position.y);
+
+            meshObject = new GameObject("Terrain Chunk");
+            meshRenderer = meshObject.AddComponent<MeshRenderer>();
+            meshFilter = meshObject.AddComponent<MeshFilter>();
+            meshRenderer.material = material;
+
+            meshObject.transform.position = positionV3;
+            meshObject.transform.parent = parent;
+            SetVisible(false);
+
+            mapGenerator.RequestMapData(OnMapDataReceived);
+        }
+
+        void OnMapDataReceived(MapData mapData)
+        {
+            mapGenerator.RequestMeshData(mapData, OnMeshDataReceived);
+        }
+
+        void OnMeshDataReceived(MeshData meshData)
+        {
+            meshFilter.mesh = meshData.CreateMesh();
+        }
+
+        public void UpdateTerrainChunk()
+        {
+            float viewerDstFromNearestEdge = Mathf.Sqrt(bounds.SqrDistance(viewerPosition));
+            bool visible = viewerDstFromNearestEdge <= maxViewDist;
+            SetVisible(visible);
+        }
+
+        public void SetVisible(bool visible)
+        {
+            meshObject.SetActive(visible);
+        }
+
+        public bool IsVisible()
+        {
+            return meshObject.activeSelf;
+        }
+    }
+}

+ 2 - 0
GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration/EndlessTerrain.cs.meta

@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 0aebda5ed429ebd42aac0fa28d948774

+ 21 - 0
GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration/MapDisplay.cs

@@ -0,0 +1,21 @@
+using UnityEditor;
+using UnityEngine;
+
+public class MapDisplay : MonoBehaviour
+{
+    public Renderer textureRenderer;
+    public MeshFilter meshFilter;
+    public MeshRenderer meshRenderer;
+
+    public void DrawTexture(Texture2D texture)
+    {
+        textureRenderer.sharedMaterial.mainTexture = texture;
+        textureRenderer.transform.localScale = new Vector3(texture.width, 1, texture.height);
+    }
+
+    public void DrawMesh(MeshData meshData, Texture2D texture)
+    {
+        meshFilter.sharedMesh = meshData.CreateMesh();
+        meshRenderer.sharedMaterial.mainTexture = texture;
+    }
+}

+ 2 - 0
GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration/MapDisplay.cs.meta

@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: e0927a56e956db84fa25a201b408ce86

+ 180 - 0
GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration/MapGenerator.cs

@@ -0,0 +1,180 @@
+using UnityEngine;
+using System.Threading;
+using System;
+using System.Collections.Generic;
+using System.Net.Http.Headers;
+
+public class MapGenerator : MonoBehaviour
+{
+    public enum DrawMode {NoiseMap, ColorMap, Mesh};
+
+    public DrawMode drawMode;
+
+    public const int mapChunkSize = 241;
+    [Range(0,6)]
+    public int levelOfDetail;
+    public float noiseScale;
+
+
+    public int octaves;
+    [Range(0, 1)]
+    public float persistance;
+    public float lacunarity;
+
+    public int seed;
+    public Vector2 offset;
+
+    public float meshHeightMultiplier;
+    public AnimationCurve meshHeightCurve;
+
+    public bool autoUpdate;
+
+    public TerrainType[] regions;
+
+    Queue<MapThreadInfo<MapData>> mapDataThreadInfoQueue = new Queue<MapThreadInfo<MapData>>();
+    Queue<MapThreadInfo<MeshData>> meshDataThreadInfoQueue = new Queue<MapThreadInfo<MeshData>>();
+
+    public void DrawMapInEditor()
+    {
+        MapData mapData = GenerateMapData();
+
+        MapDisplay display = FindFirstObjectByType<MapDisplay>();
+        if (drawMode == DrawMode.NoiseMap)
+        {
+            display.DrawTexture(TextureGenerator.TextureFromHeightMap(mapData.heightMap));
+        }
+        else if (drawMode == DrawMode.ColorMap)
+        {
+            display.DrawTexture(TextureGenerator.TextureFromColorMap(mapData.colorMap, mapChunkSize, mapChunkSize));
+        }
+        else if (drawMode == DrawMode.Mesh)
+        {
+            display.DrawMesh(MeshGenerator.GenerateTerrainMesh(mapData.heightMap, meshHeightMultiplier, meshHeightCurve, levelOfDetail), TextureGenerator.TextureFromColorMap(mapData.colorMap, mapChunkSize, mapChunkSize));
+        }
+
+    }
+
+    public void RequestMapData(Action<MapData> callback)
+    {
+        ThreadStart threadStart = delegate
+        {
+            MapDataThread(callback);
+        };
+
+        new Thread(threadStart).Start();
+    }
+
+    void MapDataThread(Action<MapData> callback)
+    {
+        MapData mapData = GenerateMapData();
+        lock (mapDataThreadInfoQueue)
+        {
+            mapDataThreadInfoQueue.Enqueue(new MapThreadInfo<MapData>(callback, mapData));
+        }
+    }
+
+    public void RequestMeshData(MapData mapData, Action<MeshData> callback)
+    {
+        ThreadStart threadStart = delegate {
+            MeshDataThread(mapData, callback);
+        };
+        new Thread(threadStart).Start();
+    }
+
+    void MeshDataThread(MapData mapData, Action<MeshData> callback)
+    {
+        MeshData meshData = MeshGenerator.GenerateTerrainMesh(mapData.heightMap, meshHeightMultiplier, meshHeightCurve, levelOfDetail);
+        lock (meshDataThreadInfoQueue)
+        {
+            meshDataThreadInfoQueue.Enqueue(new MapThreadInfo<MeshData>(callback, meshData));
+        }
+    }
+
+    private void Update()
+    {
+        if(mapDataThreadInfoQueue.Count > 0)
+        {
+            for(int i = 0; i < mapDataThreadInfoQueue.Count; i++)
+            {
+                MapThreadInfo<MapData> threadInfo = mapDataThreadInfoQueue.Dequeue();
+                threadInfo.callback(threadInfo.parameter);
+            }
+        }
+
+        if (meshDataThreadInfoQueue.Count > 0) { 
+            for(int i = 0; i < meshDataThreadInfoQueue.Count; i++)
+            {
+                MapThreadInfo<MeshData> threadInfo = meshDataThreadInfoQueue.Dequeue();
+                threadInfo.callback(threadInfo.parameter);
+            }
+        }
+    }
+
+    MapData GenerateMapData()
+    {
+        float[,] noiseMap = Noise.GenerateNoiseMap(mapChunkSize, mapChunkSize, seed, noiseScale, octaves, persistance, lacunarity, offset);
+
+        Color[] colorMap = new Color[mapChunkSize * mapChunkSize];
+        for (int y = 0; y < mapChunkSize; y++)
+        {
+            for (int x = 0; x < mapChunkSize; x++)
+            {
+                float currentHeight = noiseMap[x, y];
+                for(int i = 0; i < regions.Length; i++)
+                {
+                    if(currentHeight <= regions[i].height)
+                    {
+                        colorMap[y * mapChunkSize + x] = regions[i].color;
+                        break;
+                    }
+                }
+            }
+        }
+
+        return new MapData(noiseMap, colorMap);
+    }
+
+    private void OnValidate()
+    {
+        if(lacunarity < 1)
+        {
+            lacunarity = 1;
+        }
+        if(octaves < 0)
+        {
+            octaves = 0;
+        }
+    }
+
+    struct MapThreadInfo<T>
+    {
+        public readonly Action<T> callback;
+        public readonly T parameter;
+
+        public MapThreadInfo(Action<T> callback, T parameter)
+        {
+            this.callback = callback;
+            this.parameter = parameter;
+        }
+    }
+}
+
+[System.Serializable]
+public struct TerrainType
+{
+    public string name;
+    public float height;
+    public Color color;
+}
+
+public struct MapData
+{
+    public readonly float[,] heightMap;
+    public readonly Color[] colorMap;
+
+    public MapData(float[,] heightMap, Color[] colorMap)
+    {
+        this.heightMap = heightMap;
+        this.colorMap = colorMap;
+    }
+}

+ 2 - 0
GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration/MapGenerator.cs.meta

@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: e1cc1e9573569a44e94663095ea1abd9

+ 75 - 0
GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration/MeshGenerator.cs

@@ -0,0 +1,75 @@
+using UnityEngine;
+
+public static class MeshGenerator
+{
+    public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve, int levelOfDetail)
+    {
+        AnimationCurve heightCurve = new AnimationCurve(_heightCurve.keys);
+
+        int width = heightMap.GetLength(0);
+        int height = heightMap.GetLength(1);
+
+        float topLeftX = (width - 1) / -2f;
+        float topLeftZ = (height - 1) / 2f;
+
+        int meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2;
+        int verticesPerLine = (width - 1) / meshSimplificationIncrement + 1;
+
+        MeshData meshData = new MeshData(verticesPerLine, verticesPerLine);
+        int vertexIndex = 0;
+
+        for(int y = 0; y < height; y += meshSimplificationIncrement)
+        {
+            for(int  x = 0; x < width; x += meshSimplificationIncrement)
+            {
+                meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, heightCurve.Evaluate(heightMap[x,y])* heightMultiplier, topLeftZ - y);
+                meshData.uvs[vertexIndex] = new Vector2(x/(float)width, y/(float)height);
+
+                if(x < width - 1 && y < height - 1)
+                {
+                    meshData.AddTriangle(vertexIndex, vertexIndex + verticesPerLine + 1, vertexIndex + verticesPerLine);
+                    meshData.AddTriangle(vertexIndex + verticesPerLine + 1, vertexIndex, vertexIndex + 1);
+                }
+                
+                vertexIndex++;
+            }
+        }
+
+        return meshData;
+    }
+}
+
+public class MeshData
+{
+    public Vector3[] vertices;
+    public int[] triangles;
+
+    public Vector2[] uvs;
+
+    int triangleIndex;
+
+    public MeshData(int meshWidth, int meshHeight)
+    {
+        vertices = new Vector3[meshWidth * meshHeight];
+        uvs = new Vector2[meshWidth * meshHeight];
+        triangles = new int[(meshWidth-1) * (meshHeight-1) * 6];
+    }
+
+    public void AddTriangle(int a, int b, int c)
+    {
+        triangles[triangleIndex] = a;
+        triangles[triangleIndex+1] = b;
+        triangles[triangleIndex+2] = c;
+        triangleIndex += 3;
+    }
+
+    public Mesh CreateMesh()
+    {
+        Mesh mesh = new Mesh();
+        mesh.vertices = vertices;
+        mesh.triangles = triangles;
+        mesh.uv = uvs;
+        mesh.RecalculateNormals();
+        return mesh;
+    }
+}

+ 2 - 0
GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration/MeshGenerator.cs.meta

@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 626cb82156fc1b846a94e87eb299dc1b

+ 74 - 0
GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration/Noise.cs

@@ -0,0 +1,74 @@
+using System.IO.IsolatedStorage;
+using UnityEngine;
+
+public static class Noise
+{
+    public static float[,] GenerateNoiseMap(int mapWidth, int mapHeight, int seed, float scale, int octaves, float persistance, float lacunarity, Vector2 offset)
+    {
+        float[,] noiseMap = new float[mapWidth, mapHeight];
+
+        System.Random prng = new System.Random(seed);
+        Vector2[] octaveOffsets = new Vector2[octaves];
+
+        for(int i = 0; i < octaves; i++)
+        {
+            float offsetX = prng.Next(-100000, 100000) + offset.x;
+            float offsetY = prng.Next(-100000, 100000) + offset.y;
+            octaveOffsets[i] = new Vector2(offsetX, offsetY);
+        }
+
+        if(scale <= 0)
+        {
+            scale = 0.0001f;
+        }
+
+        float maxNoiseHeight = float.MinValue;
+        float minNoiseHeight = float.MaxValue;
+
+        float halfWidth = mapWidth / 2f;
+        float halfHeight = mapHeight / 2f;
+
+        for(int y = 0; y < mapHeight; y++)
+        {
+            for(int x = 0; x < mapWidth; x++)
+            {
+                float amplitude = 1;
+                float frequency = 1;
+                float noiseHeight = 0;
+
+                for(int i = 0; i < octaves; i++)
+                {
+                    float sampleX = (x-halfWidth) / scale * frequency + octaveOffsets[i].x;
+                    float sampleY = (y-halfHeight) / scale * frequency + octaveOffsets[i].y;
+
+                    float perlinValue = Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1;
+                    noiseHeight += perlinValue * amplitude;
+
+                    amplitude *= persistance;
+                    frequency *= lacunarity;
+                }
+                
+                if(noiseHeight > maxNoiseHeight)
+                {
+                    maxNoiseHeight = noiseHeight;
+                }
+                else if(noiseHeight < minNoiseHeight)
+                {
+                    minNoiseHeight = noiseHeight;
+                }
+
+                noiseMap[x, y] = noiseHeight;
+            }
+        }
+
+        for (int y = 0; y < mapHeight; y++)
+        {
+            for (int x = 0; x < mapWidth; x++)
+            {
+                noiseMap[x,y] = Mathf.InverseLerp(minNoiseHeight, maxNoiseHeight, noiseMap[x,y]);
+            }
+        }
+
+        return noiseMap;
+    }
+}

+ 2 - 0
GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration/Noise.cs.meta

@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: a360d4a509c1f7146a92ad66f7788fcb

+ 36 - 0
GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration/TextureGenerator.cs

@@ -0,0 +1,36 @@
+using UnityEngine;
+
+public static class TextureGenerator
+{
+    public static Texture2D TextureFromColorMap(Color[] colorMap, int width, int height)
+    {
+        Texture2D texture = new Texture2D(width, height);
+        texture.filterMode = FilterMode.Point;
+        texture.wrapMode = TextureWrapMode.Clamp;
+        texture.SetPixels(colorMap);
+        texture.Apply();
+
+        return texture;
+    }
+
+    public static Texture2D TextureFromHeightMap(float[,] heightMap)
+    {
+        int width = heightMap.GetLength(0);
+        int height = heightMap.GetLength(1);
+
+        Texture2D texture = new Texture2D(width, height);
+
+        Color[] colorMap = new Color[width * height];
+        for (int y = 0; y < height; y++)
+        {
+            for (int x = 0; x < width; x++)
+            {
+                colorMap[y * width + x] = Color.Lerp(Color.black, Color.white, heightMap[x, y]);
+            }
+        }
+
+        return TextureFromColorMap(colorMap, width, height);
+    }
+
+
+}

+ 2 - 0
GAMEN3_FinalProject/Assets/Scripts/ProceduralGeneration/TextureGenerator.cs.meta

@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 9a1d15ba90db2d44eb3fc648f92a1779

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác