first commit
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26fec7636ebd7ae43a99e2c187ed6500
|
||||
folderAsset: yes
|
||||
timeCreated: 1524052388
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,138 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_Name: Black
|
||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_ShaderKeywords:
|
||||
m_LightmapFlags: 5
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
m_SavedProperties:
|
||||
serializedVersion: 2
|
||||
m_TexEnvs:
|
||||
data:
|
||||
first:
|
||||
name: _MainTex
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _BumpMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _DetailNormalMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _ParallaxMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _OcclusionMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _EmissionMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _DetailMask
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _DetailAlbedoMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _MetallicGlossMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
data:
|
||||
first:
|
||||
name: _SrcBlend
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _DstBlend
|
||||
second: 0
|
||||
data:
|
||||
first:
|
||||
name: _Cutoff
|
||||
second: 0.5
|
||||
data:
|
||||
first:
|
||||
name: _Parallax
|
||||
second: 0.02
|
||||
data:
|
||||
first:
|
||||
name: _ZWrite
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _Glossiness
|
||||
second: 0.33
|
||||
data:
|
||||
first:
|
||||
name: _BumpScale
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _OcclusionStrength
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _DetailNormalMapScale
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _UVSec
|
||||
second: 0
|
||||
data:
|
||||
first:
|
||||
name: _Mode
|
||||
second: 0
|
||||
data:
|
||||
first:
|
||||
name: _Metallic
|
||||
second: 0
|
||||
m_Colors:
|
||||
data:
|
||||
first:
|
||||
name: _EmissionColor
|
||||
second: {r: 0, g: 0, b: 0, a: 1}
|
||||
data:
|
||||
first:
|
||||
name: _Color
|
||||
second: {r: 0.06666667, g: 0.06666667, b: 0.06666667, a: 1}
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1598ff147655ecb4893e78f88baa9475
|
||||
timeCreated: 1524052433
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,138 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_Name: LightGreen
|
||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_ShaderKeywords:
|
||||
m_LightmapFlags: 5
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
m_SavedProperties:
|
||||
serializedVersion: 2
|
||||
m_TexEnvs:
|
||||
data:
|
||||
first:
|
||||
name: _MainTex
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _BumpMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _DetailNormalMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _ParallaxMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _OcclusionMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _EmissionMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _DetailMask
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _DetailAlbedoMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _MetallicGlossMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
data:
|
||||
first:
|
||||
name: _SrcBlend
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _DstBlend
|
||||
second: 0
|
||||
data:
|
||||
first:
|
||||
name: _Cutoff
|
||||
second: 0.5
|
||||
data:
|
||||
first:
|
||||
name: _Parallax
|
||||
second: 0.02
|
||||
data:
|
||||
first:
|
||||
name: _ZWrite
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _Glossiness
|
||||
second: 0.5
|
||||
data:
|
||||
first:
|
||||
name: _BumpScale
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _OcclusionStrength
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _DetailNormalMapScale
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _UVSec
|
||||
second: 0
|
||||
data:
|
||||
first:
|
||||
name: _Mode
|
||||
second: 0
|
||||
data:
|
||||
first:
|
||||
name: _Metallic
|
||||
second: 0
|
||||
m_Colors:
|
||||
data:
|
||||
first:
|
||||
name: _EmissionColor
|
||||
second: {r: 0, g: 0, b: 0, a: 1}
|
||||
data:
|
||||
first:
|
||||
name: _Color
|
||||
second: {r: 0.6397059, g: 0.63179064, b: 0.35277897, a: 1}
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cd644746d7159df42b0c206b559af881
|
||||
timeCreated: 1524052433
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,138 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_Name: Orange
|
||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_ShaderKeywords:
|
||||
m_LightmapFlags: 5
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
m_SavedProperties:
|
||||
serializedVersion: 2
|
||||
m_TexEnvs:
|
||||
data:
|
||||
first:
|
||||
name: _MainTex
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _BumpMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _DetailNormalMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _ParallaxMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _OcclusionMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _EmissionMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _DetailMask
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _DetailAlbedoMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _MetallicGlossMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
data:
|
||||
first:
|
||||
name: _SrcBlend
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _DstBlend
|
||||
second: 0
|
||||
data:
|
||||
first:
|
||||
name: _Cutoff
|
||||
second: 0.5
|
||||
data:
|
||||
first:
|
||||
name: _Parallax
|
||||
second: 0.02
|
||||
data:
|
||||
first:
|
||||
name: _ZWrite
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _Glossiness
|
||||
second: 0.32
|
||||
data:
|
||||
first:
|
||||
name: _BumpScale
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _OcclusionStrength
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _DetailNormalMapScale
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _UVSec
|
||||
second: 0
|
||||
data:
|
||||
first:
|
||||
name: _Mode
|
||||
second: 0
|
||||
data:
|
||||
first:
|
||||
name: _Metallic
|
||||
second: 0.2
|
||||
m_Colors:
|
||||
data:
|
||||
first:
|
||||
name: _EmissionColor
|
||||
second: {r: 0, g: 0, b: 0, a: 1}
|
||||
data:
|
||||
first:
|
||||
name: _Color
|
||||
second: {r: 1, g: 0.52796555, b: 0, a: 1}
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09adc4af150569a4cb996354c367b8c8
|
||||
timeCreated: 1524052433
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,138 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_Name: Red
|
||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_ShaderKeywords:
|
||||
m_LightmapFlags: 5
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
m_SavedProperties:
|
||||
serializedVersion: 2
|
||||
m_TexEnvs:
|
||||
data:
|
||||
first:
|
||||
name: _MainTex
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _BumpMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _DetailNormalMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _ParallaxMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _OcclusionMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _EmissionMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _DetailMask
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _DetailAlbedoMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _MetallicGlossMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
data:
|
||||
first:
|
||||
name: _SrcBlend
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _DstBlend
|
||||
second: 0
|
||||
data:
|
||||
first:
|
||||
name: _Cutoff
|
||||
second: 0.5
|
||||
data:
|
||||
first:
|
||||
name: _Parallax
|
||||
second: 0.02
|
||||
data:
|
||||
first:
|
||||
name: _ZWrite
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _Glossiness
|
||||
second: 0.45
|
||||
data:
|
||||
first:
|
||||
name: _BumpScale
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _OcclusionStrength
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _DetailNormalMapScale
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _UVSec
|
||||
second: 0
|
||||
data:
|
||||
first:
|
||||
name: _Mode
|
||||
second: 0
|
||||
data:
|
||||
first:
|
||||
name: _Metallic
|
||||
second: 0
|
||||
m_Colors:
|
||||
data:
|
||||
first:
|
||||
name: _EmissionColor
|
||||
second: {r: 0, g: 0, b: 0, a: 1}
|
||||
data:
|
||||
first:
|
||||
name: _Color
|
||||
second: {r: 0.7058823, g: 0.15069398, b: 0, a: 1}
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ad7ce727a68a61f4897679b81da7b344
|
||||
timeCreated: 1524052433
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,138 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_Name: Yellow
|
||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_ShaderKeywords:
|
||||
m_LightmapFlags: 5
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
m_SavedProperties:
|
||||
serializedVersion: 2
|
||||
m_TexEnvs:
|
||||
data:
|
||||
first:
|
||||
name: _MainTex
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _BumpMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _DetailNormalMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _ParallaxMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _OcclusionMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _EmissionMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _DetailMask
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _DetailAlbedoMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
data:
|
||||
first:
|
||||
name: _MetallicGlossMap
|
||||
second:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
data:
|
||||
first:
|
||||
name: _SrcBlend
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _DstBlend
|
||||
second: 0
|
||||
data:
|
||||
first:
|
||||
name: _Cutoff
|
||||
second: 0.5
|
||||
data:
|
||||
first:
|
||||
name: _Parallax
|
||||
second: 0.02
|
||||
data:
|
||||
first:
|
||||
name: _ZWrite
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _Glossiness
|
||||
second: 0.5
|
||||
data:
|
||||
first:
|
||||
name: _BumpScale
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _OcclusionStrength
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _DetailNormalMapScale
|
||||
second: 1
|
||||
data:
|
||||
first:
|
||||
name: _UVSec
|
||||
second: 0
|
||||
data:
|
||||
first:
|
||||
name: _Mode
|
||||
second: 0
|
||||
data:
|
||||
first:
|
||||
name: _Metallic
|
||||
second: 0
|
||||
m_Colors:
|
||||
data:
|
||||
first:
|
||||
name: _EmissionColor
|
||||
second: {r: 0, g: 0, b: 0, a: 1}
|
||||
data:
|
||||
first:
|
||||
name: _Color
|
||||
second: {r: 0.972, g: 0.72733563, b: 0.025086528, a: 1}
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 90623549d4482f042ade35d8a0758e35
|
||||
timeCreated: 1524052433
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e1fad393017993c4893877b645062417
|
||||
timeCreated: 1521730297
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 66ccfe3c456c20c4f9de20d08685de69
|
||||
folderAsset: yes
|
||||
timeCreated: 1521730244
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,14 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Photon.Pun.Demo.Procedural
|
||||
{
|
||||
/// <summary>
|
||||
/// The Block component is attach to each instantiated Block at runtime.
|
||||
/// It provides the Block's ID as well as the parent's Cluster ID in order to apply modifications.
|
||||
/// </summary>
|
||||
public class Block : MonoBehaviour
|
||||
{
|
||||
public int BlockId { get; set; }
|
||||
public int ClusterId { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8b205f33043c113489ab36d5b56f7730
|
||||
timeCreated: 1521735355
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,178 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
using ExitGames.Client.Photon;
|
||||
|
||||
namespace Photon.Pun.Demo.Procedural
|
||||
{
|
||||
/// <summary>
|
||||
/// The Cluster component has references to all Blocks that are part of this Cluster.
|
||||
/// It provides functions for modifying single Blocks inside this Cluster.
|
||||
/// It also handles modifications made to the world by other clients.
|
||||
/// </summary>
|
||||
public class Cluster : MonoBehaviourPunCallbacks
|
||||
{
|
||||
private string propertiesKey;
|
||||
|
||||
private Dictionary<int, float> propertiesValue;
|
||||
|
||||
public int ClusterId { get; set; }
|
||||
|
||||
public Dictionary<int, GameObject> Blocks { get; private set; }
|
||||
|
||||
#region UNITY
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
Blocks = new Dictionary<int, GameObject>();
|
||||
|
||||
propertiesValue = new Dictionary<int, float>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the unique key of this Cluster used for storing modifications within the Custom Room Properties.
|
||||
/// </summary>
|
||||
private void Start()
|
||||
{
|
||||
propertiesKey = "Cluster " + ClusterId;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region CLASS FUNCTIONS
|
||||
|
||||
/// <summary>
|
||||
/// Adds a Block to the Cluster.
|
||||
/// This is called by the WorldGenerator while the generation process is running.
|
||||
/// In order to modify Blocks directly, we are storing the ID as well as a reference to the certain GameObject.
|
||||
/// </summary>
|
||||
public void AddBlock(int blockId, GameObject block)
|
||||
{
|
||||
Blocks.Add(blockId, block);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets called before a new world can be generated.
|
||||
/// Destroys each Block from this Cluster and removes the data stored in the Custom Room Properties.
|
||||
/// </summary>
|
||||
public void DestroyCluster()
|
||||
{
|
||||
foreach (GameObject block in Blocks.Values)
|
||||
{
|
||||
Destroy(block);
|
||||
}
|
||||
|
||||
Blocks.Clear();
|
||||
|
||||
if (PhotonNetwork.IsMasterClient)
|
||||
{
|
||||
RemoveClusterFromRoomProperties();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decreases a Block's height locally before applying the modification to the Custom Room Properties.
|
||||
/// </summary>
|
||||
public void DecreaseBlockHeight(int blockId)
|
||||
{
|
||||
float height = Blocks[blockId].transform.localScale.y;
|
||||
height = Mathf.Max((height - 1.0f), 0.0f);
|
||||
|
||||
SetBlockHeightLocal(blockId, height);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increases a Block's height locally before applying the modification to the Custom Room Properties.
|
||||
/// </summary>
|
||||
public void IncreaseBlockHeight(int blockId)
|
||||
{
|
||||
float height = Blocks[blockId].transform.localScale.y;
|
||||
height = Mathf.Min((height + 1.0f), 8.0f);
|
||||
|
||||
SetBlockHeightLocal(blockId, height);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets called when a remote client has modified a certain Block within this Cluster.
|
||||
/// Called by the WorldGenerator or the Cluster itself after the Custom Room Properties have been updated.
|
||||
/// </summary>
|
||||
public void SetBlockHeightRemote(int blockId, float height)
|
||||
{
|
||||
GameObject block = Blocks[blockId];
|
||||
|
||||
Vector3 scale = block.transform.localScale;
|
||||
Vector3 position = block.transform.localPosition;
|
||||
|
||||
block.transform.localScale = new Vector3(scale.x, height, scale.z);
|
||||
block.transform.localPosition = new Vector3(position.x, height / 2.0f, position.z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets called whenever the local client modifies any Block within this Cluster.
|
||||
/// The modification will be applied to the Block first before it is published to the Custom Room Properties.
|
||||
/// </summary>
|
||||
private void SetBlockHeightLocal(int blockId, float height)
|
||||
{
|
||||
GameObject block = Blocks[blockId];
|
||||
|
||||
Vector3 scale = block.transform.localScale;
|
||||
Vector3 position = block.transform.localPosition;
|
||||
|
||||
block.transform.localScale = new Vector3(scale.x, height, scale.z);
|
||||
block.transform.localPosition = new Vector3(position.x, height / 2.0f, position.z);
|
||||
|
||||
UpdateRoomProperties(blockId, height);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets called in order to update the Custom Room Properties with the modification made by the local client.
|
||||
/// </summary>
|
||||
private void UpdateRoomProperties(int blockId, float height)
|
||||
{
|
||||
propertiesValue[blockId] = height;
|
||||
|
||||
Hashtable properties = new Hashtable {{propertiesKey, propertiesValue}};
|
||||
PhotonNetwork.CurrentRoom.SetCustomProperties(properties);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the modifications of this Cluster from the Custom Room Properties.
|
||||
/// </summary>
|
||||
private void RemoveClusterFromRoomProperties()
|
||||
{
|
||||
Hashtable properties = new Hashtable {{propertiesKey, null}};
|
||||
PhotonNetwork.CurrentRoom.SetCustomProperties(properties);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PUN CALLBACKS
|
||||
|
||||
/// <summary>
|
||||
/// Gets called whenever the Custom Room Properties are updated.
|
||||
/// When the changed properties contain the previously set PropertiesKey (basically the Cluster ID),
|
||||
/// the Cluster and its Blocks will be updated accordingly.
|
||||
/// </summary>
|
||||
public override void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
|
||||
{
|
||||
if (propertiesThatChanged.ContainsKey(propertiesKey))
|
||||
{
|
||||
if (propertiesThatChanged[propertiesKey] == null)
|
||||
{
|
||||
propertiesValue = new Dictionary<int, float>();
|
||||
return;
|
||||
}
|
||||
|
||||
propertiesValue = (Dictionary<int, float>) propertiesThatChanged[propertiesKey];
|
||||
|
||||
foreach (KeyValuePair<int, float> pair in propertiesValue)
|
||||
{
|
||||
SetBlockHeightRemote(pair.Key, pair.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3fde284a91e7bf14dbf72b084e11736d
|
||||
timeCreated: 1521731876
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,269 @@
|
||||
using ExitGames.Client.Photon;
|
||||
using Photon.Realtime;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Photon.Pun.Demo.Procedural
|
||||
{
|
||||
/// <summary>
|
||||
/// The Ingame Control Panel basically controls the WorldGenerator.
|
||||
/// It is only interactable for the current MasterClient in the room.
|
||||
/// </summary>
|
||||
public class IngameControlPanel : MonoBehaviourPunCallbacks
|
||||
{
|
||||
private bool isSeedValid;
|
||||
|
||||
private InputField seedInputField;
|
||||
private Dropdown worldSizeDropdown;
|
||||
private Dropdown clusterSizeDropdown;
|
||||
private Dropdown worldTypeDropdown;
|
||||
private Button generateWorldButton;
|
||||
|
||||
#region UNITY
|
||||
|
||||
/// <summary>
|
||||
/// When the object gets created, all necessary references are set up.
|
||||
/// Also the UI elements get set up properly in order to control the WorldGenerator.
|
||||
/// </summary>
|
||||
public void Awake()
|
||||
{
|
||||
isSeedValid = false;
|
||||
|
||||
seedInputField = GetComponentInChildren<InputField>();
|
||||
seedInputField.characterLimit = 10;
|
||||
seedInputField.characterValidation = InputField.CharacterValidation.Integer;
|
||||
seedInputField.interactable = PhotonNetwork.PhotonServerSettings.StartInOfflineMode;
|
||||
seedInputField.onValueChanged.AddListener((string value) =>
|
||||
{
|
||||
int seed;
|
||||
if (int.TryParse(value, out seed))
|
||||
{
|
||||
isSeedValid = true;
|
||||
WorldGenerator.Instance.Seed = seed;
|
||||
}
|
||||
else
|
||||
{
|
||||
isSeedValid = false;
|
||||
Debug.LogError("Invalid Seed entered. Only numeric Seeds are allowed.");
|
||||
}
|
||||
});
|
||||
|
||||
worldSizeDropdown = GetComponentsInChildren<Dropdown>()[0];
|
||||
worldSizeDropdown.interactable = PhotonNetwork.PhotonServerSettings.StartInOfflineMode;
|
||||
worldSizeDropdown.onValueChanged.AddListener((int value) =>
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
WorldGenerator.Instance.WorldSize = WorldSize.Tiny;
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
WorldGenerator.Instance.WorldSize = WorldSize.Small;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
WorldGenerator.Instance.WorldSize = WorldSize.Medium;
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
WorldGenerator.Instance.WorldSize = WorldSize.Large;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
clusterSizeDropdown = GetComponentsInChildren<Dropdown>()[1];
|
||||
clusterSizeDropdown.interactable = PhotonNetwork.PhotonServerSettings.StartInOfflineMode;
|
||||
clusterSizeDropdown.onValueChanged.AddListener((int value) =>
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
WorldGenerator.Instance.ClusterSize = ClusterSize.Small;
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
WorldGenerator.Instance.ClusterSize = ClusterSize.Medium;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
WorldGenerator.Instance.ClusterSize = ClusterSize.Large;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
worldTypeDropdown = GetComponentsInChildren<Dropdown>()[2];
|
||||
worldTypeDropdown.interactable = PhotonNetwork.PhotonServerSettings.StartInOfflineMode;
|
||||
worldTypeDropdown.onValueChanged.AddListener((int value) =>
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
WorldGenerator.Instance.WorldType = WorldType.Flat;
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
WorldGenerator.Instance.WorldType = WorldType.Standard;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
WorldGenerator.Instance.WorldType = WorldType.Mountain;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
generateWorldButton = GetComponentInChildren<Button>();
|
||||
generateWorldButton.interactable = PhotonNetwork.PhotonServerSettings.StartInOfflineMode;
|
||||
generateWorldButton.onClick.AddListener(() =>
|
||||
{
|
||||
if (!PhotonNetwork.InRoom)
|
||||
{
|
||||
Debug.LogError("Client is not in a room.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isSeedValid)
|
||||
{
|
||||
Debug.LogError("Invalid Seed entered. Only numeric Seeds are allowed.");
|
||||
return;
|
||||
}
|
||||
|
||||
WorldGenerator.Instance.ConfirmAndUpdateProperties();
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PUN CALLBACKS
|
||||
|
||||
/// <summary>
|
||||
/// Gets called when the local client has joined the room.
|
||||
/// Since only the MasterClient can control the WorldGenerator,
|
||||
/// we are checking if we have to make the UI controls available for the local client.
|
||||
/// </summary>
|
||||
public override void OnJoinedRoom()
|
||||
{
|
||||
seedInputField.interactable = PhotonNetwork.IsMasterClient;
|
||||
worldSizeDropdown.interactable = PhotonNetwork.IsMasterClient;
|
||||
clusterSizeDropdown.interactable = PhotonNetwork.IsMasterClient;
|
||||
worldTypeDropdown.interactable = PhotonNetwork.IsMasterClient;
|
||||
generateWorldButton.interactable = PhotonNetwork.IsMasterClient;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets called whenever the current MasterClient has left the room and a new one is selected.
|
||||
/// If the local client is the new MasterClient, we make the UI controls available for him.
|
||||
/// </summary>
|
||||
public override void OnMasterClientSwitched(Player newMasterClient)
|
||||
{
|
||||
seedInputField.interactable = newMasterClient.IsLocal;
|
||||
worldSizeDropdown.interactable = newMasterClient.IsLocal;
|
||||
clusterSizeDropdown.interactable = newMasterClient.IsLocal;
|
||||
worldTypeDropdown.interactable = newMasterClient.IsLocal;
|
||||
generateWorldButton.interactable = newMasterClient.IsLocal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets called whenever the Custom Room Properties are updated.
|
||||
/// In this callback we are interested in the settings the MasterClient can apply to the WorldGenerator.
|
||||
/// If all possible settings are updated (and available within the updated properties), these settings are also used
|
||||
/// to update the Ingame Control Panel as well as the WorldGenerator on all clients.
|
||||
/// Afterwards the WorldGenerator creates a new world with the new settings.
|
||||
/// </summary>
|
||||
public override void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
|
||||
{
|
||||
if (propertiesThatChanged.ContainsKey(WorldGenerator.Instance.SeedPropertiesKey) && propertiesThatChanged.ContainsKey(WorldGenerator.Instance.WorldSizePropertiesKey) && propertiesThatChanged.ContainsKey(WorldGenerator.Instance.ClusterSizePropertiesKey) && propertiesThatChanged.ContainsKey(WorldGenerator.Instance.WorldTypePropertiesKey))
|
||||
{
|
||||
// Updating Seed
|
||||
int seed = (int) propertiesThatChanged[WorldGenerator.Instance.SeedPropertiesKey];
|
||||
seedInputField.text = seed.ToString();
|
||||
|
||||
// Updating World Size
|
||||
WorldSize worldSize = (WorldSize) propertiesThatChanged[WorldGenerator.Instance.WorldSizePropertiesKey];
|
||||
switch (worldSize)
|
||||
{
|
||||
case WorldSize.Tiny:
|
||||
{
|
||||
worldSizeDropdown.value = 0;
|
||||
break;
|
||||
}
|
||||
case WorldSize.Small:
|
||||
{
|
||||
worldSizeDropdown.value = 1;
|
||||
break;
|
||||
}
|
||||
case WorldSize.Medium:
|
||||
{
|
||||
worldSizeDropdown.value = 2;
|
||||
break;
|
||||
}
|
||||
case WorldSize.Large:
|
||||
{
|
||||
worldSizeDropdown.value = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Updating Cluster Size
|
||||
ClusterSize clusterSize = (ClusterSize) propertiesThatChanged[WorldGenerator.Instance.ClusterSizePropertiesKey];
|
||||
switch (clusterSize)
|
||||
{
|
||||
case ClusterSize.Small:
|
||||
{
|
||||
clusterSizeDropdown.value = 0;
|
||||
break;
|
||||
}
|
||||
case ClusterSize.Medium:
|
||||
{
|
||||
clusterSizeDropdown.value = 1;
|
||||
break;
|
||||
}
|
||||
case ClusterSize.Large:
|
||||
{
|
||||
clusterSizeDropdown.value = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Updating World Type
|
||||
WorldType worldType = (WorldType) propertiesThatChanged[WorldGenerator.Instance.WorldTypePropertiesKey];
|
||||
switch (worldType)
|
||||
{
|
||||
case WorldType.Flat:
|
||||
{
|
||||
worldTypeDropdown.value = 0;
|
||||
break;
|
||||
}
|
||||
case WorldType.Standard:
|
||||
{
|
||||
worldTypeDropdown.value = 1;
|
||||
break;
|
||||
}
|
||||
case WorldType.Mountain:
|
||||
{
|
||||
worldTypeDropdown.value = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Generating a new world
|
||||
WorldGenerator.Instance.CreateWorld();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e821c7c24a983d941a2d2c4400ecf9f7
|
||||
timeCreated: 1522919791
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,393 @@
|
||||
// Copyright(c) 2018, Benjamin Ward
|
||||
// All rights reserved.
|
||||
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
|
||||
// * Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
|
||||
// * Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// SimplexNoise for C#
|
||||
// Author: Benjamin Ward
|
||||
// Github Link: https://github.com/WardBenjamin/SimplexNoise
|
||||
// Originally authored by Heikki Törmälä
|
||||
|
||||
using System;
|
||||
|
||||
namespace Simplex
|
||||
{
|
||||
/// <summary>
|
||||
/// Implementation of the Perlin simplex noise, an improved Perlin noise algorithm.
|
||||
/// Based loosely on SimplexNoise1234 by Stefan Gustavson <http://staffwww.itn.liu.se/~stegu/aqsis/aqsis-newnoise/>
|
||||
/// </summary>
|
||||
public class Noise
|
||||
{
|
||||
public static float[] Calc1D(int width, float scale)
|
||||
{
|
||||
float[] values = new float[width];
|
||||
for (int i = 0; i < width; i++)
|
||||
values[i] = Generate(i * scale) * 128 + 128;
|
||||
return values;
|
||||
}
|
||||
|
||||
public static float[,] Calc2D(int width, int height, float scale)
|
||||
{
|
||||
float[,] values = new float[width, height];
|
||||
for (int i = 0; i < width; i++)
|
||||
for (int j = 0; j < height; j++)
|
||||
values[i, j] = Generate(i * scale, j * scale) * 128 + 128;
|
||||
return values;
|
||||
}
|
||||
|
||||
public static float[,,] Calc3D(int width, int height, int length, float scale)
|
||||
{
|
||||
float[,,] values = new float[width, height, length];
|
||||
for (int i = 0; i < width; i++)
|
||||
for (int j = 0; j < height; j++)
|
||||
for (int k = 0; k < length; k++)
|
||||
values[i, j, k] = Generate(i * scale, j * scale, k * scale) * 128 + 128;
|
||||
return values;
|
||||
}
|
||||
|
||||
public static float CalcPixel1D(int x, float scale)
|
||||
{
|
||||
return Generate(x * scale) * 128 + 128;
|
||||
}
|
||||
|
||||
public static float CalcPixel2D(int x, int y, float scale)
|
||||
{
|
||||
return Generate(x * scale, y * scale) * 128 + 128;
|
||||
}
|
||||
|
||||
public static float CalcPixel3D(int x, int y, int z, float scale)
|
||||
{
|
||||
return Generate(x * scale, y * scale, z * scale) * 128 + 128;
|
||||
}
|
||||
|
||||
static Noise()
|
||||
{
|
||||
perm = new byte[permOriginal.Length];
|
||||
Simplex.Noise.permOriginal.CopyTo(perm, 0);
|
||||
}
|
||||
|
||||
public static int Seed
|
||||
{
|
||||
get { return seed; }
|
||||
set
|
||||
{
|
||||
if (value == 0)
|
||||
{
|
||||
perm = new byte[permOriginal.Length];
|
||||
Simplex.Noise.permOriginal.CopyTo(perm, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
perm = new byte[512];
|
||||
Random random = new Random(value);
|
||||
random.NextBytes(perm);
|
||||
}
|
||||
}
|
||||
}
|
||||
private static int seed = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 1D simplex noise
|
||||
/// </summary>
|
||||
/// <param name="x"></param>
|
||||
/// <returns></returns>
|
||||
internal static float Generate(float x)
|
||||
{
|
||||
int i0 = FastFloor(x);
|
||||
int i1 = i0 + 1;
|
||||
float x0 = x - i0;
|
||||
float x1 = x0 - 1.0f;
|
||||
|
||||
float n0, n1;
|
||||
|
||||
float t0 = 1.0f - x0 * x0;
|
||||
t0 *= t0;
|
||||
n0 = t0 * t0 * grad(perm[i0 & 0xff], x0);
|
||||
|
||||
float t1 = 1.0f - x1 * x1;
|
||||
t1 *= t1;
|
||||
n1 = t1 * t1 * grad(perm[i1 & 0xff], x1);
|
||||
// The maximum value of this noise is 8*(3/4)^4 = 2.53125
|
||||
// A factor of 0.395 scales to fit exactly within [-1,1]
|
||||
return 0.395f * (n0 + n1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 2D simplex noise
|
||||
/// </summary>
|
||||
/// <param name="x"></param>
|
||||
/// <param name="y"></param>
|
||||
/// <returns></returns>
|
||||
internal static float Generate(float x, float y)
|
||||
{
|
||||
const float F2 = 0.366025403f; // F2 = 0.5*(sqrt(3.0)-1.0)
|
||||
const float G2 = 0.211324865f; // G2 = (3.0-Math.sqrt(3.0))/6.0
|
||||
|
||||
float n0, n1, n2; // Noise contributions from the three corners
|
||||
|
||||
// Skew the input space to determine which simplex cell we're in
|
||||
float s = (x + y) * F2; // Hairy factor for 2D
|
||||
float xs = x + s;
|
||||
float ys = y + s;
|
||||
int i = FastFloor(xs);
|
||||
int j = FastFloor(ys);
|
||||
|
||||
float t = (float)(i + j) * G2;
|
||||
float X0 = i - t; // Unskew the cell origin back to (x,y) space
|
||||
float Y0 = j - t;
|
||||
float x0 = x - X0; // The x,y distances from the cell origin
|
||||
float y0 = y - Y0;
|
||||
|
||||
// For the 2D case, the simplex shape is an equilateral triangle.
|
||||
// Determine which simplex we are in.
|
||||
int i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords
|
||||
if (x0 > y0) { i1 = 1; j1 = 0; } // lower triangle, XY order: (0,0)->(1,0)->(1,1)
|
||||
else { i1 = 0; j1 = 1; } // upper triangle, YX order: (0,0)->(0,1)->(1,1)
|
||||
|
||||
// A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
|
||||
// a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
|
||||
// c = (3-sqrt(3))/6
|
||||
|
||||
float x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords
|
||||
float y1 = y0 - j1 + G2;
|
||||
float x2 = x0 - 1.0f + 2.0f * G2; // Offsets for last corner in (x,y) unskewed coords
|
||||
float y2 = y0 - 1.0f + 2.0f * G2;
|
||||
|
||||
// Wrap the integer indices at 256, to avoid indexing perm[] out of bounds
|
||||
int ii = Mod(i, 256);
|
||||
int jj = Mod(j, 256);
|
||||
|
||||
// Calculate the contribution from the three corners
|
||||
float t0 = 0.5f - x0 * x0 - y0 * y0;
|
||||
if (t0 < 0.0f) n0 = 0.0f;
|
||||
else
|
||||
{
|
||||
t0 *= t0;
|
||||
n0 = t0 * t0 * grad(perm[ii + perm[jj]], x0, y0);
|
||||
}
|
||||
|
||||
float t1 = 0.5f - x1 * x1 - y1 * y1;
|
||||
if (t1 < 0.0f) n1 = 0.0f;
|
||||
else
|
||||
{
|
||||
t1 *= t1;
|
||||
n1 = t1 * t1 * grad(perm[ii + i1 + perm[jj + j1]], x1, y1);
|
||||
}
|
||||
|
||||
float t2 = 0.5f - x2 * x2 - y2 * y2;
|
||||
if (t2 < 0.0f) n2 = 0.0f;
|
||||
else
|
||||
{
|
||||
t2 *= t2;
|
||||
n2 = t2 * t2 * grad(perm[ii + 1 + perm[jj + 1]], x2, y2);
|
||||
}
|
||||
|
||||
// Add contributions from each corner to get the final noise value.
|
||||
// The result is scaled to return values in the interval [-1,1].
|
||||
return 40.0f * (n0 + n1 + n2); // TODO: The scale factor is preliminary!
|
||||
}
|
||||
|
||||
|
||||
internal static float Generate(float x, float y, float z)
|
||||
{
|
||||
// Simple skewing factors for the 3D case
|
||||
const float F3 = 0.333333333f;
|
||||
const float G3 = 0.166666667f;
|
||||
|
||||
float n0, n1, n2, n3; // Noise contributions from the four corners
|
||||
|
||||
// Skew the input space to determine which simplex cell we're in
|
||||
float s = (x + y + z) * F3; // Very nice and simple skew factor for 3D
|
||||
float xs = x + s;
|
||||
float ys = y + s;
|
||||
float zs = z + s;
|
||||
int i = FastFloor(xs);
|
||||
int j = FastFloor(ys);
|
||||
int k = FastFloor(zs);
|
||||
|
||||
float t = (float)(i + j + k) * G3;
|
||||
float X0 = i - t; // Unskew the cell origin back to (x,y,z) space
|
||||
float Y0 = j - t;
|
||||
float Z0 = k - t;
|
||||
float x0 = x - X0; // The x,y,z distances from the cell origin
|
||||
float y0 = y - Y0;
|
||||
float z0 = z - Z0;
|
||||
|
||||
// For the 3D case, the simplex shape is a slightly irregular tetrahedron.
|
||||
// Determine which simplex we are in.
|
||||
int i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords
|
||||
int i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords
|
||||
|
||||
/* This code would benefit from a backport from the GLSL version! */
|
||||
if (x0 >= y0)
|
||||
{
|
||||
if (y0 >= z0)
|
||||
{ i1 = 1; j1 = 0; k1 = 0; i2 = 1; j2 = 1; k2 = 0; } // X Y Z order
|
||||
else if (x0 >= z0) { i1 = 1; j1 = 0; k1 = 0; i2 = 1; j2 = 0; k2 = 1; } // X Z Y order
|
||||
else { i1 = 0; j1 = 0; k1 = 1; i2 = 1; j2 = 0; k2 = 1; } // Z X Y order
|
||||
}
|
||||
else
|
||||
{ // x0<y0
|
||||
if (y0 < z0) { i1 = 0; j1 = 0; k1 = 1; i2 = 0; j2 = 1; k2 = 1; } // Z Y X order
|
||||
else if (x0 < z0) { i1 = 0; j1 = 1; k1 = 0; i2 = 0; j2 = 1; k2 = 1; } // Y Z X order
|
||||
else { i1 = 0; j1 = 1; k1 = 0; i2 = 1; j2 = 1; k2 = 0; } // Y X Z order
|
||||
}
|
||||
|
||||
// A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in (x,y,z),
|
||||
// a step of (0,1,0) in (i,j,k) means a step of (-c,1-c,-c) in (x,y,z), and
|
||||
// a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where
|
||||
// c = 1/6.
|
||||
|
||||
float x1 = x0 - i1 + G3; // Offsets for second corner in (x,y,z) coords
|
||||
float y1 = y0 - j1 + G3;
|
||||
float z1 = z0 - k1 + G3;
|
||||
float x2 = x0 - i2 + 2.0f * G3; // Offsets for third corner in (x,y,z) coords
|
||||
float y2 = y0 - j2 + 2.0f * G3;
|
||||
float z2 = z0 - k2 + 2.0f * G3;
|
||||
float x3 = x0 - 1.0f + 3.0f * G3; // Offsets for last corner in (x,y,z) coords
|
||||
float y3 = y0 - 1.0f + 3.0f * G3;
|
||||
float z3 = z0 - 1.0f + 3.0f * G3;
|
||||
|
||||
// Wrap the integer indices at 256, to avoid indexing perm[] out of bounds
|
||||
int ii = Mod(i, 256);
|
||||
int jj = Mod(j, 256);
|
||||
int kk = Mod(k, 256);
|
||||
|
||||
// Calculate the contribution from the four corners
|
||||
float t0 = 0.6f - x0 * x0 - y0 * y0 - z0 * z0;
|
||||
if (t0 < 0.0f) n0 = 0.0f;
|
||||
else
|
||||
{
|
||||
t0 *= t0;
|
||||
n0 = t0 * t0 * grad(perm[ii + perm[jj + perm[kk]]], x0, y0, z0);
|
||||
}
|
||||
|
||||
float t1 = 0.6f - x1 * x1 - y1 * y1 - z1 * z1;
|
||||
if (t1 < 0.0f) n1 = 0.0f;
|
||||
else
|
||||
{
|
||||
t1 *= t1;
|
||||
n1 = t1 * t1 * grad(perm[ii + i1 + perm[jj + j1 + perm[kk + k1]]], x1, y1, z1);
|
||||
}
|
||||
|
||||
float t2 = 0.6f - x2 * x2 - y2 * y2 - z2 * z2;
|
||||
if (t2 < 0.0f) n2 = 0.0f;
|
||||
else
|
||||
{
|
||||
t2 *= t2;
|
||||
n2 = t2 * t2 * grad(perm[ii + i2 + perm[jj + j2 + perm[kk + k2]]], x2, y2, z2);
|
||||
}
|
||||
|
||||
float t3 = 0.6f - x3 * x3 - y3 * y3 - z3 * z3;
|
||||
if (t3 < 0.0f) n3 = 0.0f;
|
||||
else
|
||||
{
|
||||
t3 *= t3;
|
||||
n3 = t3 * t3 * grad(perm[ii + 1 + perm[jj + 1 + perm[kk + 1]]], x3, y3, z3);
|
||||
}
|
||||
|
||||
// Add contributions from each corner to get the final noise value.
|
||||
// The result is scaled to stay just inside [-1,1]
|
||||
return 32.0f * (n0 + n1 + n2 + n3); // TODO: The scale factor is preliminary!
|
||||
}
|
||||
|
||||
private static byte[] perm;
|
||||
|
||||
private static readonly byte[] permOriginal = new byte[]
|
||||
{
|
||||
151,160,137,91,90,15,
|
||||
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
|
||||
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
|
||||
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
|
||||
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
|
||||
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
|
||||
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
|
||||
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
|
||||
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
|
||||
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
|
||||
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
|
||||
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
|
||||
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,
|
||||
151,160,137,91,90,15,
|
||||
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
|
||||
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
|
||||
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
|
||||
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
|
||||
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
|
||||
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
|
||||
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
|
||||
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
|
||||
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
|
||||
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
|
||||
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
|
||||
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
|
||||
};
|
||||
|
||||
private static int FastFloor(float x)
|
||||
{
|
||||
return (x > 0) ? ((int)x) : (((int)x) - 1);
|
||||
}
|
||||
|
||||
private static int Mod(int x, int m)
|
||||
{
|
||||
int a = x % m;
|
||||
return a < 0 ? a + m : a;
|
||||
}
|
||||
|
||||
private static float grad(int hash, float x)
|
||||
{
|
||||
int h = hash & 15;
|
||||
float grad = 1.0f + (h & 7); // Gradient value 1.0, 2.0, ..., 8.0
|
||||
if ((h & 8) != 0) grad = -grad; // Set a random sign for the gradient
|
||||
return (grad * x); // Multiply the gradient with the distance
|
||||
}
|
||||
|
||||
private static float grad(int hash, float x, float y)
|
||||
{
|
||||
int h = hash & 7; // Convert low 3 bits of hash code
|
||||
float u = h < 4 ? x : y; // into 8 simple gradient directions,
|
||||
float v = h < 4 ? y : x; // and compute the dot product with (x,y).
|
||||
return ((h & 1) != 0 ? -u : u) + ((h & 2) != 0 ? -2.0f * v : 2.0f * v);
|
||||
}
|
||||
|
||||
private static float grad(int hash, float x, float y, float z)
|
||||
{
|
||||
int h = hash & 15; // Convert low 4 bits of hash code into 12 simple
|
||||
float u = h < 8 ? x : y; // gradient directions, and compute dot product.
|
||||
float v = h < 4 ? y : h == 12 || h == 14 ? x : z; // Fix repeats at h = 12 to 15
|
||||
return ((h & 1) != 0 ? -u : u) + ((h & 2) != 0 ? -v : v);
|
||||
}
|
||||
|
||||
private static float grad(int hash, float x, float y, float z, float t)
|
||||
{
|
||||
int h = hash & 31; // Convert low 5 bits of hash code into 32 simple
|
||||
float u = h < 24 ? x : y; // gradient directions, and compute dot product.
|
||||
float v = h < 16 ? y : z;
|
||||
float w = h < 8 ? z : t;
|
||||
return ((h & 1) != 0 ? -u : u) + ((h & 2) != 0 ? -v : v) + ((h & 4) != 0 ? -w : w);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 980b260de9546514d80e3d867a591802
|
||||
timeCreated: 1521731073
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,83 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Photon.Pun.Demo.Procedural
|
||||
{
|
||||
/// <summary>
|
||||
/// Simple Input Handler to control the camera.
|
||||
/// </summary>
|
||||
public class ProceduralController : MonoBehaviour
|
||||
{
|
||||
private Camera cam;
|
||||
|
||||
#region UNITY
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
cam = Camera.main;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use horizontal and vertical axes (by default WASD or the arrow keys) for moving for-, back- or sidewards.
|
||||
/// Use E or Q for 'zooming' in or out.
|
||||
/// Use the left mouse button to decrease a Block's height
|
||||
/// or the right mouse button to increase a Block's height.
|
||||
/// </summary>
|
||||
public void Update()
|
||||
{
|
||||
float h = Input.GetAxisRaw("Horizontal");
|
||||
float v = Input.GetAxisRaw("Vertical");
|
||||
|
||||
if (h >= 0.1f)
|
||||
{
|
||||
cam.transform.position += Vector3.right * 10.0f * Time.deltaTime;
|
||||
}
|
||||
else if (h <= -0.1f)
|
||||
{
|
||||
cam.transform.position += Vector3.left * 10.0f * Time.deltaTime;
|
||||
}
|
||||
|
||||
if (v >= 0.1f)
|
||||
{
|
||||
cam.transform.position += Vector3.forward * 10.0f * Time.deltaTime;
|
||||
}
|
||||
else if (v <= -0.1f)
|
||||
{
|
||||
cam.transform.position += Vector3.back * 10.0f * Time.deltaTime;
|
||||
}
|
||||
|
||||
if (Input.GetKey(KeyCode.Q))
|
||||
{
|
||||
cam.transform.position += Vector3.up * 10.0f * Time.deltaTime;
|
||||
}
|
||||
else if (Input.GetKey(KeyCode.E))
|
||||
{
|
||||
cam.transform.position += Vector3.down * 10.0f * Time.deltaTime;
|
||||
}
|
||||
|
||||
if (Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1))
|
||||
{
|
||||
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
|
||||
RaycastHit hit;
|
||||
|
||||
if (Physics.Raycast(ray, out hit, 100.0f))
|
||||
{
|
||||
Block b = hit.transform.GetComponent<Block>();
|
||||
|
||||
if (b != null)
|
||||
{
|
||||
if (Input.GetMouseButtonDown(0))
|
||||
{
|
||||
WorldGenerator.Instance.DecreaseBlockHeight(b.ClusterId, b.BlockId);
|
||||
}
|
||||
else if (Input.GetMouseButtonDown(1))
|
||||
{
|
||||
WorldGenerator.Instance.IncreaseBlockHeight(b.ClusterId, b.BlockId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 11937abc60ef5bc4796d4b3a3d273f83
|
||||
timeCreated: 1522938410
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,289 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Hashtable = ExitGames.Client.Photon.Hashtable;
|
||||
|
||||
namespace Photon.Pun.Demo.Procedural
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the Size of the World.
|
||||
/// A 'Tiny' world for example will be created with 16 x 16 Blocks.
|
||||
/// </summary>
|
||||
public enum WorldSize
|
||||
{
|
||||
Tiny = 16,
|
||||
Small = 32,
|
||||
Medium = 64,
|
||||
Large = 128
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes the type of the generated world.
|
||||
/// This basically influences the maximum height of a Block.
|
||||
/// </summary>
|
||||
public enum WorldType
|
||||
{
|
||||
Flat = 4,
|
||||
Standard = 8,
|
||||
Mountain = 16
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes how many Blocks are part of one CLuster.
|
||||
/// Having a 'Small' ClusterSize increases the amount of Clusters being created,
|
||||
/// whereat generating a world with a 'Large' ClusterSize doesn't create that many Clusters.
|
||||
/// </summary>
|
||||
public enum ClusterSize
|
||||
{
|
||||
Small = 4,
|
||||
Medium = 16,
|
||||
Large = 64
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The World Generator creates a world based on four options the current MasterClient can set.
|
||||
/// These options are available on the Ingame Control Panel. If those options are confirmed by the current MasterClient,
|
||||
/// they will be stored in the Custom Room Properties to make them available on all clients.
|
||||
/// These options are:
|
||||
/// 1) a numerical Seed to make sure that each client generates the same world and to avoid Random functions and 'network-instantiate' everything
|
||||
/// 2) the World Size to describe how large the generated world should be
|
||||
/// 3) the Cluster Size to describe how many Blocks are inside each Cluster
|
||||
/// 4) the World Type to make the generated world appear in different 'looks'.
|
||||
/// </summary>
|
||||
public class WorldGenerator : MonoBehaviour
|
||||
{
|
||||
public readonly string SeedPropertiesKey = "Seed";
|
||||
public readonly string WorldSizePropertiesKey = "WorldSize";
|
||||
public readonly string ClusterSizePropertiesKey = "ClusterSize";
|
||||
public readonly string WorldTypePropertiesKey = "WorldType";
|
||||
|
||||
private static WorldGenerator instance;
|
||||
|
||||
public static WorldGenerator Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
instance = FindObjectOfType<WorldGenerator>();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
public int Seed { get; set; }
|
||||
|
||||
public WorldSize WorldSize { get; set; }
|
||||
|
||||
public ClusterSize ClusterSize { get; set; }
|
||||
|
||||
public WorldType WorldType { get; set; }
|
||||
|
||||
private Dictionary<int, GameObject> clusterList;
|
||||
|
||||
public Material[] WorldMaterials;
|
||||
|
||||
#region UNITY
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
clusterList = new Dictionary<int, GameObject>();
|
||||
|
||||
WorldSize = WorldSize.Tiny;
|
||||
ClusterSize = ClusterSize.Small;
|
||||
WorldType = WorldType.Standard;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region CLASS FUNCTIONS
|
||||
|
||||
/// <summary>
|
||||
/// Called whenever a client receives a Custom Room Properties update containing all necessary information for creating a world.
|
||||
/// If there is currently a world generation process running, it will be stopped automatically.
|
||||
/// Also if there is a world already existing, it will be destroyed before the new one gets created.
|
||||
/// </summary>
|
||||
public void CreateWorld()
|
||||
{
|
||||
StopAllCoroutines();
|
||||
DestroyWorld();
|
||||
StartCoroutine(GenerateWorld());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys each Block from each Cluster before actually destroying the Cluster itself.
|
||||
/// </summary>
|
||||
private void DestroyWorld()
|
||||
{
|
||||
foreach (GameObject cluster in clusterList.Values)
|
||||
{
|
||||
Cluster clusterComponent = cluster.GetComponent<Cluster>();
|
||||
clusterComponent.DestroyCluster();
|
||||
|
||||
Destroy(cluster);
|
||||
}
|
||||
|
||||
clusterList.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whenever the 'Confirm' button on the Control Panel is clicked by the MasterClient,
|
||||
/// the Room Properties will be updated with the settings he defined.
|
||||
/// </summary>
|
||||
public void ConfirmAndUpdateProperties()
|
||||
{
|
||||
if (!PhotonNetwork.IsMasterClient)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Hashtable properties = new Hashtable
|
||||
{
|
||||
{SeedPropertiesKey, Seed},
|
||||
{WorldSizePropertiesKey, (int) WorldSize},
|
||||
{ClusterSizePropertiesKey, (int) ClusterSize},
|
||||
{WorldTypePropertiesKey, (int) WorldType}
|
||||
};
|
||||
|
||||
PhotonNetwork.CurrentRoom.SetCustomProperties(properties);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decreases the height of a certain Block from a certain Cluster.
|
||||
/// </summary>
|
||||
public void DecreaseBlockHeight(int clusterId, int blockId)
|
||||
{
|
||||
Cluster c = clusterList[clusterId].GetComponent<Cluster>();
|
||||
|
||||
if (c != null)
|
||||
{
|
||||
c.DecreaseBlockHeight(blockId);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increases the height of a certain Block from a certain Cluster.
|
||||
/// </summary>
|
||||
public void IncreaseBlockHeight(int clusterId, int blockId)
|
||||
{
|
||||
Cluster c = clusterList[clusterId].GetComponent<Cluster>();
|
||||
|
||||
if (c != null)
|
||||
{
|
||||
c.IncreaseBlockHeight(blockId);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region COROUTINES
|
||||
|
||||
/// <summary>
|
||||
/// Generates a new world based on the settings made either by the MasterClient on the
|
||||
/// Ingame Control Panel or after receiving the new settings from the Custom Room Properties update.
|
||||
/// </summary>
|
||||
private IEnumerator GenerateWorld()
|
||||
{
|
||||
Debug.Log(string.Format("<b>Procedural Demo</b>: Creating world using Seed: {0}, World Size: {1}, Cluster Size: {2} and World Type: {3}", Seed, WorldSize, ClusterSize, WorldType));
|
||||
|
||||
Simplex.Noise.Seed = Seed;
|
||||
|
||||
int clusterId = 0;
|
||||
|
||||
// Instantiating all necessary clusters at their target position
|
||||
for (int x = 0; x < (int) WorldSize; x += (int) Mathf.Sqrt((int) ClusterSize))
|
||||
{
|
||||
for (int z = 0; z < (int) WorldSize; z += (int) Mathf.Sqrt((int) ClusterSize))
|
||||
{
|
||||
GameObject cluster = new GameObject();
|
||||
cluster.name = "Cluster " + clusterId;
|
||||
|
||||
cluster.transform.SetParent(transform);
|
||||
cluster.transform.position = new Vector3(x, 0.0f, z);
|
||||
|
||||
Cluster clusterComponent = cluster.AddComponent<Cluster>();
|
||||
clusterComponent.ClusterId = clusterId;
|
||||
|
||||
clusterList.Add(clusterId++, cluster);
|
||||
}
|
||||
}
|
||||
|
||||
yield return new WaitForEndOfFrame();
|
||||
|
||||
// Instantiating all necessary blocks as a child of a certain cluster
|
||||
foreach (GameObject cluster in clusterList.Values)
|
||||
{
|
||||
Vector3 clusterPosition = cluster.transform.position;
|
||||
|
||||
int blockId = 0;
|
||||
|
||||
for (int x = 0; x < (int) Mathf.Sqrt((int) ClusterSize); ++x)
|
||||
{
|
||||
for (int z = 0; z < (int) Mathf.Sqrt((int) ClusterSize); ++z)
|
||||
{
|
||||
float noiseValue = Simplex.Noise.CalcPixel2D((int) clusterPosition.x + x, (int) clusterPosition.z + z, 0.02f);
|
||||
|
||||
int height = (int) noiseValue / (int) (256.0f / (float) WorldType);
|
||||
int materialIndex = (int) noiseValue / (int) (256.0f / WorldMaterials.Length);
|
||||
|
||||
GameObject block = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||||
block.name = "Block " + blockId;
|
||||
|
||||
block.transform.SetParent(cluster.transform);
|
||||
block.transform.localScale = new Vector3(1.0f, height, 1.0f);
|
||||
block.transform.position = new Vector3(clusterPosition.x + x, height / 2.0f, clusterPosition.z + z);
|
||||
block.GetComponent<MeshRenderer>().material = WorldMaterials[materialIndex];
|
||||
|
||||
Block blockComponent = block.AddComponent<Block>();
|
||||
blockComponent.BlockId = blockId;
|
||||
blockComponent.ClusterId = cluster.GetComponent<Cluster>().ClusterId;
|
||||
|
||||
cluster.GetComponent<Cluster>().AddBlock(blockId++, block);
|
||||
}
|
||||
}
|
||||
|
||||
yield return new WaitForEndOfFrame();
|
||||
}
|
||||
|
||||
// Applying modifications made to the world when joining the room later or while it is created
|
||||
foreach (DictionaryEntry entry in PhotonNetwork.CurrentRoom.CustomProperties)
|
||||
{
|
||||
if (entry.Value == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string key = entry.Key.ToString();
|
||||
|
||||
if ((key == SeedPropertiesKey) || (key == WorldSizePropertiesKey) || (key == ClusterSizePropertiesKey) || (key == WorldTypePropertiesKey))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int indexOfBlank = key.IndexOf(' ');
|
||||
key = key.Substring(indexOfBlank + 1, (key.Length - (indexOfBlank + 1)));
|
||||
|
||||
int.TryParse(key, out clusterId);
|
||||
|
||||
GameObject cluster;
|
||||
if (clusterList.TryGetValue(clusterId, out cluster))
|
||||
{
|
||||
Cluster c = cluster.GetComponent<Cluster>();
|
||||
|
||||
if (c != null)
|
||||
{
|
||||
Dictionary<int, float> clusterModifications = (Dictionary<int, float>) entry.Value;
|
||||
|
||||
foreach (KeyValuePair<int, float> pair in clusterModifications)
|
||||
{
|
||||
c.SetBlockHeightRemote(pair.Key, pair.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4190307f26497ca49b67855340776e0a
|
||||
timeCreated: 1521730317
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user