Skip to content

Instantly share code, notes, and snippets.

@gamemachine
Last active August 29, 2015 14:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save gamemachine/d222e3e1ff3a8c30d297 to your computer and use it in GitHub Desktop.
Save gamemachine/d222e3e1ff3a8c30d297 to your computer and use it in GitHub Desktop.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace PvpGame
{
public sealed class Objectpool2<T>
where T : new()
{
private readonly int size;
private readonly Queue<T> queue;
private int count = 0;
/// <summary>
/// Initializes a new instance of the ObjectPool class.
/// </summary>
/// <param name="size">The size of the object pool.</param>
public Objectpool2 (int size)
{
this.size = size;
queue = new Queue<T> ();
}
public int Count ()
{
return queue.Count;
}
/// <summary>
/// Retrieves an item from the pool.
/// </summary>
/// <returns>The item retrieved from the pool.</returns>
public T Get ()
{
if (queue.Count > 0) {
T item = queue.Dequeue ();
count--;
return item;
} else {
Debug.Log ("Queue is empty count=" + count + " size=" + size);
return default(T);
}
}
/// <summary>
/// Places an item in the pool.
/// </summary>
/// <param name="item">The item to place to the pool.</param>
public void Put (T item)
{
queue.Enqueue (item);
count++;
}
}
public class GridTracking : MonoBehaviour
{
private Grid grid;
private Dictionary<string, GridValue> objectIndex = new Dictionary<string, GridValue> ();
private Objectpool2<GameObject> objectPool = new Objectpool2<GameObject> (200);
private int removeCheckCount;
Transform player;
void Start ()
{
if (Game.playerEntity == null) {
player = GameObject.Find ("TestController").transform;
} else {
player = Game.playerEntity.model.transform;
}
grid = Grid.FindOrCreate ("terrain", 5000, 20);
CreateGrid ();
CreatePool ();
InvokeRepeating ("UpdateGrid", 0.005f, 1f);
}
public static void SetMeshColliders (GameObject go, bool enabled)
{
MeshCollider col;
col = go.GetComponent<MeshCollider> () as MeshCollider;
if (col == null) {
foreach (Transform s in go.transform) {
col = s.GetComponent<MeshCollider> () as MeshCollider;
if (col != null) {
col.enabled = enabled;
}
}
} else {
col.enabled = enabled;
}
}
public static void CreateGrid ()
{
Grid grid = Grid.FindOrCreate ("terrain", 5000, 20);
foreach (Transform t in GameObject.Find ("TerrainObjects").transform) {
foreach (Transform s in t.gameObject.transform) {
GridValue gridValue = new GridValue ();
gridValue.position = s.position;
gridValue.id = "rock+" + s.name;
gridValue.go = s.gameObject;
gridValue.entityType = GridValue.EntityType.Rock;
grid.Set (gridValue);
}
}
int treecount = 0;
foreach (Transform t in GameObject.Find ("Terrains").transform) {
Terrain terrain = t.GetComponent<Terrain> () as Terrain;
foreach (TreeInstance ti in terrain.terrainData.treeInstances) {
Vector3 tpos = (Vector3.Scale (terrain.terrainData.size, ti.position) + t.position);
GridValue gridValue = new GridValue ();
gridValue.position = tpos;
gridValue.id = "tree_" + treecount;
gridValue.entityType = GridValue.EntityType.Tree;
grid.Set (gridValue);
treecount++;
}
}
Debug.Log ("Grid size " + grid.Count ());
}
void CreatePool ()
{
GameObject trees = new GameObject ();
trees.name = "trees";
for (int i=0; i<200; i++) {
GameObject go = new GameObject ();
go.transform.parent = trees.transform;
go.tag = "harvestable";
go.name = "Tree";
go.transform.position = Vector3.zero;
Rigidbody rigid = go.AddComponent<Rigidbody> ();
rigid.isKinematic = true;
CapsuleCollider col = go.AddComponent<CapsuleCollider> () as CapsuleCollider;
col.center = Vector3.zero;
col.height = 10f;
col.radius = 0.4f;
col.direction = 1;
col.enabled = false;
objectPool.Put (go);
}
}
// Update is called once per frame
void UpdateGrid ()
{
List<GridValue> gridValues = grid.Neighbors (player.position.x, player.position.z, 0);
if (gridValues.Count > 0) {
AddNew (gridValues);
if (removeCheckCount >= 1) {
removeCheckCount = 0;
RemoveOld (gridValues);
//Debug.Log ("Gridvalues count " + gridValues.Count + " indexcount " + objectIndex.Count + " queuecount " + objectPool.Count ());
} else {
removeCheckCount++;
}
}
}
void AddNew (List<GridValue> gridValues)
{
int addCount = 0;
foreach (GridValue gridValue in gridValues) {
if (AddCollider (gridValue)) {
addCount++;
}
if (addCount > 10) {
return;
}
}
}
void RemoveOld (List<GridValue> gridValues)
{
HashSet<GridValue> toCheck = new HashSet<GridValue> (gridValues);
List<string> idsToRemove = new List<string> ();
foreach (GridValue old in objectIndex.Values) {
if (!toCheck.Contains (old)) {
idsToRemove.Add (old.id);
}
}
int removeCount = 0;
foreach (string id in idsToRemove) {
GridValue gridValue = objectIndex [id];
RemoveCollider (gridValue);
objectIndex.Remove (id);
removeCount++;
if (removeCount > 20) {
break;
}
}
if (removeCount > 0) {
Debug.Log ("Removed " + removeCount);
}
}
void RemoveCollider (GridValue gridValue)
{
if (gridValue.entityType == GridValue.EntityType.Rock) {
SetMeshColliders (gridValue.go, false);
} else if (gridValue.entityType == GridValue.EntityType.Tree) {
GameObject go = gridValue.go;
go.transform.position = Vector3.zero;
go.GetComponent<CapsuleCollider> ().enabled = false;
objectPool.Put (go);
gridValue.go = null;
}
}
bool AddCollider (GridValue gridValue)
{
if (objectIndex.ContainsKey (gridValue.id)) {
return false;
}
if (gridValue.entityType == GridValue.EntityType.Rock) {
SetMeshColliders (gridValue.go, true);
} else if (gridValue.entityType == GridValue.EntityType.Tree) {
GameObject go = objectPool.Get ();
go.transform.position = gridValue.position;
go.GetComponent<CapsuleCollider> ().enabled = true;
gridValue.go = go;
}
objectIndex [gridValue.id] = gridValue;
return true;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment