using UnityEngine; using System.Collections; using System.Collections.Generic; namespace WorldStreamer2 { /// /// Sets Terrain neighbours. /// public class TerrainNeighbours : MonoBehaviour { public List terrainsToOmit; [Tooltip("If you use Floating Point fix system drag and drop world mover prefab from your scene hierarchy.")] /// /// The world mover. /// public WorldMover worldMover; public List _terrains = new List(); Dictionary _terrainDict = null; [Tooltip("Debug value, it gives info about starting position offset.")] /// /// The first position for terrain tile management. /// Vector2 firstPosition; int sizeX = 0; int sizeZ = 0; bool firstPositonSet = false; /// /// Start this instance and creates neighbours for scene terrains /// void Start() { CreateNeighbours(); } /// /// Sets the neighbours for all terrains in scenes /// public void CreateNeighbours() { //https://github.com/Unity-Technologies/UnityCsReference/blob/02d565cf3dd0f6b15069ba976064c75dc2705b08/Modules/Terrain/Public/TerrainUtility.cs //UnityEngine.Experimental.TerrainAPI.TerrainUtility.AutoConnect(); //return; List _terrainsNew = new List(); _terrainsNew.AddRange(Terrain.activeTerrains); foreach (var item in terrainsToOmit) { if (_terrainsNew.Contains(item)) { _terrainsNew.Remove(item); } } foreach (var item in _terrains) { if (_terrainsNew.Contains(item)) { _terrainsNew.Remove(item); } } if (_terrainDict == null) _terrainDict = new Dictionary(new IntArrayComparer()); Dictionary _terrainDictNew = new Dictionary(new IntArrayComparer()); Dictionary _terrainDictRob2 = new Dictionary(new IntArrayComparer()); if (_terrainsNew.Count > 0) { if (!firstPositonSet) { firstPositonSet = true; firstPosition = new Vector2(_terrainsNew[0].transform.position.x, _terrainsNew[0].transform.position.z); sizeX = (int)_terrainsNew[0].terrainData.size.x; sizeZ = (int)_terrainsNew[0].terrainData.size.z; } foreach (var terrain in _terrainsNew) { _terrains.Add(terrain); Vector3 pos = terrain.transform.position; if (worldMover != null) pos -= worldMover.currentMove; int[] posTer = new int[] { (int)(Mathf.RoundToInt ((pos.x - firstPosition.x) / sizeX)), (int)(Mathf.RoundToInt ((pos.z - firstPosition.y) / sizeZ)) }; if (_terrainDict.ContainsKey(posTer)) { _terrainDict[posTer] = terrain; } else _terrainDict.Add(posTer, terrain); _terrainDictNew.Add(posTer, terrain); } foreach (var item in _terrainDictNew) { int[] posTer = item.Key; Terrain top = null; Terrain left = null; Terrain right = null; Terrain bottom = null; int[] topPos = new int[] { posTer [0], posTer [1] + 1 }; _terrainDict.TryGetValue(topPos, out top); int[] leftPos = new int[] { posTer [0] - 1, posTer [1] }; _terrainDict.TryGetValue(leftPos, out left); int[] posRight = new int[] { posTer [0] + 1, posTer [1] }; _terrainDict.TryGetValue(posRight, out right); int[] posBottom = new int[] { posTer [0], posTer [1] - 1 }; _terrainDict.TryGetValue(posBottom, out bottom); item.Value.SetNeighbors(left, top, right, bottom); item.Value.Flush(); if (top != null && !_terrainDictRob2.ContainsKey(topPos)) _terrainDictRob2.Add(topPos, top); if (left != null && !_terrainDictRob2.ContainsKey(leftPos)) _terrainDictRob2.Add(leftPos, left); if (right != null && !_terrainDictRob2.ContainsKey(posRight)) _terrainDictRob2.Add(posRight, right); if (bottom != null && !_terrainDictRob2.ContainsKey(posBottom)) _terrainDictRob2.Add(posBottom, bottom); } foreach (var item in _terrainDictRob2) { int[] posTer = item.Key; Terrain top = null; Terrain left = null; Terrain right = null; Terrain bottom = null; int[] topPos = new int[] { posTer [0], posTer [1] + 1 }; _terrainDict.TryGetValue(topPos, out top); int[] leftPos = new int[] { posTer [0] - 1, posTer [1] }; _terrainDict.TryGetValue(leftPos, out left); int[] posRight = new int[] { posTer [0] + 1, posTer [1] }; _terrainDict.TryGetValue(posRight, out right); int[] posBottom = new int[] { posTer [0], posTer [1] - 1 }; _terrainDict.TryGetValue(posBottom, out bottom); item.Value.SetNeighbors(left, top, right, bottom); item.Value.Flush(); } // Terrain.SetConnectivityDirty(); } } } }