using SUISS.Core; using UnityEngine; namespace SUISSEngine { public class IslandInput : MonoBehaviour { private enum FingerPhase { Began, Moved, Ended } private struct Finger { public int id; public FingerPhase phase; public Vector2 startPosition; public float startPositionTime; public Vector2 previousPosition; public float previousPositionTime; public Vector2 currentPosition; public float currentPositionTime; public Vector2[] velocities; public int velocityIndex; public int velocityCount; public float distance; public bool hasMoved; public int lastSeenFrameIndex; } private enum State { Idle, Panning, Pinching, BuildingPanning } private enum CameraAnimation { None, Target, Deceleration } private const int InvalidFingerID = -1; private const int MouseFingerID = int.MaxValue; private const float MinMovementDistance = 0.15f; private const int VelocityBufferSize = 5; private const float MouseScrollSensitivity = 1.5f; public IsometricIsland island; [SerializeField] private float _maxOrthographicSizeFactorTablet = 0.9f; [SerializeField] private float _maxOrthographicSizeFactorPhone = 0.8f; private bool newTouchDetected; private bool _hasTouch; private int fingerCount; private Finger[] fingers; private State state; private int panningFingerID; private int pinchingFingerID; private Vector2 buildingPanningOffset; private int currentFrameIndex; private CameraAnimation cameraAnimation; private Vector2 cameraAnimationSource; private Vector2 cameraAnimationDestination; private float cameraAnimationStart; private float cameraAnimationDuration; private AnimationCurve cameraAnimationCurve; private Vector2 cameraAnimationVelocity; private float _maxOrthographicSizeFactor; private float _minPixelsPerInch; private float _maxPixelsPerInch; private int _mouseSkewGauge; protected bool _activeTouches; protected bool _activeMouse; protected virtual void Awake() { newTouchDetected = false; _activeTouches = false; _activeMouse = false; fingerCount = 0; fingers = new Finger[2]; for (int i = 0; i < fingers.Length; i++) { fingers[i].id = -1; fingers[i].velocities = new Vector2[5]; } state = State.Idle; panningFingerID = -1; pinchingFingerID = -1; _mouseSkewGauge = 0; cameraAnimation = CameraAnimation.None; { _maxOrthographicSizeFactor = _maxOrthographicSizeFactorTablet; } _hasTouch = true; IsometricIsland.IslandLoadedEvent += OnIslandLoadedEvent; IsometricIsland.IslandUnloadedEvent += OnIslandUnloadedEvent; if (IsometricIsland.Current != null) { OnIslandLoadedEvent(IsometricIsland.Current); } } protected virtual void OnDestroy() { IsometricIsland.IslandLoadedEvent -= OnIslandLoadedEvent; IsometricIsland.IslandUnloadedEvent -= OnIslandUnloadedEvent; } protected void OnIslandLoadedEvent(IsometricIsland island) { this.island = island; UpdateMinMaxPerInch(); SetInitialCameraBounds(); } protected void OnIslandUnloadedEvent() { island = null; CameraAnimation cameraAnimation = this.cameraAnimation; if (cameraAnimation == CameraAnimation.Target || cameraAnimation == CameraAnimation.Deceleration) { this.cameraAnimation = CameraAnimation.None; if (SingletonMonobehaviour.IsAvailable) { SingletonMonobehaviour.Instance.PopUnlimitedFPSRequest(this); } } } protected virtual void Update() { currentFrameIndex++; if (ShouldProcessInput()) { ProcessInput(); } if (cameraAnimation == CameraAnimation.Target) { Camera islandCamera = island.islandCamera; Vector3 position = islandCamera.transform.position; float num = cameraAnimationCurve.Evaluate(Time.realtimeSinceStartup); if (num >= 1f) { position.x = cameraAnimationDestination.x; position.y = cameraAnimationDestination.y; cameraAnimation = CameraAnimation.None; SingletonMonobehaviour.Instance.PopUnlimitedFPSRequest(this); } else { position.x = cameraAnimationSource.x + (cameraAnimationDestination.x - cameraAnimationSource.x) * num; position.y = cameraAnimationSource.y + (cameraAnimationDestination.y - cameraAnimationSource.y) * num; } islandCamera.transform.position = position; } if (!_activeTouches && cameraAnimation == CameraAnimation.Deceleration) { Camera islandCamera2 = island.islandCamera; float num2 = Time.realtimeSinceStartup - cameraAnimationStart; float num3 = Mathf.Pow(0.05f, num2); Vector3 extents = island.islandWorldBounds.extents; float num4 = extents.y / islandCamera2.orthographicSize; cameraAnimationVelocity *= num3; float num5 = Mathf.Sqrt(cameraAnimationVelocity.x * cameraAnimationVelocity.x + cameraAnimationVelocity.y * cameraAnimationVelocity.y); Vector3 position2 = islandCamera2.transform.position; position2.x += cameraAnimationVelocity.x / num4 * num2; position2.y += cameraAnimationVelocity.y / num4 * num2; islandCamera2.transform.position = position2; RestrictCameraToBounds(); if (num5 < 10f) { cameraAnimation = CameraAnimation.None; SingletonMonobehaviour.Instance.PopUnlimitedFPSRequest(this); } else { cameraAnimationStart = Time.realtimeSinceStartup; } } else if (newTouchDetected) { CancelCameraAnimation(); } } public void SetInitialCameraBounds() { island.islandCamera.orthographicSize = island.preferedInitialZoomLevel; CenterViewOn(GetInitialCameraPosition(), animated: false); RestrictCameraToBounds(); } public void RestrictCameraToBounds() { Camera islandCamera = island.islandCamera; float num = islandCamera.orthographicSize * 2f * island.pixelsPerUnit / islandCamera.pixelRect.height * island.dpi; if (num < _minPixelsPerInch) { islandCamera.orthographicSize = _minPixelsPerInch * islandCamera.pixelRect.height / (2f * island.pixelsPerUnit * island.dpi); } else if (num > _maxPixelsPerInch) { islandCamera.orthographicSize = _maxPixelsPerInch * islandCamera.pixelRect.height / (2f * island.pixelsPerUnit * island.dpi); } Bounds islandWorldBounds = island.islandWorldBounds; Vector3 position = islandCamera.transform.position; float num2 = position.x - islandCamera.orthographicSize * islandCamera.aspect; Vector3 min = islandWorldBounds.min; if (num2 < min.x) { Vector3 min2 = islandWorldBounds.min; position.x = min2.x + islandCamera.orthographicSize * islandCamera.aspect; } float num3 = position.y - islandCamera.orthographicSize; Vector3 min3 = islandWorldBounds.min; if (num3 < min3.y) { Vector3 min4 = islandWorldBounds.min; position.y = min4.y + islandCamera.orthographicSize; } float num4 = position.x + islandCamera.orthographicSize * islandCamera.aspect; Vector3 max = islandWorldBounds.max; if (num4 > max.x) { float num5 = islandCamera.orthographicSize * islandCamera.aspect; Vector3 extents = islandWorldBounds.extents; if (num5 > extents.x) { Vector3 center = islandWorldBounds.center; position.x = center.x; } else { Vector3 max2 = islandWorldBounds.max; position.x = max2.x - islandCamera.orthographicSize * islandCamera.aspect; } } float num6 = position.y + islandCamera.orthographicSize; Vector3 max3 = islandWorldBounds.max; if (num6 > max3.y) { float orthographicSize = islandCamera.orthographicSize; Vector3 extents2 = islandWorldBounds.extents; if (orthographicSize > extents2.y) { Vector3 center2 = islandWorldBounds.center; position.y = center2.y; } else { Vector3 max4 = islandWorldBounds.max; position.y = max4.y - islandCamera.orthographicSize; } } islandCamera.transform.position = position; } public void CenterViewOn(GridIndex index, bool animated) { GridPoint point = new GridPoint(index); point.u += 0.5f; point.v += 0.5f; CenterViewOn(point, animated); } public void CenterViewOn(GridPoint point, bool animated) { Vector2 target = (Vector2)island.grid.transform.position + island.grid.GetPositionForGridPoint(point); CenterViewOn(target, animated); } public void CenterViewOn(GameObject gameObject, bool animated) { SpriteRenderer component = gameObject.GetComponent(); if (component == null) { CenterViewOn(gameObject.transform.position, animated); } else { CenterViewOn(component.bounds.center, animated); } } public void CenterViewOn(Vector2 target, bool animated) { if (state != 0) { return; } Camera islandCamera = island.islandCamera; Bounds islandWorldBounds = island.islandWorldBounds; Vector2 vector = default(Vector2); vector.x = islandCamera.orthographicSize * islandCamera.aspect; vector.y = islandCamera.orthographicSize; float x = vector.x; Vector3 extents = islandWorldBounds.extents; if (x > extents.x) { Vector3 center = islandWorldBounds.center; target.x = center.x; } else { float num = target.x - vector.x; Vector3 min = islandWorldBounds.min; if (num < min.x) { Vector3 min2 = islandWorldBounds.min; target.x = min2.x + vector.x; } else { float num2 = target.x + vector.x; Vector3 max = islandWorldBounds.max; if (num2 > max.x) { Vector3 max2 = islandWorldBounds.max; target.x = max2.x - vector.x; } } } float y = vector.y; Vector3 extents2 = islandWorldBounds.extents; if (y > extents2.y) { Vector3 center2 = islandWorldBounds.center; target.y = center2.y; } else { float num3 = target.y - vector.y; Vector3 min3 = islandWorldBounds.min; if (num3 < min3.y) { Vector3 min4 = islandWorldBounds.min; target.y = min4.y + vector.y; } else { float num4 = target.y + vector.y; Vector3 max3 = islandWorldBounds.max; if (num4 > max3.y) { Vector3 max4 = islandWorldBounds.max; target.y = max4.y - vector.y; } } } if (animated) { cameraAnimationSource = islandCamera.transform.position; cameraAnimationDestination = target; cameraAnimationStart = Time.realtimeSinceStartup; cameraAnimationDuration = 0.5f; cameraAnimationCurve = AnimationCurve.EaseInOut(cameraAnimationStart, 0f, cameraAnimationStart + cameraAnimationDuration, 1f); cameraAnimationCurve.preWrapMode = WrapMode.ClampForever; cameraAnimationCurve.postWrapMode = WrapMode.ClampForever; cameraAnimation = CameraAnimation.Target; SingletonMonobehaviour.Instance.PushUnlimitedFPSRequest(this); } else { Vector3 position = islandCamera.transform.position; position.x = target.x; position.y = target.y; islandCamera.transform.position = position; } } public void CancelCameraAnimation() { cameraAnimation = CameraAnimation.None; SingletonMonobehaviour.Instance.PopUnlimitedFPSRequest(this); } protected virtual bool ShouldProcessInput() { return true; } protected void ProcessInput() { ProcessTouches(); ProcessMouse(); ProcessFingers(); EndFingers(); } protected virtual bool HandleTapAt(Vector2 position) { if (island == null || island.islandCamera == null) { return false; } Vector2 vector = island.islandCamera.ScreenToWorldPoint(position); if (island.builder != null && (island.builder.isBuilding || island.builder.isBuildingRoad)) { if (island.builder.isBuildingRoad && island.grid != null) { GridIndex index = island.grid.ConvertIslandCoordinateToGridIndex(vector); if (index.isInvalid) { return false; } island.builder.UpdateRoad(index); return true; } return false; } GameObject closestGameObjectAt = GetClosestGameObjectAt(vector); if (island.destroyer != null && island.destroyer.isSelecting && island.grid != null) { Building building = null; if (closestGameObjectAt != null) { building = closestGameObjectAt.GetComponent(); } if (building != null) { island.destroyer.ClickedBuilding(building); return true; } GridIndex index2 = island.grid.ConvertIslandCoordinateToGridIndex(vector); if (!index2.isInvalid) { GridElement gridElement = island.grid[index2]; if (gridElement != null && gridElement.Tile != null) { Road component = gridElement.Tile.GetComponent(); if (component != null) { island.destroyer.ClickedRoad(component); return true; } building = gridElement.Tile.GetComponent(); if (building != null) { island.destroyer.ClickedBuilding(building); return true; } } } } else if (closestGameObjectAt != null) { Clickable component2 = closestGameObjectAt.GetComponent(); if (component2 != null) { component2.OnClick(component2.gameObject); return true; } } else if (island.builder != null && island.grid != null) { GridIndex index3 = island.grid.ConvertIslandCoordinateToGridIndex(vector); if (!index3.isInvalid) { GridElement gridElement2 = island.grid[index3]; if (gridElement2 != null) { GridTile tile = gridElement2.Tile; if (tile != null) { Clickable component3 = tile.GetComponent(); if (component3 != null) { component3.OnClick(tile.gameObject); return true; } } } } } Boid.RunAwayFrom(island.grid.ConvertIslandCoordinateToGridIndex(vector)); return false; } protected GameObject GetClosestGameObjectAt(Vector2 position) { SpriteRenderer spriteRenderer = null; GameObject result = null; Collider2D[] array = Physics2D.OverlapPointAll(position); foreach (Collider2D collider2D in array) { SpriteRenderer componentInChildren = collider2D.GetComponentInChildren(); if (componentInChildren == null) { return collider2D.gameObject; } if (spriteRenderer == null || componentInChildren.sortingOrder > spriteRenderer.sortingOrder) { spriteRenderer = componentInChildren; result = collider2D.gameObject; } } return result; } protected virtual float GetInitialCameraPPI() { return (_minPixelsPerInch + _maxPixelsPerInch) / 2f; } protected virtual Vector2 GetInitialCameraPosition() { return island.preferedInitialPosition; } private void ProcessTouches() { newTouchDetected = false; _activeTouches = false; if (UnityEngine.Input.touchCount > 0) { Touch[] touches = Input.touches; Touch[] array = touches; Vector2 vector = default(Vector2); for (int i = 0; i < array.Length; i++) { Touch touch = array[i]; int num = -1; if (touch.phase == TouchPhase.Began) { newTouchDetected = true; _activeTouches = true; if (fingerCount < fingers.Length && island.islandCamera.pixelRect.Contains(touch.position)) { num = fingerCount; fingers[num].id = touch.fingerId; fingers[num].phase = FingerPhase.Began; fingers[num].startPosition = touch.position; fingers[num].startPositionTime = Time.realtimeSinceStartup; fingers[num].previousPosition = touch.position; fingers[num].previousPositionTime = Time.realtimeSinceStartup; fingers[num].hasMoved = false; fingers[num].velocityIndex = -1; fingers[num].velocityCount = 0; fingerCount++; } } else if (touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled) { num = IndexOfFingerID(touch.fingerId); if (num >= 0) { fingers[num].phase = FingerPhase.Ended; } } else { _activeTouches = true; num = IndexOfFingerID(touch.fingerId); } if (num < 0) { continue; } fingers[num].lastSeenFrameIndex = currentFrameIndex; fingers[num].currentPosition = touch.position; fingers[num].currentPositionTime = Time.realtimeSinceStartup; fingers[num].distance = (fingers[num].currentPosition - fingers[num].startPosition).magnitude; if (!fingers[num].hasMoved && fingers[num].distance > 0.15f * island.dpi) { fingers[num].hasMoved = true; if (fingers[num].phase == FingerPhase.Began) { fingers[num].phase = FingerPhase.Moved; } } float num2 = fingers[num].currentPositionTime - fingers[num].previousPositionTime; if (num2 > 0f) { vector.x = (fingers[num].currentPosition.x - fingers[num].previousPosition.x) / num2; vector.y = (fingers[num].currentPosition.y - fingers[num].previousPosition.y) / num2; fingers[num].velocityIndex = (fingers[num].velocityIndex + 1) % 5; fingers[num].velocities[fingers[num].velocityIndex] = vector; if (fingers[num].velocityCount < 5) { fingers[num].velocityCount++; } } } } if (!_hasTouch) { return; } for (int j = 0; j < fingerCount; j++) { if (fingers[j].id != int.MaxValue && currentFrameIndex - fingers[j].lastSeenFrameIndex > 0) { fingers[j].phase = FingerPhase.Ended; } } } private void ProcessMouse() { _activeMouse = false; if (_activeTouches || newTouchDetected) { return; } int num = -1; if (Input.GetMouseButtonDown(0)) { SingletonMonobehaviour.Instance.PushUnlimitedFPSRequest(this); if (fingerCount < fingers.Length && island.islandCamera.pixelRect.Contains(UnityEngine.Input.mousePosition)) { _mouseSkewGauge++; num = fingerCount; fingers[num].id = int.MaxValue; fingers[num].phase = FingerPhase.Began; fingers[num].startPosition = UnityEngine.Input.mousePosition; fingers[num].startPositionTime = Time.realtimeSinceStartup; fingers[num].previousPosition = UnityEngine.Input.mousePosition; fingers[num].previousPositionTime = Time.realtimeSinceStartup; fingers[num].hasMoved = false; fingers[num].velocityIndex = -1; fingers[num].velocityCount = 0; fingerCount++; _activeMouse = true; } } if (Input.GetMouseButtonUp(0)) { SingletonMonobehaviour.Instance.PopUnlimitedFPSRequest(this); num = IndexOfFingerID(int.MaxValue); if (num >= 0) { _mouseSkewGauge--; fingers[num].phase = FingerPhase.Ended; } _activeMouse = false; } else if (Input.GetMouseButton(0)) { num = IndexOfFingerID(int.MaxValue); _activeMouse = true; } else if (_mouseSkewGauge != 0) { _mouseSkewGauge = 0; num = IndexOfFingerID(int.MaxValue); if (num < 0) { UnityEngine.Debug.LogError("fingerIndex of MouseFingerID < 0"); } else { fingers[num].phase = FingerPhase.Ended; } } Vector2 mouseScrollDelta = Input.mouseScrollDelta; float y = mouseScrollDelta.y; if (!Mathf.Approximately(0f, y)) { Vector3 size = island.islandWorldBounds.size; float num2 = size.y * 0.5f; float num3 = island.islandCamera.orthographicSize / num2; float num4 = y * 1.5f * Time.unscaledDeltaTime; num3 -= num4; island.islandCamera.orthographicSize = num3 * num2; RestrictCameraToBounds(); } if (num < 0) { return; } fingers[num].currentPosition = UnityEngine.Input.mousePosition; fingers[num].currentPositionTime = Time.realtimeSinceStartup; fingers[num].distance = (fingers[num].currentPosition - fingers[num].startPosition).magnitude; if (!fingers[num].hasMoved && fingers[num].distance >= 0.120000005f * island.dpi) { fingers[num].hasMoved = true; if (fingers[num].phase == FingerPhase.Began) { fingers[num].phase = FingerPhase.Moved; } } } private void ProcessFingers() { Camera islandCamera = island.islandCamera; bool flag = false; for (int i = 0; i < fingerCount; i++) { if (fingers[i].phase == FingerPhase.Moved) { switch (state) { case State.Idle: CancelCameraAnimation(); state = State.Panning; SingletonMonobehaviour.Instance.PushUnlimitedFPSRequest(this); panningFingerID = fingers[i].id; if (island.grid != null && island.builder != null && island.builder.isBuilding) { GameObject closestGameObjectAt = GetClosestGameObjectAt(islandCamera.ScreenToWorldPoint(fingers[i].startPosition)); GridTile component; if (closestGameObjectAt != null && (component = closestGameObjectAt.GetComponent()) != null && component == island.builder.currentTile) { state = State.BuildingPanning; buildingPanningOffset = (Vector2)islandCamera.ScreenToWorldPoint(fingers[i].startPosition) - ((Vector2)component.grid.transform.position + component.element.Origin + new Vector2(0f, island.grid.elementSize.y * 0.5f)); } } break; case State.Panning: if (fingers[i].id != panningFingerID) { state = State.Pinching; SingletonMonobehaviour.Instance.PushUnlimitedFPSRequest(this); pinchingFingerID = fingers[i].id; } break; } } else { if (fingers[i].phase != FingerPhase.Ended) { continue; } switch (state) { case State.Panning: case State.BuildingPanning: { if (fingers[i].id != panningFingerID) { break; } state = State.Idle; panningFingerID = -1; if (fingers[i].velocityCount <= 0) { break; } Vector2 a = Vector2.zero; int num = 0; int velocityCount = fingers[i].velocityCount; for (int j = num; j < velocityCount; j++) { int num2 = fingers[i].velocityIndex - j; if (num2 < 0) { num2 += 5; } a += fingers[i].velocities[num2]; } a /= velocityCount - num; if (a.magnitude / island.dpi > 0.2f) { cameraAnimation = CameraAnimation.Deceleration; cameraAnimationStart = Time.realtimeSinceStartup; cameraAnimationVelocity = -a; } else { SingletonMonobehaviour.Instance.PopUnlimitedFPSRequest(this); } break; } case State.Pinching: if (fingers[i].id == panningFingerID) { state = State.Panning; panningFingerID = pinchingFingerID; pinchingFingerID = -1; } else if (fingers[i].id == pinchingFingerID) { state = State.Panning; pinchingFingerID = -1; } break; } if (!fingers[i].hasMoved && !HandleTapAt(fingers[i].currentPosition)) { flag = true; } } } if (state == State.Panning || state == State.Pinching) { int num3 = IndexOfFingerID(panningFingerID); int num4 = (state != State.Pinching) ? (-1) : IndexOfFingerID(pinchingFingerID); Vector2 previousPosition = default(Vector2); Vector2 currentPosition = default(Vector2); if (state == State.Pinching) { previousPosition.x = (fingers[num3].previousPosition.x + fingers[num4].previousPosition.x) * 0.5f; previousPosition.y = (fingers[num3].previousPosition.y + fingers[num4].previousPosition.y) * 0.5f; currentPosition.x = (fingers[num3].currentPosition.x + fingers[num4].currentPosition.x) * 0.5f; currentPosition.y = (fingers[num3].currentPosition.y + fingers[num4].currentPosition.y) * 0.5f; } else { previousPosition = fingers[num3].previousPosition; currentPosition = fingers[num3].currentPosition; } Vector3 vector = default(Vector3); vector.x = (0f - (currentPosition.x - previousPosition.x)) / islandCamera.pixelRect.width * (islandCamera.orthographicSize * 2f * islandCamera.aspect); vector.y = (0f - (currentPosition.y - previousPosition.y)) / islandCamera.pixelRect.height * (islandCamera.orthographicSize * 2f); vector.z = 0f; islandCamera.transform.position += vector; if (state == State.Pinching) { float magnitude = (fingers[num3].previousPosition - fingers[num4].previousPosition).magnitude; float num5 = (fingers[num3].currentPosition - fingers[num4].currentPosition).magnitude; float num6 = islandCamera.orthographicSize * (magnitude / num5) * 2f * island.pixelsPerUnit / islandCamera.pixelRect.height * island.dpi; if (num6 < _minPixelsPerInch) { num5 = islandCamera.orthographicSize * 2f * magnitude * island.pixelsPerUnit * island.dpi / (_minPixelsPerInch * islandCamera.pixelRect.height); } else if (num6 > _maxPixelsPerInch) { num5 = islandCamera.orthographicSize * 2f * magnitude * island.pixelsPerUnit * island.dpi / (_maxPixelsPerInch * islandCamera.pixelRect.height); } islandCamera.orthographicSize *= magnitude / num5; float x = currentPosition.x; Vector2 center = islandCamera.pixelRect.center; vector.x = (x - center.x) / islandCamera.pixelRect.width * (islandCamera.orthographicSize * 2f * islandCamera.aspect) * ((num5 - magnitude) / magnitude); float y = currentPosition.y; Vector2 center2 = islandCamera.pixelRect.center; vector.y = (y - center2.y) / islandCamera.pixelRect.height * (islandCamera.orthographicSize * 2f) * ((num5 - magnitude) / magnitude); vector.z = 0f; islandCamera.transform.position += vector; } RestrictCameraToBounds(); } else if (state == State.BuildingPanning) { int num7 = IndexOfFingerID(panningFingerID); GridIndex newIndex = island.grid.ConvertIslandCoordinateToGridIndex((Vector2)islandCamera.ScreenToWorldPoint(fingers[num7].currentPosition) - buildingPanningOffset); island.builder.UpdateBuild(newIndex); } else if (flag) { GameEvents.Invoke(new UnemiShouldCloseEvent(this)); } } private void EndFingers() { int num = 0; while (num < fingerCount) { if (fingers[num].phase == FingerPhase.Ended) { for (int i = num; i < fingerCount - 1; i++) { fingers[i] = fingers[i + 1]; } fingers[fingerCount - 1].id = -1; fingerCount--; } else { fingers[num].previousPosition = fingers[num].currentPosition; fingers[num].previousPositionTime = fingers[num].currentPositionTime; num++; } } } private int IndexOfFingerID(int id) { for (int i = 0; i < fingers.Length; i++) { if (fingers[i].id == id) { return i; } } return -1; } private void UpdateMinMaxPerInch() { Vector3 extents = island.islandBounds.extents; float x = extents.x; Vector3 extents2 = island.islandBounds.extents; float num = x / extents2.y; float num2 = island.islandCamera.pixelRect.width / island.islandCamera.pixelRect.height; float num3; if (num > num2) { Vector3 extents3 = island.islandBounds.extents; num3 = extents3.y; } else { Vector3 extents4 = island.islandBounds.extents; num3 = extents4.x / num2; } float num4 = num3 * _maxOrthographicSizeFactor; _maxPixelsPerInch = num4 * 2f * island.pixelsPerUnit / island.islandCamera.pixelRect.height * island.dpi; _minPixelsPerInch = _maxPixelsPerInch * 0.5f; } } }