using UnityEngine; using System.Collections; using System.Collections.Generic; using System.Linq; namespace PvpGame { public sealed class Objectpool2 where T : new() { private readonly int size; private readonly Queue queue; private int count = 0; /// /// Initializes a new instance of the ObjectPool class. /// /// The size of the object pool. public Objectpool2 (int size) { this.size = size; queue = new Queue (); } public int Count () { return queue.Count; } /// /// Retrieves an item from the pool. /// /// The item retrieved from the pool. 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); } } /// /// Places an item in the pool. /// /// The item to place to the pool. public void Put (T item) { queue.Enqueue (item); count++; } } public class GridTracking : MonoBehaviour { private Grid grid; private Dictionary objectIndex = new Dictionary (); private Objectpool2 objectPool = new Objectpool2 (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 () as MeshCollider; if (col == null) { foreach (Transform s in go.transform) { col = s.GetComponent () 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 () 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 (); rigid.isKinematic = true; CapsuleCollider col = go.AddComponent () 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 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 gridValues) { int addCount = 0; foreach (GridValue gridValue in gridValues) { if (AddCollider (gridValue)) { addCount++; } if (addCount > 10) { return; } } } void RemoveOld (List gridValues) { HashSet toCheck = new HashSet (gridValues); List idsToRemove = new List (); 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 ().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 ().enabled = true; gridValue.go = go; } objectIndex [gridValue.id] = gridValue; return true; } } }