/// <summary> /// Update the element given a distance of parallax move, t /// </summary> /// <param name="p">InfiniteScroll container</param> /// <param name="t">Total amount the parallax moved. Elements will move a percetage of this distance.</param> public void Update(InfiniteScroll p, float t, Camera c) { if (GameObjects == null || GameObjects.Count == 0 || GameObjects.Count != GameObjectRenderers.Count) { // cannot update, something went wrong in setup return; } // move everything first if (p.IsHorizontal) { foreach (GameObject obj in GameObjects) { obj.transform.Translate(t * SpeedRatio, 0.0f, 0.0f); } } else { foreach (GameObject obj in GameObjects) { obj.transform.Translate(0.0f, t * SpeedRatio, 0.0f); } } bool wrap = RepositionLogic.PositionMode != FreeParallaxPositionMode.IndividualStartOffScreen && RepositionLogic.PositionMode != FreeParallaxPositionMode.IndividualStartOnScreen; // if it's an individual object we let it go an extra screen width in case the player changes direction float padding = (wrap ? 0.0f : 1.0f); float minEdge, maxEdge; if (p.IsHorizontal) { minEdge = c.rect.x - padding; maxEdge = c.rect.width + padding; } else { minEdge = c.rect.y - padding; maxEdge = c.rect.height + padding; } int end = GameObjects.Count; // now check for wrapping and stuff going off screen for (int i = 0; i < end; i++) { GameObject obj = GameObjects[i]; Renderer r = GameObjectRenderers[i]; Bounds b = r.bounds; Vector3 screenEdge = (t > 0 ? c.WorldToViewportPoint(b.min) : c.WorldToViewportPoint(b.max)); float screenEdgeValue = (p.IsHorizontal ? screenEdge.x : screenEdge.y); if (wrap) { if (t > 0 && screenEdgeValue >= maxEdge) { if (p.IsHorizontal) { // move to the back of the line at far left float newX = (GameObjectRenderers[0].bounds.min.x - r.bounds.size.x) + p.WrapOverlap; InfiniteScroll.SetPosition(obj, r, newX, r.bounds.min.y); } else { // move to the back of the line at far bottom float newY = (GameObjectRenderers[0].bounds.min.y - r.bounds.size.y) + p.WrapOverlap; InfiniteScroll.SetPosition(obj, r, r.bounds.min.x, newY); } GameObjects.RemoveAt(i); GameObjects.Insert(0, obj); GameObjectRenderers.RemoveAt(i); GameObjectRenderers.Insert(0, r); } else if (t < 0 && screenEdgeValue <= minEdge) { if (p.IsHorizontal) { // move to the front of the line at far right float newX = (GameObjectRenderers[GameObjects.Count - 1].bounds.max.x) - p.WrapOverlap; InfiniteScroll.SetPosition(obj, r, newX, r.bounds.min.y); } else { // move to the front of the line at far top float newY = (GameObjectRenderers[GameObjects.Count - 1].bounds.max.y) - p.WrapOverlap; InfiniteScroll.SetPosition(obj, r, r.bounds.min.x, newY); } GameObjects.RemoveAt(i); GameObjects.Add(obj); GameObjectRenderers.RemoveAt(i--); GameObjectRenderers.Add(r); end--; } } else if (p.IsHorizontal) { if (t > 0 && (screenEdge.y >= c.rect.height || screenEdgeValue >= maxEdge)) { if (RepositionLogicFunction != null) { RepositionLogicFunction(p, this, t, obj, r); } else { Vector3 leftEdge = c.ViewportToWorldPoint(Vector3.zero); float randX = UnityEngine.Random.Range(RepositionLogic.MinXPercent, RepositionLogic.MaxXPercent); float randY = UnityEngine.Random.Range(RepositionLogic.MinYPercent, RepositionLogic.MaxYPercent); Vector3 newWorldPoint = c.ViewportToWorldPoint(new Vector3(randX, randY)); InfiniteScroll.SetPosition(obj, r, leftEdge.x - newWorldPoint.x, newWorldPoint.y); } } else if (t < 0 && (screenEdge.y >= c.rect.height || screenEdge.x < minEdge)) { if (RepositionLogicFunction != null) { RepositionLogicFunction(p, this, t, obj, r); } else { Vector3 rightEdge = c.ViewportToWorldPoint(Vector3.one); float randX = UnityEngine.Random.Range(RepositionLogic.MinXPercent, RepositionLogic.MaxXPercent); float randY = UnityEngine.Random.Range(RepositionLogic.MinYPercent, RepositionLogic.MaxYPercent); Vector3 newWorldPoint = c.ViewportToWorldPoint(new Vector3(randX, randY)); InfiniteScroll.SetPosition(obj, r, rightEdge.x + newWorldPoint.x, newWorldPoint.y); } } } else { if (t > 0 && (screenEdge.x >= c.rect.width || screenEdgeValue >= maxEdge)) { if (RepositionLogicFunction != null) { RepositionLogicFunction(p, this, t, obj, r); } else { Vector3 bottomEdge = c.ViewportToWorldPoint(Vector3.zero); float randX = UnityEngine.Random.Range(RepositionLogic.MinXPercent, RepositionLogic.MaxXPercent); float randY = UnityEngine.Random.Range(RepositionLogic.MinYPercent, RepositionLogic.MaxYPercent); Vector3 newWorldPoint = c.ViewportToWorldPoint(new Vector3(randX, randY)); InfiniteScroll.SetPosition(obj, r, newWorldPoint.x, bottomEdge.y - newWorldPoint.y); } } else if (t < 0 && (screenEdge.x >= c.rect.width || screenEdge.y < minEdge)) { if (RepositionLogicFunction != null) { RepositionLogicFunction(p, this, t, obj, r); } else { Vector3 topEdge = c.ViewportToWorldPoint(Vector3.one); float randX = UnityEngine.Random.Range(RepositionLogic.MinXPercent, RepositionLogic.MaxXPercent); float randY = UnityEngine.Random.Range(RepositionLogic.MinYPercent, RepositionLogic.MaxYPercent); Vector3 newWorldPoint = c.ViewportToWorldPoint(new Vector3(randX, randY)); InfiniteScroll.SetPosition(obj, r, newWorldPoint.x, topEdge.y + newWorldPoint.y); } } } } }
public void SetupPosition(InfiniteScroll p, Camera c, int index) { Vector3 screenLeft = c.ViewportToWorldPoint(Vector3.zero); Vector3 screenTop = c.ViewportToWorldPoint(Vector3.one); float start, offset; if (p.IsHorizontal) { start = screenTop.y + 1.0f; offset = screenLeft.x + GameObjectRenderers[0].bounds.size.x; } else { start = screenTop.x + 1.0f; offset = screenLeft.y + GameObjectRenderers[0].bounds.size.y; } for (int i = 0; i < GameObjects.Count; i++) { GameObject obj = GameObjects[i]; Renderer r = GameObjectRenderers[i]; if (RepositionLogic.SortingOrder != 0) { r.sortingOrder = RepositionLogic.SortingOrder; } if (RepositionLogic.PositionMode == FreeParallaxPositionMode.IndividualStartOffScreen || RepositionLogic.PositionMode == FreeParallaxPositionMode.IndividualStartOnScreen) { float x, y; if (p.IsHorizontal) { x = (RepositionLogic.PositionMode == FreeParallaxPositionMode.IndividualStartOnScreen ? r.bounds.min.x : 0); y = (RepositionLogic.PositionMode == FreeParallaxPositionMode.IndividualStartOnScreen ? r.bounds.min.y : start + r.bounds.size.y); } else { x = (RepositionLogic.PositionMode == FreeParallaxPositionMode.IndividualStartOnScreen ? r.bounds.min.x : start + r.bounds.size.x); y = (RepositionLogic.PositionMode == FreeParallaxPositionMode.IndividualStartOnScreen ? r.bounds.min.y : 0); } InfiniteScroll.SetPosition(obj, r, x, y); } else { // position in the next spot in line if (p.IsHorizontal) { offset -= (r.bounds.size.x - p.WrapOverlap); } else { offset -= (r.bounds.size.y - p.WrapOverlap); } obj.transform.rotation = Quaternion.identity; // anchor to the top of the screen if (RepositionLogic.PositionMode == FreeParallaxPositionMode.WrapAnchorTop) { if (p.IsHorizontal) { Vector3 topWorld = c.ViewportToWorldPoint(new Vector3(0.0f, 1.0f, 0.0f)); InfiniteScroll.SetPosition(obj, r, offset, topWorld.y - r.bounds.size.y); } else { Vector3 topWorld = c.ViewportToWorldPoint(new Vector3(1.0f, 0.0f, 0.0f)); InfiniteScroll.SetPosition(obj, r, topWorld.x - r.bounds.size.x, offset + r.bounds.size.y); } } else if (RepositionLogic.PositionMode == FreeParallaxPositionMode.WrapAnchorBottom) { if (p.IsHorizontal) { InfiniteScroll.SetPosition(obj, r, offset, screenLeft.y); } else { InfiniteScroll.SetPosition(obj, r, screenLeft.x, offset); } } else { // no anchor, maintain position if (p.IsHorizontal) { InfiniteScroll.SetPosition(obj, r, offset, r.bounds.min.y); } else { InfiniteScroll.SetPosition(obj, r, r.bounds.min.x, offset); } } GameObjects.RemoveAt(i); GameObjects.Insert(0, obj); GameObjectRenderers.RemoveAt(i); GameObjectRenderers.Insert(0, r); } } }