using UnityEngine; using System.Collections; using System.Collections.Generic; using System; using UnityEngine.Events; namespace WorldStreamer2 { /// /// World mover - movesw the world when moving out of chosen range. /// public class WorldMover : MonoBehaviour { /// /// The WORLD MOVER TAG. /// public static string WORLDMOVERTAG = "WorldMover"; /// /// The x tile range based on main streamer. /// [Tooltip("Frequency distance of world position restarting, distance in is grid elements.")] public float xTileRange = 2; /// /// The y tile range based on main streamer. /// [Tooltip("Frequency distance of world position restarting, distance in is grid elements.")] public float yTileRange = 2; /// /// The z tile range based on main streamer. /// [Tooltip("Frequency distance of world position restarting, distance in is grid elements.")] public float zTileRange = 2; /// /// Debug value used for client-server communication it's position without floating point fix and looping /// [Tooltip("Time from reaching frequency distance for world mover to restart world position.")] public float waitForRestart = 10; /// /// The x current tile move. /// [HideInInspector] public float xCurrentTile = 0; /// /// The y current tile move. /// [HideInInspector] public float yCurrentTile = 0; /// /// The z current tile move. /// [HideInInspector] public float zCurrentTile = 0; /// /// The streamer main for checking range. /// [Tooltip("Drag and drop here, your _Streamer_Major prefab from scene hierarchy.")] public Streamer streamerMajor; /// /// The additional streamers to move tiles. /// [Tooltip("Drag and drop here, your all _Streamer_Minors prefabs from scene hierarchy.")] public Streamer[] streamerMinors; /// /// The current move vector. /// [Tooltip("Differences between real and restarted player position. Useful in AI and network communications.")] public Vector3 currentMove = Vector3.zero; /// /// The objects to move with tiles. /// [HideInInspector] public List objectsToMove = new(); /// /// Debug value used for client-server communication it's position without floating point fix and looping /// [Tooltip("Debug value used for client-server communication it's position without floating point fix and looping")] public Vector3 playerPositionMovedLooped; /// /// Event fired on world moved. /// public UnityEvent WorldMoved; private Vector3 worldSize; bool waitForMover; /// /// Start this instance and sets main streamer field for world mover. /// public void Start() { streamerMajor.worldMover = this; List streamersTemp = new List(); streamersTemp.AddRange(streamerMinors); streamersTemp.Remove(streamerMajor); streamerMinors = streamersTemp.ToArray(); worldSize = new Vector3(streamerMajor.sceneCollectionManagers[0].xSize * (streamerMajor.sceneCollectionManagers[0].xLimitsy - streamerMajor.sceneCollectionManagers[0].xLimitsx + 1), streamerMajor.sceneCollectionManagers[0].ySize * (streamerMajor.sceneCollectionManagers[0].yLimitsy - streamerMajor.sceneCollectionManagers[0].yLimitsx + 1), streamerMajor.sceneCollectionManagers[0].zSize * (streamerMajor.sceneCollectionManagers[0].zLimitsy - streamerMajor.sceneCollectionManagers[0].zLimitsx + 1)); Debug.Log("World Mover worldSize - " + worldSize); } public void Update() { if (streamerMajor.player != null) { playerPositionMovedLooped = streamerMajor.player.position - currentMove; if (streamerMajor.looping) { //Debug.Log (playerPositionMovedLooped.z + " " + Mathf.Abs (streamerMajor.sceneCollection.zSize * streamerMajor.sceneCollection.zLimitsx) + " " + worldSize.z); playerPositionMovedLooped = new Vector3( worldSize.x != 0 ? modf((playerPositionMovedLooped.x + Mathf.Abs(streamerMajor.sceneCollectionManagers[0].xSize * streamerMajor.sceneCollectionManagers[0].xLimitsx)), worldSize.x) + streamerMajor.sceneCollectionManagers[0].xSize * streamerMajor.sceneCollectionManagers[0].xLimitsx : playerPositionMovedLooped.x, worldSize.y != 0 ? modf((playerPositionMovedLooped.y + Mathf.Abs(streamerMajor.sceneCollectionManagers[0].ySize * streamerMajor.sceneCollectionManagers[0].yLimitsx)), worldSize.y) + streamerMajor.sceneCollectionManagers[0].ySize * streamerMajor.sceneCollectionManagers[0].yLimitsx : playerPositionMovedLooped.y, worldSize.z != 0 ? modf((playerPositionMovedLooped.z + Mathf.Abs(streamerMajor.sceneCollectionManagers[0].zSize * streamerMajor.sceneCollectionManagers[0].zLimitsx)), worldSize.z) + streamerMajor.sceneCollectionManagers[0].zSize * streamerMajor.sceneCollectionManagers[0].zLimitsx : playerPositionMovedLooped.z); } } } /// /// Checks the mover distance. /// /// X position current in tiles. /// Y position current in tiles. /// Z position current in tiles. public void CheckMoverDistance(int xPosCurrent, int yPosCurrent, int zPosCurrent) { if (waitForMover) return; if (!(Mathf.Abs(xPosCurrent - xCurrentTile) > xTileRange) && !(Mathf.Abs(yPosCurrent - yCurrentTile) > yTileRange) && !(Mathf.Abs(zPosCurrent - zCurrentTile) > zTileRange)) return; waitForMover = true; WorldMoved?.Invoke(); StartCoroutine(MoveWorld(xPosCurrent, yPosCurrent, zPosCurrent)); } /// /// Moves the world. /// /// X position current in tiles. /// Y position current in tiles. /// Z position current in tiles. IEnumerator MoveWorld(int xPosCurrent, int yPosCurrent, int zPosCurrent) { //Debug.Log("PreMoveWorld " + xPosCurrent + " " + yPosCurrent + " " + zPosCurrent); yield return new WaitForSeconds(waitForRestart); //Debug.Log("MoveWorld " + xPosCurrent + " " + yPosCurrent + " " + zPosCurrent); Vector3 moveVector = new Vector3((xPosCurrent - xCurrentTile) * streamerMajor.sceneCollectionManagers[0].xSize, (yPosCurrent - yCurrentTile) * streamerMajor.sceneCollectionManagers[0].ySize, (zPosCurrent - zCurrentTile) * streamerMajor.sceneCollectionManagers[0].zSize); currentMove -= moveVector; streamerMajor.player.position -= moveVector; foreach (var scm in streamerMajor.sceneCollectionManagers) foreach (var item in scm.loadedScenes) { if (item.loaded && item.sceneGo != null) item.sceneGo.transform.position -= moveVector; } Vector3 position; foreach (var item in objectsToMove) { if (item != null) { //Debug.Log (item.name); position = item.position; position -= moveVector; //if (position.x > worldSize.x) // position.x -= worldSize.x; //if (position.x < 0) // position.x += worldSize.x; //if (position.y > worldSize.y) // position.y -= worldSize.y; //if (position.y < 0) // position.y += worldSize.y; //if (position.z > worldSize.z) // position.z -= worldSize.z; //if (position.x < 0) // position.z += worldSize.z; item.position = position; } } xCurrentTile = xPosCurrent; yCurrentTile = yPosCurrent; zCurrentTile = zPosCurrent; streamerMajor.currentMove = currentMove; foreach (var item in streamerMinors) { item.currentMove = currentMove; foreach (var scm in item.sceneCollectionManagers) foreach (var scene in scm.loadedScenes) { if (scene.loaded && scene.sceneGo != null) scene.sceneGo.transform.position -= moveVector; } } waitForMover = false; } /// /// Moves the object. /// /// Object transform. public void MoveObject(Transform objectTransform) { objectTransform.position += currentMove; } /// /// Adds the object to move. /// /// Object to move. public void AddObjectToMove(Transform objectToMove) { MoveObject(objectToMove); objectsToMove.Add(objectToMove); } private float modf(float x, float m) { return (x % m + m) % m; } } }