Skip to content

Instantly share code, notes, and snippets.

@andrew-raphael-lukasik
Last active September 28, 2023 18:52
Show Gist options
  • Select an option

  • Save andrew-raphael-lukasik/bb5c9036411c2a87b95735604a4c049c to your computer and use it in GitHub Desktop.

Select an option

Save andrew-raphael-lukasik/bb5c9036411c2a87b95735604a4c049c to your computer and use it in GitHub Desktop.
grid system example
// 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