764 lines
25 KiB
C#
764 lines
25 KiB
C#
using Sirenix.OdinInspector;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.SceneManagement;
|
|
|
|
namespace Beyond {
|
|
public class ObjectGrid<T, G> : MonoBehaviour, IJSONSerializable where T : ISpawnable, IGuidable, IPositionable
|
|
where G : MonoBehaviour
|
|
{
|
|
#region ToOverload
|
|
protected virtual bool UseFrustum { get => false; }
|
|
protected virtual bool DespawnOnStart { get => false; }
|
|
|
|
#endregion
|
|
|
|
ISpawnable m_spawnable;
|
|
|
|
protected struct GridPos
|
|
{
|
|
public GridPos(int x, int z)
|
|
{
|
|
this.x = x; this.z = z;
|
|
}
|
|
public int x, z;
|
|
}
|
|
[Serializable]
|
|
public class Cell
|
|
{
|
|
public Cell(bool wasActive)
|
|
{
|
|
guidToItem = new Dictionary<Guid, T>();
|
|
this.wasActive = wasActive;
|
|
}
|
|
public Dictionary<Guid, T> guidToItem;
|
|
public bool wasActive;
|
|
}
|
|
|
|
[SerializeField] private Camera m_camera;
|
|
|
|
// public class Cell : Dictionary<Guid, T> { }
|
|
protected Cell[,] m_ItemGrid;
|
|
protected Dictionary<Guid, Cell> m_guidToCell;
|
|
protected Dictionary<Guid, T> m_guidToItem;
|
|
|
|
// Start is called before the first frame update
|
|
[BoxGroup("Grid Size")]
|
|
[SerializeField] private bool m_useManualSize = true;
|
|
[BoxGroup("Grid Size")]
|
|
[SerializeField]
|
|
protected Vector3 m_minPos = new Vector3(-1024, 0, -1536), m_maxPos = new Vector3(1024,0,1536);
|
|
|
|
private Bounds m_cellBounds;
|
|
private int m_lastFrameUpdate = -1;
|
|
|
|
public enum CellSize {_8x8 = 8, _16x16 = 16, _32x32 = 32, _64x64 }
|
|
|
|
[SerializeField] protected CellSize Size = CellSize._32x32;
|
|
protected float m_size;
|
|
protected float m_hsize;
|
|
public float m_visibilityRange = 30f;
|
|
public float m_checkTimeDelta = 0.1f;
|
|
public bool m_visualize = false;
|
|
private float m_timer = 0f;
|
|
//public Camera m_camera;
|
|
protected Vector3 m_playerPos; //cached player position
|
|
protected int m_xCount, m_zCount;
|
|
private bool m_firstFrame = true;
|
|
private int m_loopRange;
|
|
//private Queue<Cell> m_SpawnQueue;
|
|
|
|
private Vector3 TerrainCenter(Terrain t)
|
|
{
|
|
return t.transform.position + t.terrainData.size * 0.5f;
|
|
}
|
|
|
|
private Vector3 CellPosition(int x, int z)
|
|
{
|
|
Vector3 pos;
|
|
pos.y = 0f;
|
|
pos.x = ((float)x+.5f) * m_size + m_minPos.x;
|
|
pos.z = ((float)z+.5f) * m_size + m_minPos.z;
|
|
return pos;
|
|
}
|
|
|
|
[Button]
|
|
protected virtual void PrepareGrid()
|
|
{
|
|
m_size = (float) Size;
|
|
m_loopRange = (int) ((m_visibilityRange / m_size) + 0.5f);
|
|
if (!m_useManualSize)
|
|
{
|
|
m_minPos.x = float.MaxValue;
|
|
m_maxPos.x = -float.MaxValue;
|
|
m_minPos.z = float.MaxValue;
|
|
m_maxPos.z = -float.MaxValue;
|
|
|
|
Terrain[] terrains = GameObject.FindObjectsOfType<Terrain>();
|
|
if (terrains.Length > 0)
|
|
{
|
|
foreach (var t in terrains)
|
|
{
|
|
Vector3 min = t.transform.position;
|
|
Vector3 max = min + t.terrainData.size;
|
|
m_minPos.x = m_minPos.x > min.x ? min.x : m_minPos.x;
|
|
m_maxPos.x = m_maxPos.x < max.x ? max.x : m_maxPos.x;
|
|
m_minPos.z = m_minPos.z > min.z ? min.z : m_minPos.z;
|
|
m_maxPos.z = m_maxPos.z < max.z ? max.z : m_maxPos.z;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_minPos.x = m_minPos.z = -1000f;
|
|
m_maxPos.x = m_maxPos.z = 1000f;
|
|
}
|
|
}
|
|
|
|
m_xCount = (int)((m_maxPos.x - m_minPos.x) / m_size + float.Epsilon) + 1;
|
|
m_zCount = (int)((m_maxPos.z - m_minPos.z) / m_size + float.Epsilon) + 1;
|
|
//Debug.Log("xCount: " + xCount + " zCount: " + zCount);
|
|
m_cellBounds.size = new Vector3(m_size, 200f, m_size);
|
|
m_ItemGrid = new Cell[m_xCount,m_zCount];
|
|
for (int i=0; i<m_xCount; i++)
|
|
for (int j=0; j<m_zCount; j++)
|
|
{
|
|
m_ItemGrid[i, j] = new Cell(DespawnOnStart);
|
|
}
|
|
m_guidToCell = new Dictionary<Guid, Cell>();
|
|
m_guidToItem = new Dictionary<Guid, T>();
|
|
}
|
|
|
|
protected static G s_instance;
|
|
public static G instance
|
|
{
|
|
get
|
|
{
|
|
return s_instance;
|
|
}
|
|
}
|
|
|
|
protected GridPos CellForPosition(Vector3 pos)
|
|
{
|
|
GridPos p;
|
|
p.x = (int)((pos.x - m_minPos.x) / m_size);
|
|
p.z = (int)((pos.z - m_minPos.z) / m_size);
|
|
if (p.x < 0 || p.z < 0 || p.x >= m_ItemGrid.GetLength(0) || p.z >= m_ItemGrid.GetLength(1))
|
|
{
|
|
Debug.LogWarning("ItemGrid position out of range: "+pos);
|
|
p.x = p.z = -1;
|
|
}
|
|
return p;
|
|
}
|
|
|
|
protected bool PositionIsValid(GridPos pos)
|
|
{
|
|
if (pos.x < m_xCount && pos.z < m_zCount && pos.x >= 0 && pos.z >= 0)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public virtual Guid AddItem(T item)
|
|
{
|
|
if (HasItem(item))
|
|
{
|
|
//remove and add again to make sure item is at correct cell
|
|
RemoveItem(item);
|
|
}
|
|
GridPos p = CellForPosition(item.GetPosition());
|
|
if (!PositionIsValid(p))
|
|
{
|
|
Debug.LogWarning($"Object is out of range: {item.ToString()}");
|
|
return Guid.Empty;
|
|
}
|
|
var guid = item.GetGuid();
|
|
var cell = m_ItemGrid[p.x, p.z];
|
|
if (!cell.guidToItem.ContainsKey(guid))
|
|
{
|
|
cell.guidToItem[guid] = item;
|
|
if (cell.wasActive != item.IsSpawned())
|
|
{
|
|
if (cell.wasActive)
|
|
item.Spawn();
|
|
else
|
|
{
|
|
item.Despawn();
|
|
}
|
|
}
|
|
m_guidToCell[guid] = cell;
|
|
m_guidToItem[guid] = item;
|
|
}
|
|
return guid;
|
|
}
|
|
/// <summary>
|
|
/// Rmoves item from the grid. Returns GUID of the item.
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <returns></returns>
|
|
public virtual Guid RemoveItem(T item)
|
|
{
|
|
/*
|
|
GridPos p = CellForPosition(item.GetPosition());
|
|
if (!PositionIsValid(p))
|
|
return Guid.Empty;
|
|
*/
|
|
var guid = item.GetGuid();
|
|
if (!m_guidToCell.ContainsKey(guid)) return guid;
|
|
var cell = m_guidToCell[guid];
|
|
if (cell != null)
|
|
{
|
|
cell.guidToItem.Remove(guid);
|
|
}
|
|
m_guidToCell.Remove(guid);
|
|
m_guidToItem.Remove(guid);
|
|
return guid;
|
|
|
|
}
|
|
|
|
public bool HasItem(T item)
|
|
{
|
|
return m_guidToCell.ContainsKey(item.GetGuid());
|
|
}
|
|
|
|
public virtual void UpdateItem(T item)
|
|
{
|
|
GridPos p = CellForPosition(item.GetPosition());
|
|
if (!PositionIsValid(p))
|
|
{
|
|
Debug.LogError($"Trying to update item outside the grid {item.ToString()}!");
|
|
return;
|
|
}
|
|
var guid = item.GetGuid();
|
|
var cell = m_ItemGrid[p.x, p.z];
|
|
if (cell != m_guidToCell[guid])
|
|
{
|
|
RemoveItem(item);
|
|
AddItem(item);
|
|
}
|
|
else
|
|
{
|
|
if (cell.wasActive != item.IsSpawned())
|
|
{
|
|
if (cell.wasActive)
|
|
item.Spawn();
|
|
else
|
|
item.Despawn();
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Return true if given cell is in the range of player
|
|
/// </summary>
|
|
/// <param name="x"></param>
|
|
/// <param name="z"></param>
|
|
/// <returns></returns>
|
|
protected bool CellInRange(int x, int z)
|
|
{
|
|
float minX = m_minPos.x + m_size * (float)x;
|
|
float minZ = m_minPos.z + m_size * (float)z;
|
|
float maxX = minX + m_size;
|
|
float maxZ = minZ + m_size;
|
|
if (maxX < m_playerPos.x - m_visibilityRange)
|
|
return false;
|
|
if (minX > m_playerPos.x + m_visibilityRange)
|
|
return false;
|
|
if (maxZ < m_playerPos.z - m_visibilityRange)
|
|
return false;
|
|
if (minZ > m_playerPos.z + m_visibilityRange)
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
protected virtual void CheckObjectsInCell(Cell cell, bool activate)
|
|
{
|
|
if (activate && !cell.wasActive)
|
|
{
|
|
cell.wasActive = true;
|
|
foreach (var ob in cell.guidToItem)
|
|
{
|
|
if (!ob.Value.IsSpawned())
|
|
{
|
|
ob.Value.Spawn();
|
|
}
|
|
}
|
|
// m_SpawnQueue.Enqueue(cell);
|
|
}
|
|
else if (!activate && cell.wasActive)
|
|
{
|
|
cell.wasActive = false;
|
|
//m_ItemGrid.
|
|
foreach (var ob in cell.guidToItem)
|
|
{
|
|
if (ob.Value.IsSpawned())
|
|
{
|
|
ob.Value.Despawn();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks if objects in cell
|
|
/// </summary>
|
|
/// <param name="x"></param>
|
|
/// <param name="z"></param>
|
|
protected virtual void CheckObjectsInCell(int x, int z, bool activate)
|
|
{
|
|
var cell = m_ItemGrid[x, z];
|
|
CheckObjectsInCell(cell, activate);
|
|
|
|
}
|
|
|
|
protected int MinXPos(int playerXPos)
|
|
{
|
|
int minX = playerXPos - m_loopRange;
|
|
minX = minX < 0 ? 0 : minX;
|
|
return minX;
|
|
}
|
|
|
|
protected int MaxXPos(int playerXPos)
|
|
{
|
|
int maxX = playerXPos + m_loopRange;
|
|
maxX = maxX >= m_xCount ? m_xCount - 1 : maxX;
|
|
return maxX;
|
|
}
|
|
|
|
protected int MinZPos(int playerZPos)
|
|
{
|
|
int minZ = playerZPos - m_loopRange;
|
|
minZ = minZ < 0 ? 0 : minZ;
|
|
return minZ;
|
|
}
|
|
|
|
protected int MaxZPos(int playerZPos)
|
|
{
|
|
int maxZ = playerZPos + m_loopRange;
|
|
maxZ = maxZ >= m_xCount ? m_xCount - 1 : maxZ;
|
|
return maxZ;
|
|
}
|
|
|
|
//public bool IsInRange()
|
|
|
|
protected void DespawnFarObjects()
|
|
{
|
|
for (int i = 0; i < m_xCount; i++)
|
|
{
|
|
for (int j = 0; j < m_zCount; j++)
|
|
{
|
|
if (!CellInRange(i, j))
|
|
CheckObjectsInCell(i, j, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CellIsVisible2(int x, int z)
|
|
{
|
|
bool visible = false;
|
|
Vector3 size = Vector3.one * m_size;
|
|
Vector3 pos = Vector3.zero;
|
|
pos.x = m_minPos.x + ((float)x + 0.5f) * m_size;
|
|
pos.z = m_minPos.z + ((float)z + 0.5f) * m_size;
|
|
|
|
Bounds bb = new Bounds(pos, new Vector3(m_size, 10000f, m_size));
|
|
var planes = GeometryUtility.CalculateFrustumPlanes(Camera.main);
|
|
visible = GeometryUtility.TestPlanesAABB(planes, bb);
|
|
return visible;
|
|
}
|
|
|
|
|
|
public void BoundsOfCell(int x, int z, ref Bounds bounds)
|
|
{
|
|
Vector3 pos = bounds.center;
|
|
pos.x = m_minPos.x + ((float)x + 0.5f) * m_size;
|
|
pos.z = m_minPos.z + ((float)z + 0.5f) * m_size;
|
|
bounds.center = pos;
|
|
}
|
|
public void CheckAllObjects(bool despawnFarObjects = true)
|
|
{
|
|
if (despawnFarObjects)
|
|
{
|
|
DespawnFarObjects();
|
|
}
|
|
m_playerPos = Player.Instance.transform.position;
|
|
GridPos playerGrid = CellForPosition(m_playerPos);
|
|
int minX = MinXPos(playerGrid.x);
|
|
int maxX = MaxXPos(playerGrid.x);
|
|
int minZ = MinZPos(playerGrid.z);
|
|
int maxZ = MaxZPos(playerGrid.z);
|
|
if (!UseFrustum)
|
|
{
|
|
for (int x = minX; x <= maxX; x++)
|
|
{
|
|
for (int z = minZ; z <= maxZ; z++)
|
|
{
|
|
CheckObjectsInCell(x, z, true);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var frustumPlanes = GeometryUtility.CalculateFrustumPlanes(m_camera);
|
|
for (int x = minX; x <= maxX; x++)
|
|
{
|
|
for (int z = minZ; z <= maxZ; z++)
|
|
{
|
|
BoundsOfCell(x,z, ref m_cellBounds);
|
|
var visible = GeometryUtility.TestPlanesAABB(frustumPlanes, m_cellBounds);
|
|
CheckObjectsInCell(x, z, visible);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
protected virtual void CheckCellsThatChangedWithFrustum()
|
|
{
|
|
GridPos prevGridPos = CellForPosition(m_playerPos);
|
|
m_playerPos = Player.Instance.transform.position;
|
|
GridPos playerGrid = CellForPosition(m_playerPos);
|
|
|
|
//Bounds bb = new Bounds(pos, new Vector3(m_size, 200f, m_size));
|
|
var frustumPlanes = GeometryUtility.CalculateFrustumPlanes(m_camera);
|
|
int minZ = MinZPos(playerGrid.z);
|
|
int maxZ = MaxZPos(playerGrid.z);
|
|
int minX = MinXPos(playerGrid.x);
|
|
int maxX = MaxXPos(playerGrid.x);
|
|
//check all current cells to check if frustum visibility changed
|
|
for (int x = minX; x <= maxX; x++)
|
|
{
|
|
for (int z = minZ; z <= maxZ; z++)
|
|
{
|
|
BoundsOfCell(x,z, ref m_cellBounds);
|
|
var visible = GeometryUtility.TestPlanesAABB(frustumPlanes, m_cellBounds);
|
|
CheckObjectsInCell(x, z, visible);
|
|
}
|
|
}
|
|
|
|
|
|
if (playerGrid.x == prevGridPos.x && prevGridPos.z == playerGrid.z)
|
|
{
|
|
//nothing has change, return
|
|
return;
|
|
}
|
|
|
|
if (Math.Abs(playerGrid.x - prevGridPos.x) > 1 || Math.Abs(prevGridPos.z - playerGrid.z) > 1)
|
|
{
|
|
//larger position change, update all objects. Despawn object that are out of range.
|
|
CheckAllObjects(true);
|
|
return;
|
|
}
|
|
// CheckAllObjects(true);
|
|
|
|
if (Math.Abs(playerGrid.x - prevGridPos.x) == 1)
|
|
{
|
|
|
|
int activeX,deactiveX = 0;
|
|
|
|
if (playerGrid.x > prevGridPos.x)
|
|
{
|
|
activeX = MaxXPos(playerGrid.x);
|
|
deactiveX = MinXPos(prevGridPos.x);
|
|
//deactivate
|
|
}
|
|
else
|
|
{
|
|
deactiveX = MaxXPos(prevGridPos.x);
|
|
activeX = MinXPos(playerGrid.x);
|
|
}
|
|
|
|
if (Math.Abs(deactiveX - playerGrid.x) > m_loopRange)
|
|
{
|
|
for (int z = minZ; z <= maxZ; z++)
|
|
{
|
|
CheckObjectsInCell(deactiveX, z, false);
|
|
}
|
|
}
|
|
if (Math.Abs(activeX - playerGrid.x) >= m_loopRange)
|
|
{
|
|
for (int z = minZ; z <= maxZ; z++)
|
|
{
|
|
BoundsOfCell(activeX,z, ref m_cellBounds);
|
|
var visible = GeometryUtility.TestPlanesAABB(frustumPlanes, m_cellBounds);
|
|
CheckObjectsInCell(activeX, z, visible);
|
|
}
|
|
}
|
|
}
|
|
if (playerGrid.z != prevGridPos.z)
|
|
{
|
|
|
|
int activeZ,deactiveZ = 0;
|
|
|
|
if (playerGrid.z > prevGridPos.z)
|
|
{
|
|
activeZ = MaxZPos(playerGrid.z);
|
|
deactiveZ = MinZPos(prevGridPos.z);
|
|
//deactivate
|
|
}
|
|
else
|
|
{
|
|
deactiveZ = MaxZPos(prevGridPos.z);
|
|
activeZ = MinZPos(playerGrid.z);
|
|
}
|
|
|
|
if (Math.Abs(deactiveZ - playerGrid.z) > m_loopRange)
|
|
{
|
|
for (int x = minX; x <= maxX; x++)
|
|
{
|
|
CheckObjectsInCell(x, deactiveZ, false);
|
|
}
|
|
}
|
|
if (Math.Abs(activeZ - playerGrid.z) >= m_loopRange)
|
|
{
|
|
for (int x = minX; x <= maxX; x++)
|
|
{
|
|
BoundsOfCell(x,activeZ, ref m_cellBounds);
|
|
var visible = GeometryUtility.TestPlanesAABB(frustumPlanes, m_cellBounds);
|
|
CheckObjectsInCell(x, activeZ, visible);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool PlayerCellChanged()
|
|
{
|
|
GridPos prevGridPos = CellForPosition(m_playerPos);
|
|
GridPos playerGrid = CellForPosition(Player.Instance.transform.position);
|
|
if (playerGrid.x == prevGridPos.x && prevGridPos.z == playerGrid.z)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
protected virtual void CheckCellsThatChanged()
|
|
{
|
|
if (!PlayerCellChanged())
|
|
return;
|
|
GridPos prevGridPos = CellForPosition(m_playerPos);
|
|
m_playerPos = Player.Instance.transform.position;
|
|
GridPos playerGrid = CellForPosition(m_playerPos);
|
|
|
|
if (Math.Abs(playerGrid.x - prevGridPos.x) > 1 || Math.Abs(prevGridPos.z - playerGrid.z) > 1)
|
|
{
|
|
//larger position change, update all objects. Despawn object that are out of range.
|
|
CheckAllObjects(true);
|
|
return;
|
|
}
|
|
//CheckAllObjects(true);
|
|
|
|
if (Math.Abs(playerGrid.x - prevGridPos.x) == 1)
|
|
{
|
|
int minZ = MinZPos(playerGrid.z);
|
|
int maxZ = MaxZPos(playerGrid.z);
|
|
int activeX,deactiveX = 0;
|
|
|
|
if (playerGrid.x > prevGridPos.x)
|
|
{
|
|
activeX = MaxXPos(playerGrid.x);
|
|
deactiveX = MinXPos(prevGridPos.x);
|
|
//deactivate
|
|
}
|
|
else
|
|
{
|
|
deactiveX = MaxXPos(prevGridPos.x);
|
|
activeX = MinXPos(playerGrid.x);
|
|
}
|
|
|
|
if (Math.Abs(deactiveX - playerGrid.x) > m_loopRange)
|
|
{
|
|
for (int z = minZ; z <= maxZ; z++)
|
|
{
|
|
CheckObjectsInCell(deactiveX, z, false);
|
|
}
|
|
}
|
|
if (Math.Abs(activeX - playerGrid.x) >= m_loopRange)
|
|
{
|
|
for (int z = minZ; z <= maxZ; z++)
|
|
{
|
|
CheckObjectsInCell(activeX, z, true);
|
|
}
|
|
}
|
|
}
|
|
if (playerGrid.z != prevGridPos.z)
|
|
{
|
|
int minX = MinXPos(playerGrid.x);
|
|
int maxX = MaxXPos(playerGrid.x);
|
|
int activeZ,deactiveZ = 0;
|
|
|
|
if (playerGrid.z > prevGridPos.z)
|
|
{
|
|
activeZ = MaxZPos(playerGrid.z);
|
|
deactiveZ = MinZPos(prevGridPos.z);
|
|
//deactivate
|
|
}
|
|
else
|
|
{
|
|
deactiveZ = MaxZPos(prevGridPos.z);
|
|
activeZ = MinZPos(playerGrid.z);
|
|
}
|
|
|
|
if (Math.Abs(deactiveZ - playerGrid.z) > m_loopRange)
|
|
{
|
|
for (int x = minX; x <= maxX; x++)
|
|
{
|
|
CheckObjectsInCell(x, deactiveZ, false);
|
|
}
|
|
}
|
|
if (Math.Abs(activeZ - playerGrid.z) >= m_loopRange)
|
|
{
|
|
for (int x = minX; x <= maxX; x++)
|
|
{
|
|
CheckObjectsInCell(x, activeZ, true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
protected void CheckCellsToActivate()
|
|
{
|
|
if (m_lastFrameUpdate == Time.renderedFrameCount)
|
|
return;
|
|
|
|
if (m_firstFrame)
|
|
{
|
|
CheckAllObjects(DespawnOnStart);
|
|
m_firstFrame = false;
|
|
}
|
|
else
|
|
{
|
|
if (UseFrustum)
|
|
{
|
|
CheckCellsThatChangedWithFrustum();
|
|
}
|
|
else
|
|
{
|
|
CheckCellsThatChanged();
|
|
}
|
|
|
|
}
|
|
|
|
m_lastFrameUpdate = Time.renderedFrameCount;
|
|
}
|
|
protected void OnDrawGizmosSelected()
|
|
{
|
|
if (m_ItemGrid == null || !m_visualize)
|
|
return;
|
|
Color c = Color.gray;
|
|
c.a = 0.7f;
|
|
Gizmos.color = c;
|
|
Vector3 size = Vector3.one * m_size;
|
|
Vector3 pos = Vector3.zero;
|
|
if (Player.Instance)
|
|
{
|
|
m_playerPos = Player.Instance.transform.position;
|
|
pos.y = m_playerPos.y;
|
|
}
|
|
for (int i = 0; i < m_xCount; i++)
|
|
for (int j = 0; j < m_zCount; j++)
|
|
{
|
|
pos.x = m_minPos.x + ((float)i + 0.5f) * m_size;
|
|
pos.z = m_minPos.z + ((float)j + 0.5f) * m_size;
|
|
/*
|
|
if (m_player)
|
|
{
|
|
if (CellInRange(i, j))
|
|
Gizmos.color = Color.red;
|
|
else
|
|
Gizmos.color = c;
|
|
|
|
}
|
|
*/
|
|
var cell = m_ItemGrid[i, j];
|
|
if (cell.wasActive)
|
|
{
|
|
Gizmos.color = Color.red;
|
|
}
|
|
else
|
|
{
|
|
Gizmos.color = c;
|
|
}
|
|
|
|
Gizmos.DrawWireCube(pos, size);
|
|
}
|
|
}
|
|
|
|
protected virtual void Awake()
|
|
{
|
|
if (s_instance == null)
|
|
{
|
|
s_instance = this as G;
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("ObjectGrid already exists!");
|
|
DestroyImmediate(gameObject);
|
|
}
|
|
|
|
//m_SpawnQueue = new Queue<Cell>(100);
|
|
PrepareGrid();
|
|
SceneManager.sceneUnloaded += SceneManagerOnsceneUnloaded;
|
|
}
|
|
|
|
protected void OnDestroy()
|
|
{
|
|
SceneManager.sceneUnloaded -= SceneManagerOnsceneUnloaded;
|
|
}
|
|
|
|
private void SceneManagerOnsceneUnloaded(Scene arg0)
|
|
{
|
|
CheckCellsToActivate();
|
|
}
|
|
|
|
protected virtual void Start()
|
|
{
|
|
CheckCellsToActivate();
|
|
}
|
|
|
|
/*
|
|
private void SpawnCellsInaQueue()
|
|
{
|
|
for (int i=0; i<m_SpawnQueue.Count; i++)
|
|
{
|
|
var cell = m_SpawnQueue.Dequeue();
|
|
if (!cell.wasActive)
|
|
{
|
|
cell.wasActive = true;
|
|
foreach (var pairs in cell.guidToItem)
|
|
{
|
|
pairs.Value.Spawn();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
|
|
protected virtual void Update()
|
|
{
|
|
#if UNITY_EDITOR
|
|
//update in edit mode to check different ranges
|
|
m_loopRange = (int) (m_visibilityRange / m_size) + 1;
|
|
#endif
|
|
m_timer += Time.deltaTime;
|
|
if (m_timer > m_checkTimeDelta || PlayerCellChanged())
|
|
{
|
|
m_timer = 0f;
|
|
CheckCellsToActivate();
|
|
}
|
|
|
|
//SpawnCellsInaQueue();
|
|
}
|
|
//protected fsSerializer m_Serializer = new fsSerializer();
|
|
|
|
public virtual string SerializeToJSON()
|
|
{
|
|
return "";
|
|
}
|
|
|
|
public virtual void DeserializeFromJSON(string js)
|
|
{
|
|
}
|
|
}
|
|
}
|