public void Clear()
        {
            _numberOfCameraType = NumberOfCamera.None;

            if (_cameraDataList == null)
            {
                _cameraDataList = new List <CameraData>();
            }
            if (_cam2CameraData == null)
            {
                _cam2CameraData = new Dictionary <Camera, CameraData>();
            }
            if (_renderCameraDataList == null)
            {
                _renderCameraDataList = new List <CameraData>();
            }
            _cameraDataList.Clear();
            _cam2CameraData.Clear();
            _renderCameraDataList.Clear();
            _nCameras       = 0;
            _nRenderCameras = 0;

            _mainData = null;

            _dualCameraType = DualCameraType.None;
            _leftEyeData    = null;
            _rightEyeData   = null;

            _worldToCameraMatrix = Matrix4x4.identity;
            _zDepthToCam         = 0.0f;

            _centerRotation = Quaternion.identity;
            _centerForward  = Vector3.forward;
            _centerPos      = Vector3.zero;

            _persOrthoType = PersOrthoType.Unknown;

            _isAllSameForward  = false;
            _isAllOrthographic = false;
        }
        public void Refresh(bool isRefreshForce, bool isRefreshMatrix)
        {
            //그대로 유지할지 확인
            //- 카메라의 개수
            //- 현재 카메라가 유효한지


            //자동 갱신 옵션이 꺼진 경우
            if (!_isAutomaticRefresh)
            {
                if (isRefreshMatrix)
                {
                    RefreshMatrix();
                }
                return;
            }

            //씬의 카메라를 계속 참조하는건 옳지 않다.
            //현재 카메라가 설정되었다면 외부에 새로운 카메라가 생겼다 할지라도 갱신하지는 않는다.

            bool isNeedToRefresh = false;

            if (!isRefreshForce)
            {
                if (_numberOfCameraType == NumberOfCamera.None ||
                    _mainData == null ||
                    _cameraDataList.Count == 0 ||
                    _refreshKey < 0)
                {
                    //초기화 된 상태이거나 씬의 카메라 개수가 다르다면
                    isNeedToRefresh = true;
                }
                else
                {
                    //존재하는 카메라가 유효하지 않는다면
                    if (_numberOfCameraType == NumberOfCamera.Single)
                    {
                        if (!IsLookPortrait(_mainData._camera))
                        {
                            //Single 카메라가 제대로 바라보고 있지 않다면
                            isNeedToRefresh = true;
                        }
                    }
                    else if (_numberOfCameraType == NumberOfCamera.Multiple)
                    {
                        _cal_curCamData = null;
                        for (int i = 0; i < _cameraDataList.Count; i++)
                        {
                            _cal_curCamData = _cameraDataList[i];

                            //하나씩 테스트하여 null이거나 제대로 바라보고 있지 않다면
                            if (_cal_curCamData == null || !IsLookPortrait(_cal_curCamData._camera))
                            {
                                isNeedToRefresh = true;
                                break;
                            }
                        }
                    }
                }
            }

            if (!isNeedToRefresh)
            {
                //제대로 동작 중이다.
                //Matrix만 갱신하고 끝
                if (isRefreshMatrix)
                {
                    RefreshMatrix();
                }

                return;
            }

            //기존에 설정된 카메라가 아직 유효하다.
            int nSceneCameras = Camera.allCamerasCount;

            if (nSceneCameras == 0)
            {
                //카메라가 없네요.
                if (_numberOfCameraType != NumberOfCamera.None)
                {
                    Clear();
                }
                return;
            }

            //다시 Refresh를 해야한다.
            if (_numberOfCameraType != NumberOfCamera.None)
            {
                //일단 초기화
                Clear();
            }

            //Debug.Log("새로운 카메라 탐색");


            //씬 카메라를 모두 갱신해주자. (일단 VR 모드 상관없이)
            if (nSceneCameras > 0)
            {
                Camera[] sceneCameras = Camera.allCameras;

                for (int i = 0; i < sceneCameras.Length; i++)
                {
                    _cal_curSceneCamera = sceneCameras[i];
                    if (_cal_curSceneCamera != null && IsLookPortrait(_cal_curSceneCamera))
                    {
                        //바라보고 있는 카메라다. > 일단 모두 추가
                        CameraData newCamData = new CameraData(_cal_curSceneCamera);
                        _cameraDataList.Add(newCamData);
                        _cam2CameraData.Add(_cal_curSceneCamera, newCamData);
                        if (_parentPortrait._isForceCamSortModeToOrthographic)
                        {
                            //강제로 Orthographic으로 고정한다.
                            _cal_curSceneCamera.transparencySortMode = TransparencySortMode.Orthographic;
                        }
                    }
                }

                _nCameras = _cameraDataList.Count;

                if (_nCameras == 0)
                {
                    //실제 유효한 카메라가 없다.
                    _numberOfCameraType = NumberOfCamera.None;
                    _persOrthoType      = PersOrthoType.Unknown;

                    //Debug.LogError("> 카메라 없음");
                }
                else
                {
                    if (_nCameras == 1 || _vrSupportMode != apPortrait.VR_SUPPORT_MODE.MultiCamera)
                    {
                        //싱글 카메라 (카메라가 한개이거나 [멀티 카메라 VR]을 지원하지 않는 경우)
                        _numberOfCameraType = NumberOfCamera.Single;

                        _mainData = _cameraDataList[0];

                        _persOrthoType = (_mainData._camera.orthographic ? PersOrthoType.Orthographic : PersOrthoType.Perspective);

                        //Debug.LogWarning("> 1개의 카메라");

                        _renderCameraDataList.Add(_mainData);                        //렌더 카메라는 1개
                        _nRenderCameras = 1;
                    }
                    else
                    {
                        //멀티 카메라
                        _numberOfCameraType = NumberOfCamera.Multiple;

                        //메인 카메라를 찾자
                        //카메라의 속성을 먼저 보자

                        //- 왼쪽 눈, 오른쪽 눈에 해당하는 카메라를 찾는다. > 존재하면 Center Rotation을 만들 수 있다.

                        //1) LR 둘다 있을 때 > LR 타입 + L이 메인 + 중점에서 Matrix 계산
                        //2) LR 하나라도 없을 때 > "알 수 없는" 타입 + 첫번째 카메라가 메인 + 전체 중점에서 Matrix 계산

                        _cal_curCamData = null;

                        //두바퀴 돌아서 체크
                        //일단 Left, Right 타입을 체크한다.

                        for (int i = 0; i < _nCameras; i++)
                        {
                            _cal_curCamData = _cameraDataList[i];
                            _renderCameraDataList.Add(_cal_curCamData);                            //<<렌더 카메라로 추가한다.

                            switch (_cal_curCamData._camera.stereoTargetEye)
                            {
                            case StereoTargetEyeMask.Left:
                            {
                                if (_leftEyeData == null)
                                {
                                    _leftEyeData = _cal_curCamData;
                                }
                            }
                            break;

                            case StereoTargetEyeMask.Right:
                            {
                                if (_rightEyeData == null)
                                {
                                    _rightEyeData = _cal_curCamData;
                                }
                            }
                            break;
                            }
                        }

                        _nRenderCameras = _renderCameraDataList.Count;

                        //두번째 체크. 만약 LR 카메라가 하나라도 발견되지 않았다면, 이름이라도 확인하자.
                        if (_leftEyeData == null || _rightEyeData == null)
                        {
                            _cal_curCamData = null;
                            for (int i = 0; i < _nCameras; i++)
                            {
                                _cal_curCamData = _cameraDataList[i];

                                string camName = _cal_curCamData._transform.gameObject.name.ToLower();

                                if (camName.Contains("left"))
                                {
                                    //이름에 Left가 들어갔다면
                                    if (_leftEyeData == null)
                                    {
                                        _leftEyeData = _cal_curCamData;
                                    }
                                }
                                else if (camName.Contains("right"))
                                {
                                    //이름에 Right가 들어갔다면
                                    if (_rightEyeData == null)
                                    {
                                        _rightEyeData = _cal_curCamData;
                                    }
                                }

                                if (_leftEyeData != null && _rightEyeData != null)
                                {
                                    break;
                                }
                            }
                        }

                        //LR 타입 체크
                        if (_leftEyeData != null && _rightEyeData != null)
                        {
                            //LR 둘다 있다.
                            _dualCameraType = DualCameraType.LeftRight;
                            _mainData       = _leftEyeData;

                            if (_leftEyeData._camera.orthographic && _rightEyeData._camera.orthographic)
                            {
                                _persOrthoType = PersOrthoType.Orthographic;
                            }
                            else if (!_leftEyeData._camera.orthographic && !_rightEyeData._camera.orthographic)
                            {
                                _persOrthoType = PersOrthoType.Perspective;
                            }
                            else
                            {
                                _persOrthoType = PersOrthoType.Mixed;
                            }

                            //Debug.LogWarning("> LR 두개의 카메라");
                        }
                        else
                        {
                            //LR 둘중 하나라도 없다.
                            _dualCameraType = DualCameraType.Unknown;
                            _mainData       = _cameraDataList[0];

                            _persOrthoType = (_mainData._camera.orthographic ? PersOrthoType.Orthographic : PersOrthoType.Perspective);

                            //Debug.LogWarning("> 여러개의 카메라");
                        }
                    }
                }
            }

            //RefreshKey도 교체하자
            if (_refreshKey < 0)
            {
                _refreshKey = 10;
            }
            else
            {
                _refreshKey++;
                if (_refreshKey > 9999)
                {
                    _refreshKey = 10;
                }
            }

            if (isRefreshMatrix)
            {
                RefreshMatrix();
            }
        }
        public int SetCameras(params Camera[] cameras)
        {
            if (cameras == null)
            {
                return(0);
            }
            if (cameras.Length == 0)
            {
                return(0);
            }

            //실제 카메라가 지정되면 자동 갱신이 취소된다.
            _isAutomaticRefresh = false;

            //다시 Refresh를 해야한다.
            if (_numberOfCameraType != NumberOfCamera.None)
            {
                //일단 초기화
                Clear();
            }

            int nParamCameras = cameras.Length;

            _cal_curSceneCamera = null;

            for (int i = 0; i < nParamCameras; i++)
            {
                _cal_curSceneCamera = cameras[i];
                if (_cal_curSceneCamera != null && IsLookPortrait(_cal_curSceneCamera))
                {
                    //바라보고 있는 카메라다. > 일단 모두 추가
                    CameraData newCamData = new CameraData(_cal_curSceneCamera);
                    _cameraDataList.Add(newCamData);
                    _cam2CameraData.Add(_cal_curSceneCamera, newCamData);
                    if (_parentPortrait._isForceCamSortModeToOrthographic)
                    {
                        //강제로 Orthographic으로 고정한다.
                        _cal_curSceneCamera.transparencySortMode = TransparencySortMode.Orthographic;
                    }
                }
            }

            _nCameras = _cameraDataList.Count;

            if (_nCameras == 0)
            {
                //실제 유효한 카메라가 없다.
                _numberOfCameraType = NumberOfCamera.None;
                _persOrthoType      = PersOrthoType.Unknown;

                //Debug.LogError("> 카메라 없음");
            }
            else
            {
                if (_nCameras == 1 || _vrSupportMode != apPortrait.VR_SUPPORT_MODE.MultiCamera)
                {
                    //싱글 카메라 (카메라가 한개이거나 [멀티 카메라 VR]을 지원하지 않는 경우)
                    _numberOfCameraType = NumberOfCamera.Single;

                    _mainData = _cameraDataList[0];

                    _persOrthoType = (_mainData._camera.orthographic ? PersOrthoType.Orthographic : PersOrthoType.Perspective);

                    _renderCameraDataList.Add(_mainData);                    //렌더 카메라는 1개
                    _nRenderCameras = 1;
                }
                else
                {
                    //멀티 카메라
                    _numberOfCameraType = NumberOfCamera.Multiple;

                    //메인 카메라를 찾자
                    //카메라의 속성을 먼저 보자

                    _cal_curCamData = null;

                    //두바퀴 돌아서 체크
                    //일단 Left, Right 타입을 체크한다.

                    for (int i = 0; i < _nCameras; i++)
                    {
                        _cal_curCamData = _cameraDataList[i];
                        _renderCameraDataList.Add(_cal_curCamData);                        //<<렌더 카메라로 추가한다.

                        switch (_cal_curCamData._camera.stereoTargetEye)
                        {
                        case StereoTargetEyeMask.Left:
                        {
                            if (_leftEyeData == null)
                            {
                                _leftEyeData = _cal_curCamData;
                            }
                        }
                        break;

                        case StereoTargetEyeMask.Right:
                        {
                            if (_rightEyeData == null)
                            {
                                _rightEyeData = _cal_curCamData;
                            }
                        }
                        break;
                        }
                    }

                    _nRenderCameras = _renderCameraDataList.Count;

                    //두번째 체크. 만약 LR 카메라가 하나라도 발견되지 않았다면, 이름이라도 확인하자.
                    if (_leftEyeData == null || _rightEyeData == null)
                    {
                        _cal_curCamData = null;
                        for (int i = 0; i < _nCameras; i++)
                        {
                            _cal_curCamData = _cameraDataList[i];

                            string camName = _cal_curCamData._transform.gameObject.name.ToLower();

                            if (camName.Contains("left"))
                            {
                                //이름에 Left가 들어갔다면
                                if (_leftEyeData == null)
                                {
                                    _leftEyeData = _cal_curCamData;
                                }
                            }
                            else if (camName.Contains("right"))
                            {
                                //이름에 Right가 들어갔다면
                                if (_rightEyeData == null)
                                {
                                    _rightEyeData = _cal_curCamData;
                                }
                            }

                            if (_leftEyeData != null && _rightEyeData != null)
                            {
                                break;
                            }
                        }
                    }

                    //LR 타입 체크
                    if (_leftEyeData != null && _rightEyeData != null)
                    {
                        //LR 둘다 있다.
                        _dualCameraType = DualCameraType.LeftRight;
                        _mainData       = _leftEyeData;

                        if (_leftEyeData._camera.orthographic && _rightEyeData._camera.orthographic)
                        {
                            _persOrthoType = PersOrthoType.Orthographic;
                        }
                        else if (!_leftEyeData._camera.orthographic && !_rightEyeData._camera.orthographic)
                        {
                            _persOrthoType = PersOrthoType.Perspective;
                        }
                        else
                        {
                            _persOrthoType = PersOrthoType.Mixed;
                        }

                        //Debug.LogWarning("> LR 두개의 카메라");
                    }
                    else
                    {
                        //LR 둘중 하나라도 없다.
                        _dualCameraType = DualCameraType.Unknown;
                        _mainData       = _cameraDataList[0];

                        _persOrthoType = (_mainData._camera.orthographic ? PersOrthoType.Orthographic : PersOrthoType.Perspective);

                        //Debug.LogWarning("> 여러개의 카메라");
                    }
                }
            }

            //RefreshKey도 교체하자
            if (_refreshKey < 0)
            {
                _refreshKey = 10;
            }
            else
            {
                _refreshKey++;
                if (_refreshKey > 9999)
                {
                    _refreshKey = 10;
                }
            }

            RefreshMatrix();

            return(_nCameras);
        }