AlleyDemoControl.cs 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. using UnityEngine;
  2. using UnityEngine.Rendering;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. public class AlleyDemoControl : MonoBehaviour
  6. {
  7. [Header("Dimensions")]
  8. public float width = 6f;
  9. public float height = 4f;
  10. public float depth = 24f;
  11. public float speed = 5f;
  12. [Header("Population")]
  13. public int maxBlocks = 200;
  14. public int maxPebbles = 200;
  15. public int maxWires = 50;
  16. public int maxSigns = 150;
  17. [Header("Rendering")]
  18. public Color fogColor = Color.white;
  19. public Material blockMaterial;
  20. public Material pebbleMaterial;
  21. public Material wireMaterial;
  22. public SSFSGenerator ssfsGenerator;
  23. Light sun;
  24. Transform[] leftblocks;
  25. Transform[] rightblocks;
  26. Transform[] pebbles;
  27. Transform[] signs;
  28. List<Transform> wires = new List<Transform>();
  29. Vector3 tunnelMovement { get { return -Vector3.forward * Time.deltaTime * speed * ( 1f + 3f * Mathf.PerlinNoise( Time.time * 0.05f , 111.111f ) ); } }
  30. private void Start()
  31. {
  32. CreateSun();
  33. CreateWall( Vector3.back , new Vector3( 0f , height * 5f , depth ) , new Vector3( width * 5f , 1f , height * 2.5f ) , true );//light wall
  34. CreateWall( Vector3.up , new Vector3( 0f , 0f , depth * 0.5f ) , new Vector3( height * 0.1f , 1f , depth * 0.1f ) );
  35. CreateWall( Vector3.left , new Vector3( width * 0.5f , height * 0.5f , depth * 0.5f ) , new Vector3( height * 0.1f , 1f , depth * 0.1f ) );
  36. CreateWall( Vector3.right , new Vector3( -width * 0.5f , height * 0.5f , depth * 0.5f ) , new Vector3( height * 0.1f , 1f , depth * 0.1f ) );
  37. PopulateBlockList( ref leftblocks , -1f );
  38. PopulateBlockList( ref rightblocks , 1f );
  39. PopulateSigns();
  40. PopulatePebbles();
  41. }
  42. private void Update()
  43. {
  44. UpdateBlocks( ref leftblocks , -1f );
  45. UpdateBlocks( ref rightblocks , 1f );
  46. UpdateDetail();
  47. //fogColor = Color.HSVToRGB( Mathf.PerlinNoise( Time.time * 0.1f , 31.13415f ) , 0.25f , 1f );
  48. Shader.SetGlobalFloat( "_TunnelDemoDepth" , depth );
  49. Shader.SetGlobalColor( "_TunnelDemoFogColor" , fogColor );
  50. sun.color = fogColor;
  51. Vector3 campos = Vector3.up;
  52. campos.x += ( -1f + 2f * Mathf.PerlinNoise( Time.time * 0.01f , 1f ) ) * width * 0.5f;
  53. campos.y += Mathf.PerlinNoise( 2f , Time.time * 0.02f );
  54. campos.z += Mathf.PerlinNoise( Time.time * 0.03f , 3f );
  55. transform.position = campos;
  56. transform.rotation = Quaternion.Euler( Mathf.PerlinNoise( 1.11f , Time.time * 0.01f ) * 10f - 10f , Mathf.PerlinNoise( Time.time * 0.02f , 0.5f ) * 5f , 12f * Mathf.Sin( Time.time * 0.01f ) );
  57. sun.transform.forward = new Vector3( -0.5f + Mathf.PerlinNoise( 11.111f , Time.time * 0.01f ) , -1f , -1f ).normalized;
  58. }
  59. private void CreateSun ()
  60. {
  61. GameObject o = new GameObject( "Sun" );
  62. o.hideFlags = HideFlags.HideInHierarchy;
  63. sun = o.AddComponent<Light>();
  64. sun.type = LightType.Directional;
  65. sun.transform.rotation = Quaternion.Euler( 35f , 170f , 0f );
  66. sun.intensity = 1.2f;
  67. sun.shadows = LightShadows.Soft;
  68. sun.shadowStrength = 0.95f;
  69. sun.shadowResolution = LightShadowResolution.VeryHigh;
  70. sun.shadowBias = 0.025f;
  71. sun.shadowNormalBias = 0f;
  72. sun.shadowNearPlane = 5f;
  73. }
  74. private void RandColor( ref Transform block , float minValue = 0.2f , float valueRange = 0.4f )
  75. {
  76. MaterialPropertyBlock matprops = new MaterialPropertyBlock();
  77. matprops.SetColor( "_Color" , Color.HSVToRGB( Random.value , Random.value * 0.3f , Random.value * valueRange + minValue ) );
  78. block.GetComponent<MeshRenderer>().SetPropertyBlock( matprops );
  79. }
  80. void CreateWall( Vector3 up , Vector3 pos , Vector3 scl , bool noshadow = false )
  81. {
  82. Transform w = GameObject.CreatePrimitive( PrimitiveType.Plane ).transform;
  83. w.hideFlags = HideFlags.HideInHierarchy;
  84. MeshRenderer mr = w.GetComponent<MeshRenderer>();
  85. mr.shadowCastingMode = noshadow ? ShadowCastingMode.Off : ShadowCastingMode.TwoSided;
  86. mr.sharedMaterial = blockMaterial;
  87. w.up = up;
  88. w.position = pos;
  89. w.localScale = scl;
  90. }
  91. void PopulateBlockList( ref Transform[] blocks , float side )
  92. {
  93. blocks = new Transform[ maxBlocks ];
  94. for ( int i = 0 ; i < maxBlocks ; i++ )
  95. {
  96. blocks[ i ] = GameObject.CreatePrimitive( PrimitiveType.Cube ).transform;
  97. blocks[ i ].hideFlags = HideFlags.HideInHierarchy;
  98. blocks[ i ].GetComponent<MeshRenderer>().sharedMaterial = blockMaterial;
  99. bool bridge = Random.value > 0.98f;
  100. ScaleBlock( ref blocks[ i ] , bridge );
  101. PositionBlock( ref blocks[ i ] , side * width * 0.5f , bridge );
  102. Vector3 p = blocks[i].position;
  103. p.z = Random.value * depth;
  104. blocks[ i ].position = p;
  105. RandColor( ref blocks[ i ] );
  106. }
  107. }
  108. void PopulatePebbles()
  109. {
  110. pebbles = new Transform[ maxPebbles ];
  111. for ( int i = 0 ; i < maxPebbles ; i++ )
  112. {
  113. pebbles[ i ] = GameObject.CreatePrimitive( PrimitiveType.Cube ).transform;
  114. pebbles[ i ].hideFlags = HideFlags.HideInHierarchy;
  115. MeshRenderer mr = pebbles[ i ].GetComponent<MeshRenderer>();
  116. mr.sharedMaterial = pebbleMaterial;
  117. mr.shadowCastingMode = ShadowCastingMode.Off;//we don't need the tiny pebbles on the floor to cast shadows
  118. NewPebblePos( ref pebbles[ i ] , true );
  119. RandColor( ref pebbles[ i ] , 0.25f , 0.5f );
  120. }
  121. }
  122. private void ScaleBlock( ref Transform block , bool bridge )
  123. {
  124. Vector3 s = new Vector3( Random.value * 2f + 0.2f , Random.value * height + 0.5f , Random.value * depth * 0.1f + 0.25f);
  125. if ( bridge ) { s.x = width; s.y = 1f; s.z = Random.value * 3f + 1f; }
  126. block.localScale = s;
  127. }
  128. private void PositionBlock(ref Transform block , float xpos , bool bridge )
  129. {
  130. Vector3 p = new Vector3( xpos , Random.value * height , depth );
  131. if ( bridge ) { p.x = 0f; p.y = Mathf.Max( p.y , 3f ); }
  132. block.position = p;
  133. }
  134. private void TripBlock( ref Transform block , float side )
  135. {
  136. bool bridge = Random.value > 0.98f;
  137. ScaleBlock( ref block , bridge );
  138. PositionBlock( ref block , side * width * 0.5f , bridge );
  139. if ( block.position.y > 3f && Random.value > 0.8f && wires.Count < maxWires )
  140. CreateWire( block.position , -Mathf.Sign( block.position.x ) * Vector3.right * width + Vector3.up * Random.value );
  141. }
  142. private void PopulateSigns ()
  143. {
  144. signs = new Transform[ maxSigns ];
  145. if ( ssfsGenerator == null ) return;
  146. for ( int i = 0 ; i < maxSigns ; i ++ )
  147. {
  148. GameObject o = GameObject.CreatePrimitive( PrimitiveType.Quad );
  149. o.hideFlags = HideFlags.HideInHierarchy;
  150. o.transform.localScale = Vector3.one * ( 2f * Random.value + 1f );
  151. Vector3 p = NewSignPosition();
  152. o.transform.position = p;
  153. o.transform.forward = Random.value > 0.8f ? Vector3.forward : Mathf.Sign( p.x ) * Vector3.right;
  154. //Use an SSFSGenerator to generate a random sign material:
  155. MeshRenderer mr = o.GetComponent<MeshRenderer>();
  156. mr.sharedMaterial = ssfsGenerator.GenerateMaterial();
  157. mr.shadowCastingMode = ShadowCastingMode.Off;
  158. Light l = o.AddComponent<Light>();
  159. l.color = Color.HSVToRGB( Random.value , Random.value * 0.5f + 0.5f , 1f );
  160. l.range = 2f;
  161. signs[ i ] = o.transform;
  162. }
  163. }
  164. private Vector3 NewSignPosition ( bool atEnd = false )
  165. {
  166. Vector3 pos = Vector3.zero;
  167. Vector3 wallpos = new Vector3( 0f , ( Random.value * 0.8f + 0.1f ) * height , atEnd ? depth - 5f : Random.value * depth );
  168. RaycastHit h;
  169. Ray r = new Ray( wallpos , Random.value > 0.5f ? Vector3.right : Vector3.left );
  170. if(Physics.Raycast(r,out h))
  171. {
  172. pos = h.point + h.normal * ( Random.value + 0.1f );
  173. }
  174. return pos;
  175. }
  176. private void UpdateBlocks( ref Transform[] blocks , float side )
  177. {
  178. for ( int i = 0 ; i < maxBlocks ; i++ )
  179. {
  180. blocks[ i ].position += tunnelMovement;
  181. if ( blocks[ i ].position.z < -blocks[ i ].localScale.z )
  182. TripBlock( ref blocks[ i ] , side );
  183. }
  184. }
  185. private void NewPebblePos( ref Transform pebble , bool randomDepth = false)
  186. {
  187. Vector3 p = new Vector3( width * ( Random.value - 0.5f ) , 0f , randomDepth ? Random.value * depth : depth );
  188. Vector3 s = Random.onUnitSphere * 0.1f + Vector3.one * 0.2f;
  189. s.y *= 0.5f;
  190. pebble.position = p;
  191. pebble.localScale = s;
  192. }
  193. private void UpdateDetail ()
  194. {
  195. for ( int i = wires.Count - 1 ; i > -1 ; i-- )
  196. {
  197. wires[ i ].position += tunnelMovement;
  198. if ( wires[ i ].position.z < -1f )
  199. {
  200. Destroy( wires[ i ].gameObject );
  201. wires.RemoveAt( i );
  202. }
  203. }
  204. for ( int i = 0 ; i < maxSigns ; i++ )
  205. {
  206. if ( signs[ i ] != null )
  207. {
  208. signs[ i ].position += tunnelMovement;
  209. if ( signs[ i ].position.z < -1f )
  210. {
  211. signs[ i ].position = NewSignPosition( true );
  212. signs[ i ].forward = Random.value > 0.8f ? Vector3.forward : Mathf.Sign( signs[ i ].position.x ) * Vector3.right;
  213. Material m = signs[ i ].GetComponent<MeshRenderer>().sharedMaterial;
  214. ssfsGenerator.GenerateMaterial( ref m );
  215. Light l = signs[ i ].GetComponent<Light>();
  216. if ( l != null )
  217. {
  218. l.color = Color.HSVToRGB( Random.value , Random.value * 0.5f + 0.5f , 1f );
  219. l.range = 2f;
  220. }
  221. }
  222. }
  223. }
  224. for ( int i = 0 ; i < maxPebbles ; i++ )
  225. {
  226. pebbles[ i ].position += tunnelMovement;
  227. if ( pebbles[ i ].position.z < -1f )
  228. NewPebblePos( ref pebbles[ i ] );
  229. }
  230. }
  231. public int maxWireVerts = 7;
  232. private void CreateWire(Vector3 p1 , Vector3 p2)
  233. {
  234. GameObject o = new GameObject();
  235. o.hideFlags = HideFlags.HideInHierarchy;
  236. o.transform.position = p1;
  237. LineRenderer l = o.AddComponent<LineRenderer>();
  238. l.material = wireMaterial;
  239. Vector3[] verts = new Vector3[ maxWireVerts ];
  240. for ( int i = 0 ; i < maxWireVerts ; i++ )
  241. {
  242. float p = ( float )i / ( ( float )maxWireVerts - 1f );
  243. verts[ i ] = Vector3.Lerp( Vector3.zero , p2 , p );
  244. verts[ i ] -= Vector3.up * p2.magnitude * 0.1f * ( 1f - Mathf.Pow( 2f * p - 1f , 2f ) );
  245. }
  246. l.useWorldSpace = false;
  247. l.widthMultiplier = ( Random.value + 0.1f ) * 0.1f;
  248. l.positionCount = maxWireVerts;
  249. l.SetPositions( verts );
  250. wires.Add( o.transform );
  251. }
  252. }