void Update() { // calculate average position of each player and grappling hook reticles int sources = 0; Vector3 newAimOffset1 = Vector3.zero; if (grapple1.GetReticle(1) != null && grapple1.GetReticle(1).activeSelf) { newAimOffset1 += (grapple1.GetReticle(1).transform.position - player1.transform.position); sources++; } if (grapple1.GetReticle(2) != null && grapple1.GetReticle(2).activeSelf) { newAimOffset1 += (grapple1.GetReticle(2).transform.position - player1.transform.position); sources++; } if (sources > 0) { newAimOffset1 /= sources; } sources = 0; Vector3 newAimOffset2 = Vector3.zero; if (grapple2.GetReticle(1) != null && grapple2.GetReticle(1).activeSelf) { newAimOffset2 += (grapple2.GetReticle(1).transform.position - player2.transform.position); sources++; } if (grapple2.GetReticle(2) != null && grapple2.GetReticle(2).activeSelf) { newAimOffset2 += (grapple2.GetReticle(2).transform.position - player2.transform.position); sources++; } if (sources > 0) { newAimOffset2 /= sources; } // lerp screen centers to new screen centers aimOffset1 = Vector3.Lerp(aimOffset1, newAimOffset1, lerpSpeed); aimOffset2 = Vector3.Lerp(aimOffset2, newAimOffset2, lerpSpeed); screenCenter1 = player1.transform.position + (aimOffset1 / 2); screenCenter2 = player2.transform.position + (aimOffset2 / 2); // center of each split screen Vector3 center; // ratio of screen width to height float widthHeightRatio = 1f * Screen.width / Screen.height; // corners of camera Vector3 topLeft = new Vector3(-widthHeightRatio, 1f, 0f); Vector3 topRight = new Vector3(widthHeightRatio, 1f, 0f); Vector3 bottomLeft = new Vector3(-widthHeightRatio, -1f, 0f); Vector3 bottomRight = new Vector3(widthHeightRatio, -1f, 0f); // point between players Vector3 centerPoint = (screenCenter1 + screenCenter2) / 2; // direction from one player to the other Vector3 splitOrthogonal = screenCenter1 - centerPoint; // direction of split Vector3 split = Vector3.Cross(splitOrthogonal, Vector3.forward).normalized; // if split is intersecting with left and right of screen if (Mathf.Abs(split.x) > Mathf.Abs(split.y) * widthHeightRatio) { // intersecting points Vector3 splitIntersection1 = new Vector3(widthHeightRatio, split.y * (widthHeightRatio / split.x), 0f); Vector3 splitIntersection2 = -splitIntersection1; // if player1 is on the top if (splitOrthogonal.y > 0) { // location in center of each screen center = cameraSize * Centroid4(topLeft, topRight, splitIntersection1, splitIntersection2); } // if player1 is on the bottom else { // location in center of each screen center = cameraSize * Centroid4(bottomLeft, bottomRight, splitIntersection1, splitIntersection2); } } // if split is intersecting with top and bottom of screen else { // intersecting points Vector3 splitIntersection1 = new Vector3(split.x * (1f / split.y), 1f, 0f); Vector3 splitIntersection2 = -splitIntersection1; // if player1 is on the right if (splitOrthogonal.x > 0) { // location in center of each screen center = cameraSize * Centroid4(bottomRight, topRight, splitIntersection1, splitIntersection2); } // if player1 is on the left else { // location in center of each screen center = cameraSize * Centroid4(bottomLeft, topLeft, splitIntersection1, splitIntersection2); } } // feathered location for split screen cameras float featherAmount = ((screenCenter1 - screenCenter2).magnitude - splitscreenDistanceMultiplier * cameraSize) / (centerCameraDistanceMultiplier * cameraSize - splitscreenDistanceMultiplier * cameraSize); if (featherAmount < 0) { featherAmount = 0; } if (featherAmount > 1) { featherAmount = 1; } Vector3 feather = (1 - featherAmount) * splitscreenDistanceMultiplier * cameraSize / 2 * (screenCenter2 - screenCenter1).normalized - featherAmount * center; // set positions of all cameras // main camera should be between two players transform.position = (screenCenter1 + screenCenter2) / 2 + offset; // these cameras should smoothly transition according to feather cam1.transform.position = screenCenter1 + feather + offset; cam2.transform.position = screenCenter2 - feather + offset; // set orientation of renderer based on orientation of players, split should be perpendicular to vector between players vRenderer.transform.up = screenCenter2 - screenCenter1; divider.transform.up = vRenderer.transform.up; // scale divider according to distance between players float scale = dividerScaleMultiplier * (screenCenter1 - screenCenter2).magnitude; if (scale > maxDividerSize) { scale = maxDividerSize; } divider.transform.localScale = new Vector3(1f, scale, 1f); // if the screen should split, show the renderer if ((screenCenter1 - screenCenter2).magnitude > splitscreenDistanceMultiplier * cameraSize) { vRenderer.SetActive(true); divider.SetActive(true); } else { vRenderer.SetActive(false); divider.SetActive(false); } }