Last active
September 28, 2023 18:52
-
-
Save andrew-raphael-lukasik/bb5c9036411c2a87b95735604a4c049c to your computer and use it in GitHub Desktop.
grid system example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // src* = https://gist.github.com/andrew-raphael-lukasik/bb5c9036411c2a87b95735604a4c049c | |
| 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 }; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment


