Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by Klusimo · Nov 01, 2020 at 09:31 AM · gridprocedural meshprocedural generationgrid based gamedots

DOTS Grid-based generation question.

Hello, i am currently working on a grid-based (just code, not object) dots procedural generation project and i need some help. I want to have a system where the game "activates" grid cells(from now on "chunks") around players and then generates them. I already have the generation done, but i need some help with the chosing what chunk it is. I dont know if cycling through the entire grid is a good idea and i want it to do this:


  1. Know which grid cells to activate (the coordinates of the chunk)

  2. Keep track which chunks are already activated so it doesnt activate those

  3. Deactivate chunks that are far away


So as i said i already have code for genereation that will activate with the activation of each chunk and i can easily add code to deactivating etc. but i dont know how to do the system that decides what is active or not and what to activate or deactivate. I thought of using native containers to store the data which chunks are active and add/remove at run time. or maybe an simple array that just changes the coordinates that are active when you move, without actually making active chunks special. Any help, tips or ideas are welcomed. Also sorry for any grammatic errors.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by andrew-lukasik · Nov 03, 2020 at 02:03 AM

players moving around, loaded cells are highlighted: players moving around

load distance: load distance

point to cell index, cell index to point conversion: cell index-origin conversions


Here is a code that shows general idea how you can do this (not dots-specific). It uses my NativeGrid package to simplify index finding

(you may want to install it (see Installation readme notes) OR deep copy this specific function (more work imo)).


 using System.Collections.Generic;
 using UnityEngine;
 using Unity.Mathematics;
 
 [ExecuteAlways]
 public class GridTester : MonoBehaviour
 {
     [SerializeField] float2 _gridWorldSize = new float2{ x=10 , y=10 };
     [SerializeField] int2 _gridResolution = new int2{ x=16 , y=16 };
     [SerializeField] Transform[] _players = new Transform[0];
     [SerializeField][Range(0,10)] int _loadDistance = 1;
     
     HashSet<int2> _active = new HashSet<int2>();// cells we want to be loaded
     HashSet<int2> _loaded = new HashSet<int2>();// cells that are loaded
     HashSet<int2> _redundant = new HashSet<int2>();// cells to unload
 
     void Update ()
     {
         // create list of active cells:
         _active.Clear();
         foreach( Transform player in _players )
         {
             int2 playerI2 = PointToIndex2d( player.position );
             for( int oy=-_loadDistance ; oy<=_loadDistance ; oy++ )
             for( int ox=-_loadDistance ; ox<=_loadDistance ; ox++ )
             {
                 int2 i2 = playerI2 + new int2{ x=ox , y=oy };
                 if( i2.x>=0 && i2.x<_gridResolution.x && i2.y>=0 && i2.y<_gridResolution.y )// bounds checks
                     _active.Add( i2 );
             }
         }
 
         // load active cells
         foreach( int2 i2 in _active )
         {
             if( !_loaded.Contains(i2) )
             {
                 /*
                     insert code that loads cell's content here
                 */
                 _loaded.Add(i2);
             }
         }
         
         // unload redundant cells:
         _redundant.Clear();
         foreach( int2 i2 in _loaded )
             if( !_active.Contains(i2) )
                 _redundant.Add(i2);
         foreach( int2 i2 in _redundant )
         {
             /*
                 insert code that unloads cell's content here
             */
             _loaded.Remove(i2);
         }
     }
 
     #if UNITY_EDITOR
     void OnDrawGizmos ()
     {
         float3 cellSize = new float3{
             x = _gridWorldSize.x / _gridResolution.x ,
             y = 0f ,
             z = _gridWorldSize.y / _gridResolution.y
         };
 
         // draw grid:
         Gizmos.color = new Color{ r=1 , g=1 , b=1 , a=0.2f };
         for( int Y=0 ; Y<_gridResolution.y ; Y++ )
         for( int X=0 ; X<_gridResolution.x ; X++ )
         {
             float3 cellOriginLocal = new float3{
                 x = X * cellSize.x ,
                 y = 0f ,
                 z = Y * cellSize.z
             };
             float3 cellCenterLocal = cellOriginLocal + cellSize*0.5f;
             Gizmos.DrawWireCube( cellCenterLocal , cellSize );
         }
         
         // draw loaded cells:
         Gizmos.color = new Color{ r=0 , g=1 , b=1 , a=0.2f };
         foreach( int2 i2 in _loaded )
         {
             float3 cellOriginLocal = new float3{
                 x = i2.x * cellSize.x ,
                 y = 0f ,
                 z = i2.y * cellSize.z
             };
             float3 cellCenterLocal = cellOriginLocal + cellSize*0.5f;
             Gizmos.DrawCube( cellCenterLocal , cellSize );
         }
 
         // draw player positions:
         Gizmos.color = Color.cyan;
         float sphereRadius = math.min(cellSize.x,cellSize.z)*0.25f;
         foreach( Transform player in _players )
         {
             float3 pos = player.position;
             Gizmos.DrawLine( pos , new float3{ x=pos.x , y=0 , z=pos.z } );
             Gizmos.DrawSphere( pos , sphereRadius );
         }
 
         // highlight grid cell under mouse pointer:
         int2 i2Highlighted = int2.zero;
         {
             Ray ray = UnityEditor.HandleUtility.GUIPointToWorldRay( Event.current.mousePosition );
             new Plane( inNormal:transform.up , inPoint:transform.position ).Raycast( ray , out float dist );
             float3 hit = ray.origin + ray.direction*dist;
 
             Gizmos.color = new Color{ r=1 , g=1 , b=1 , a=0.35f };
             Gizmos.DrawWireSphere( hit , sphereRadius );
 
             int2 i2 = PointToIndex2d( hit );
             float3 cellOriginLocal = new float3{
                 x = i2.x * cellSize.x ,
                 y = 0f ,
                 z = i2.y * cellSize.z
             };
             float3 cellCenterLocal = cellOriginLocal + cellSize*0.5f;
             Gizmos.DrawCube( cellCenterLocal , cellSize );
             Gizmos.DrawLine( hit , cellOriginLocal );
 
             i2Highlighted = i2;
         }
 
         // any i2 to cell origin, conversion example:
         {
             float3 cellOriginLocal = Index2dToPoint( i2Highlighted );
             Gizmos.color = Color.magenta;
             Gizmos.DrawWireSphere( cellOriginLocal , sphereRadius*0.25f );
         }
 
     }
     #endif
 
     /// <returns> Cell index2d </returns>
     public int2 PointToIndex2d ( FLOAT3 worldPoint )
     {
         return NativeGrid.PointToIndex2d(
             // point:      worldPoint.XZ()-((FLOAT3)transform.position).XZ() ,
             point:      worldPoint.XZ() ,
             worldSize:  _gridWorldSize ,
             width:      _gridResolution.x ,
             height:     _gridResolution.y
         );
     }
 
     /// <returns> Cell origin point </returns>
     public float3 Index2dToPoint ( INT2 i2 )
     {
         float2 point2d = NativeGrid.Index2dToPoint( i2:i2 , step:_gridWorldSize/_gridResolution );
         return new float3{ x=point2d.x , y=0 , z=point2d.y };
     }
 
 }

