Search Unity

Procedural 3D-Tilemap looking for some Gameplay!

Discussion in 'Works In Progress - Archive' started by misterPantoni, Jan 22, 2014.

  1. misterPantoni

    misterPantoni

    Joined:
    Feb 7, 2013
    Posts:
    44
    Hey there!

    The last weekend i was trying some serialization Stuff in Unity and therefore put together a little 3D-Tilemap sample. I kind of liked it, refined the visuals a bit and built a balloon and a player, to explore the maps. So now i am thinkin: "This could somehow be a game!" - but i don't really know how exactly. Don't get me wrong, i got tons of ideas what to do with it, but none which (in my eyes) is really great and worth the efford of actually putting it to life.

    So - when you look at this, what kind of gameplay do you see? What would YOU do with it? I'm thankful for any input, perhaps there are some ideas that will get me thinking in directions i haven't thought before...

    Here is some demo-Webplayer, basically it's just some "islands" floating in space, all provedurally generated, that you can explore and jump around on :)

    WEBPLAYER LINK




     

    Attached Files:

    Last edited: Jan 22, 2014
  2. TheRaider

    TheRaider

    Joined:
    Dec 5, 2010
    Posts:
    2,250
    each tile is an individual object I assume?
     
  3. misterPantoni

    misterPantoni

    Joined:
    Feb 7, 2013
    Posts:
    44
    It is, this far away from perfect but Unity does a great job in dynamic batching - it runs well on my android device, always under 50 drawcalls. If you were asking because of performance issues. :)
     
  4. TheRaider

    TheRaider

    Joined:
    Dec 5, 2010
    Posts:
    2,250
    How many objects is that?

    I am curious cause it looks cool and I have always wanted to do something like that by remaking the mesh is too much for my head lol.
     
  5. misterPantoni

    misterPantoni

    Joined:
    Feb 7, 2013
    Posts:
    44
    in total i generate LOTS of meshes/objects right now - the demo is 80 islands, each between 10 and 40 tiles width/depth. This will be over 50k objects in scene... :eek: If i will make a game out of it, i will only instantiate some islands around the player and build the new ones if they get in range of the player as well as optimizing it in many other ways. For example right now each tile has its own material, but a not very efficient uv layout - this can be changed to get all tile textures into one, so in theory i could render the terrain with just one drawcall :)

    visible Objects on screen are around 250-500. I use no lighting (shader is a custom-light shader), so they all get batched by dynamic batching.
     
  6. TheRaider

    TheRaider

    Joined:
    Dec 5, 2010
    Posts:
    2,250
    Do you know where I can get any info on custom shaders like that? I would love to give it a try.
     
  7. misterPantoni

    misterPantoni

    Joined:
    Feb 7, 2013
    Posts:
    44
    I can give you some info :) Basically it's just a simple Shader which has 8 float4 "light" variables. In my scene i have a script which checks the nearest 8 ights (which are basically just Transforms) and passes them to the shader (Shader.SetVector). In the shader i check the distance of the vertice to each light, and if it is near, i lighten the output color. I can't access the project right now, i will give you some code examples if i can. But i'm not sure that this is a good method, i might have to look at this again if i continue working on this.
     
  8. TheRaider

    TheRaider

    Joined:
    Dec 5, 2010
    Posts:
    2,250
    I would love an example because I have literally zero experience with shaders lol :)
     
  9. NomadKing

    NomadKing

    Joined:
    Feb 11, 2010
    Posts:
    1,461
    Looks interesting :)

    The disproportionate Player and world details (trees, house etc) almost remind me of world map you'd get in an old for an RPG / ARPG style game.
     
  10. landon912

    landon912

    Joined:
    Nov 8, 2011
    Posts:
    1,579
    I was in the same situation as you the other day.

    I recently combined all my tiles into a chunking system. It was much easier than I expected.

    What I did was procedurally generate the tile mesh, and stored it as a Mesh in a script. Then you just combine all the meshes into sizable chunks, and store any scripts that were previously on the objects in a array.

    If you just make a "chunk" gameObject and generate a array of scripts that represent the objects. You can within the scripts generate the mesh at the correct place, and assign the UV cords on a texture atlas.Then using a CombineInstance you can combine all meshes into one on the chunkScript.

    Of course it's more difficult as that, but it should point you in the general direction if your interested. Make sure to plan everything out. If you need the blocks to be changeable you need to design the system around that. (I stored a local copy of the mesh in the tileScript, and when something changes it changes the mesh on that tile, and rebuilds the mesh using all the other local copies.)

    PS: Change the link to "http://" instead of "https://"
     
    Last edited: Jan 23, 2014
  11. snowconesolid

    snowconesolid

    Joined:
    Dec 9, 2011
    Posts:
    868
    This is super cool. I also enjoyed the webplayer. It looks great with a lot of different space island things to explore.
    This definitely has a lot of potential to be a good game. Lots of different possibilities for gameplay too. I think make any kind of gameplay you feel would be best. Personally, I think Mario Galaxy mixed with survival elements would make for a pretty cool and unique gameplay for this. But that might be hard to achieve or to do right.

    Best of luck on this man. Its off to a great start and if you keep working on it I feel like it will turn out as a great game. :)
     
  12. misterPantoni

    misterPantoni

    Joined:
    Feb 7, 2013
    Posts:
    44
    @Landon: I dont think i got every part of what you where trying to tell me, but i think i understood what you wanted to tell me in general :D

    @snowconesolid: Thanks! Nice to hear that you liked it! I didn't come to a decision on what game to do, so i'm working on refining some general features on the procedural islands and think about what i could do with those. My latest ideas go somehow in the survival/exploration area, i will post some updates here if i got anything new.

    @theRaider: Here is my shader, i started to learn a bit about shaders short time ago, so this may not be perfect, but it works for now :) I'm using this custom light approach because of unity lights stop dynamic batching, even if all objects use an unlit shader. In this version i only use max of 4 lights, no i'm using 8. It's a pitty you can't pass arrays into a shader btw...

    Code (csharp):
    1. Shader "Custom/CustomPointLight"{
    2.     Properties{
    3.         _Color ("Color", Color) =(1.0,1.0,1.0,1.0)
    4.         _MainTex("Texture", 2D) = "white" {}
    5.        
    6.         _LightRoundDist("LightRoundDist",float) = 1.0
    7.        
    8.         _RimColor("Rim Color",Color) = (1.0,1.0,1.0,1.0)
    9.         _RimPower("Rim Power",range(0.0,10.0)) = 3.0
    10.     }
    11.     SubShader{
    12.         Pass{
    13.         Tags{   "LightMode" = "Always" 
    14.        
    15.         }
    16.             CGPROGRAM
    17.            
    18.             #pragma vertex vert
    19.             #pragma fragment frag
    20.            
    21.             uniform float4 _Color;
    22.             uniform float _LightRoundDist;
    23.            
    24.             uniform sampler2D _MainTex;
    25.             uniform float4 _MainTex_ST;
    26.              
    27.             uniform float4 light0;
    28.             uniform float4 light1;
    29.             uniform float4 light2;
    30.             uniform float4 light3;
    31.              
    32.             //Rim
    33.             uniform float4 _RimColor;
    34.             uniform float _RimPower;
    35.            
    36.             struct vertexInput{
    37.                 float4 vertex : POSITION; //Grab Position of Mesh Vertex
    38.                 float4 texcoord : TEXCOORD0;
    39.                 float3 normal : NORMAL;
    40.             };
    41.             struct vertexOutput{
    42.                 float4 pos: SV_POSITION; // POSITION würde auch gehen, aber neuer (DX11) ist SV_Position
    43.                 float3 worldPosition : TEXCOORD1;
    44.                 float distColorMultiplier;
    45.                 float3 normalDir : TEXCOORD2;
    46.                 float4 tex : TEXCOORD0;
    47.             };
    48.            
    49.             //vertex function
    50.             vertexOutput vert(vertexInput v){
    51.                 vertexOutput o;
    52.                 o.pos = mul(UNITY_MATRIX_MVP,v.vertex); //convert position in Unity-Matrix. Multiplies Matrix to unity Matrix              
    53.            
    54.                 float lightValue = 0;
    55.                
    56.                 //Calculation of Color based on World pos              
    57.                 float4 worldPos = mul(_Object2World,v.vertex);
    58.                 o.worldPosition = worldPos.xyz;
    59.                
    60.                 worldPos = float4(
    61.                
    62.                 round(worldPos.x / _LightRoundDist)*_LightRoundDist,
    63.                 round(worldPos.y / _LightRoundDist)*_LightRoundDist,
    64.                 round(worldPos.z / _LightRoundDist)*_LightRoundDist,
    65.                 0);
    66.                
    67.                 //float dist =  1.0/ unity_4LightAtten0[0];
    68.                 float dist = 5;
    69.                    
    70.                 for(int i = 0;i<4;i++){
    71.                                
    72.                     //float4 lightPosition = float4(unity_4LightPosX0[0], unity_4LightPosY0[0], unity_4LightPosZ0[0], 1.0);
    73.                     float4 lightPosition = light0;
    74.                     if(i == 1){
    75.                         lightPosition = light1;
    76.                     }else if(i== 2){
    77.                         lightPosition = light2;
    78.                     }else if(i== 3){
    79.                         lightPosition = light3;
    80.                     }
    81.                    
    82.                     if(lightPosition.w != 0){
    83.                         //dist = 4;
    84.                         float worldDistance = clamp(distance(worldPos,lightPosition),0,dist + lightPosition.w) / (dist + lightPosition.w);
    85.                        
    86.                         if((1- worldDistance) >= lightValue){
    87.                             lightValue = (1- worldDistance);
    88.                         }
    89.                     }
    90.                 }
    91.                
    92.                 o.distColorMultiplier = lightValue;
    93.                                    
    94.                 //Texture
    95.                 o.tex = v.texcoord;
    96.                
    97.                 //rim
    98.                 o.normalDir = normalize(mul(float4(v.normal,0.0), _World2Object ).xyz);
    99.                
    100.                 return o;
    101.             }
    102.            
    103.             //fragment function
    104.             float4 frag(vertexOutput i) :COLOR{
    105.                
    106.                 float4 _AmbientLight = UNITY_LIGHTMODEL_AMBIENT * 2;
    107.                 float4 combinedLight = clamp(_AmbientLight + i.distColorMultiplier,0,1);
    108.                
    109.                 //Texture
    110.                 //unwrap Texture:
    111.                 float4 tex = tex2D(_MainTex,i.tex.xy * _MainTex_ST.xy + _MainTex_ST.zw);
    112.                
    113.                 //Rim
    114.                 float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.worldPosition.xyz);
    115.                 float rim = 1 - saturate(dot(normalize(viewDirection),i.normalDir));
    116.                 float3 rimLighting = _RimColor.xyz * pow(rim, _RimPower);
    117.                
    118.                 return float4(tex.xyz * combinedLight.xyz *_Color.xyz + (rimLighting), 1.0);
    119.                
    120.             }
    121.            
    122.            
    123.             ENDCG
    124.         }
    125.     }
    126.    
    127.     //Fallback commented out for Development
    128.     //Fallback "Diffuse"
    129. }
     
    Last edited: Jan 23, 2014
  13. NutellaDaddy

    NutellaDaddy

    Joined:
    Oct 22, 2013
    Posts:
    288
    I could use this for tons of things and this looks really good for a web player demo.
     
  14. SunnyChow

    SunnyChow

    Joined:
    Jun 6, 2013
    Posts:
    360
    I like the art style. It's good to know it can run in mobile device.

    this is what i think about it. Balloon represent exploration and these floating island procedurally generated. Therefore I will expected it's a large world and the player has to explore all of it. So the question is "why the player has to travel from an island to an island?".