導語:
在屏幕適配之正交攝像機(Orthographic Camera)下游戲區域適配中我們學習了如何在正交攝像機下進行游戲區域的適配,下面我們來學習如何在透視攝像機下如何進行游戲區域的適配。
1.創建一個Camera(攝像機),將Camera的Projection設置為PersPective
2.設置Field of View 為10(開發者可根據需要自行調整FieldOfView的值)
3.上代碼
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CameraAutoFix : MonoBehaviour { [SerializeField] private Transform background; private float designOrthographicSize; private float designHeight; private float designWidth; private float designAspect; private Camera _camera; public void Awake() { FixScreen(); } private void FixScreen() { ScreenOrientation designAutoRotation = Screen.orientation; _camera = this.gameObject.GetComponent<Camera>(); bool isOrthographic = _camera.orthographic; float aspect = Screen.width / (float)Screen.height; designHeight = 1920f; designWidth = 1080f; designAspect = designWidth / designHeight; if (isOrthographic) { OrthographicFix(designAutoRotation, aspect); return; } PerspectiveFix(designAutoRotation, aspect); } private void OrthographicFix(ScreenOrientation designAutoRotation, float aspect) { designOrthographicSize = 9.6f; float widthOrthographicSize = designOrthographicSize * designAspect; switch (designAutoRotation) { case ScreenOrientation.Portrait: if (aspect < designAspect) { _camera.orthographicSize = widthOrthographicSize / aspect; } if (aspect > designAspect) { _camera.orthographicSize = designOrthographicSize; //_camera.orthographicSize = designOrthographicSize * (aspect / designAspect); } break; case ScreenOrientation.AutoRotation: break; case ScreenOrientation.LandscapeLeft: break; case ScreenOrientation.LandscapeRight: break; case ScreenOrientation.PortraitUpsideDown: break; default: break; } } private void PerspectiveFix(ScreenOrientation designAutoRotation,float aspect) { float designFieldOfView = 10.0f; switch (designAutoRotation) { case ScreenOrientation.Portrait: if (aspect < designAspect) { _camera.fieldOfView = designFieldOfView * (designAspect / aspect); } break; case ScreenOrientation.AutoRotation: break; case ScreenOrientation.LandscapeLeft: break; case ScreenOrientation.LandscapeRight: break; case ScreenOrientation.PortraitUpsideDown: break; default: break; } if (background) { Vector3 scale = background.localScale; float scaleX = scale.x * (aspect / designAspect); background.localScale = new Vector3(scaleX * (_camera.fieldOfView / designFieldOfView), scaleX / aspect * (_camera.fieldOfView / designFieldOfView), scale.z); } } public struct CamereArea { public float height; public float width; public override string ToString() { return "(height:" + height + ";width:" + width + ")"; } } public CamereArea GetCameraAreaWithDistance(float distance) { float halfFOV = (_camera.fieldOfView * 0.5f) * Mathf.Deg2Rad; float aspect = _camera.aspect; float height = distance * Mathf.Tan(halfFOV); float width = height * aspect; CamereArea camereArea = new CamereArea() { height = height, width = width }; return camereArea; } public Vector3 ConvertWordPositionToCameraPosition(Vector3 wordPosition, float aimZ) { CamereArea camereArea = GetCameraAreaWithDistance(wordPosition.z - _camera.transform.position.z); CamereArea camereAreaAim = GetCameraAreaWithDistance(aimZ - _camera.transform.position.z); //Debug.Log("camereArea=" + camereArea + ",camereAreaAim=" + camereAreaAim); float heightRadio = camereAreaAim.height / (camereArea.height); float widthRadio = camereAreaAim.width / (camereArea.width); // Debug.Log("wordPosition:(" + wordPosition.x + "," + wordPosition.x + "," + wordPosition.z + ")"); // Debug.Log("heightRadio=" + heightRadio + ",widthRadio=" + widthRadio); Vector3 convertPosition = new Vector3(wordPosition.x * widthRadio, wordPosition.y * heightRadio, wordPosition.z); return convertPosition; } }