public void Refresh() { if (Prefab == null) { SharedMesh = null; SharedMaterials = null; ShadowCastingMode = ShadowCastingMode.Off; ReceiveShadow = false; Layer = 0; } else { MeshFilter mf = Prefab.GetComponentInChildren <MeshFilter>(); if (mf != null) { SharedMesh = mf.sharedMesh; } MeshRenderer mr = Prefab.GetComponentInChildren <MeshRenderer>(); if (mr != null) { SharedMaterials = mr.sharedMaterials; ShadowCastingMode = mr.shadowCastingMode; ReceiveShadow = mr.receiveShadows; } CapsuleCollider col = Prefab.GetComponentInChildren <CapsuleCollider>(); hasCollider = col != null; if (col != null) { ColliderInfo = new GTreeColliderInfo(col); } if (KeepPrefabLayer) { Layer = Prefab.layer; } } if (BaseScale == Vector3.zero) { BaseScale = Vector3.one; } }
private void LateUpdate() { if (Terrain == null) { return; } if (Terrain.TerrainData == null) { return; } if (Terrain.TerrainData.Foliage.Trees == null) { return; } if (Terrain.TerrainData.Foliage.Trees.Prototypes.Count == 0) { return; } GameObject actualTarget = null; if (Target != null) { actualTarget = Target; } else if (Camera.main != null) { actualTarget = Camera.main.gameObject; } if (actualTarget == null) { return; } Vector3 terrainSize = new Vector3( Terrain.TerrainData.Geometry.Width, Terrain.TerrainData.Geometry.Height, Terrain.TerrainData.Geometry.Length); Vector3 targetLocalPos = Terrain.transform.InverseTransformPoint(actualTarget.transform.position); Vector3 treeLocalPos = Vector3.zero; float sqrDistance = distance * distance; TreeInstances.Clear(); List <GTreeInstance> instances = Terrain.TerrainData.Foliage.TreeInstances; for (int i = 0; i < instances.Count; ++i) { GTreeInstance tree = instances[i]; treeLocalPos.Set( tree.Position.x * terrainSize.x, tree.Position.y * terrainSize.y, tree.Position.z * terrainSize.z); if (Vector3.SqrMagnitude(targetLocalPos - treeLocalPos) <= sqrDistance) { TreeInstances.Add(tree); } } Vector3 targetNormalizePos = Terrain.WorldPointToNormalized(actualTarget.transform.position); TreeInstances.Sort((t0, t1) => { float d0 = Vector3.SqrMagnitude(targetNormalizePos - t0.Position); float d1 = Vector3.SqrMagnitude(targetNormalizePos - t1.Position); return(d0.CompareTo(d1)); }); List <GTreePrototype> prototypes = Terrain.TerrainData.Foliage.Trees.Prototypes; int colliderIndex = 0; for (int i = 0; i < TreeInstances.Count; ++i) { GTreeInstance tree = TreeInstances[i]; GTreePrototype prototype = prototypes[tree.PrototypeIndex]; if (!prototype.HasCollider) { continue; } if (colliderIndex >= ColliderBudget) { break; } CapsuleCollider col = GetCollider(colliderIndex); colliderIndex += 1; Vector3 localPos = new Vector3( terrainSize.x * tree.Position.x, terrainSize.y * tree.Position.y, terrainSize.z * tree.Position.z); Vector3 worldPos = Terrain.transform.TransformPoint(localPos); col.transform.position = worldPos; col.transform.rotation = tree.Rotation; col.transform.localScale = tree.Scale; GTreeColliderInfo colliderInfo = prototype.ColliderInfo; col.center = colliderInfo.Center; col.radius = colliderInfo.Radius; col.height = colliderInfo.Height; col.direction = colliderInfo.Direction; col.gameObject.layer = prototype.Layer; col.gameObject.tag = prototype.Prefab.tag; col.gameObject.SetActive(true); } for (int i = colliderIndex; i < ColliderBudget; ++i) { CapsuleCollider col = GetCollider(i); col.gameObject.SetActive(false); } }