Comment
Add comment · Show 8 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Klusimo · Nov 03, 2020 at 08:15 AM 0
Share

Thank you! Its close to what i thought it´ll be. I´ll look into it.

avatar image Klusimo · Nov 03, 2020 at 08:54 AM 0
Share

Oh also, gridResolution is basically grid cell´s lenght, right?

avatar image andrew-lukasik Klusimo · Nov 03, 2020 at 10:18 AM 0
Share

Yes. Number of columns and rows in a grid

avatar image andrew-lukasik · Nov 03, 2020 at 10:57 AM 0
Share

Btw.: You can replace HashSet<int2> with List<int2> if ever needed. Just know I'm using hashset because it's Contains() method is O(1) fast where lists can be O(n).

avatar image andrew-lukasik · Nov 03, 2020 at 11:07 AM 0
Share

In places where int2 i2 comes up it means cell's 2D grid coordinates packed as a pair of integers with i2.x and i2.y coordinates.

avatar image Klusimo andrew-lukasik · Nov 04, 2020 at 02:17 PM 0
Share

Thanks! I am working on it, i hope the result will be like yours.

avatar image andrew-lukasik Klusimo · Nov 04, 2020 at 03:59 PM 0
Share

Anticipating future need I added Index2dToPoint(i2) method so you'll know how to find cell origin in 3d space (to place meshes and and objects associated with this cell, for example)

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

219 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How can i make the Unity2d grid use rounded numbers? 1 Answer

Procedural mesh with texture atlas, how to get rid of material artifacts? 0 Answers

How do you find adjacent tiles of the same type in grid array [x,y].type == [x+1,y].type 0 Answers

Problem making a grid for a TBS game 2 Answers

grid checking for objects 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges