Explorar el Código

固定背景下,边界限制

lvjincheng hace 4 años
padre
commit
576db657b1
Se han modificado 1 ficheros con 56 adiciones y 12 borrados
  1. 56 12
      Assets/BowArrow/Scripts/Game/BowCamera.cs

+ 56 - 12
Assets/BowArrow/Scripts/Game/BowCamera.cs

@@ -35,6 +35,10 @@ public class BowCamera : MonoBehaviour
             _isTouchMode = value;
         }
     }
+    //左右转动范围限制
+    float[] limitRangeRotateY = {-80, 80};
+    //上下转动范围限制
+    float[] limitRangeRotateX = {-80, 80};
     //禁止逻辑,只用于同步状态和渲染,目前用于联机
     [NonSerialized] public bool banLogic = false;
     private static BowCamera _ins;
@@ -61,8 +65,8 @@ public class BowCamera : MonoBehaviour
             if (banLogic) return;
             if (isOnUI) return;
             //触摸控制镜头和拉弓射箭
-            this.localEulerAngles.x = Mathf.Clamp(this.localEulerAngles.x - t.deltaPosition.y * Time.deltaTime * 5, -80, 80);
-            this.localEulerAngles.y = Mathf.Clamp(this.localEulerAngles.y + t.deltaPosition.x * Time.deltaTime * 5, -90, 90);   
+            this.localEulerAngles.x = Mathf.Clamp(this.localEulerAngles.x - t.deltaPosition.y * Time.deltaTime * 5, limitRangeRotateX[0], limitRangeRotateX[1]);
+            this.localEulerAngles.y = Mathf.Clamp(this.localEulerAngles.y + t.deltaPosition.x * Time.deltaTime * 5, limitRangeRotateY[0], limitRangeRotateY[1]);   
             this.transform.localEulerAngles = this.localEulerAngles; 
         };
         touchChecker.onEnded += delegate(Touch t, bool isOnUI) {
@@ -87,8 +91,8 @@ public class BowCamera : MonoBehaviour
 
         if (GameMgr.debugInEditor) {
             //鼠标控制镜头和拉弓射箭
-            this.localEulerAngles.x = Mathf.Clamp(this.localEulerAngles.x - 2f * Input.GetAxis("Mouse Y"), -80, 80);
-            this.localEulerAngles.y = Mathf.Clamp(this.localEulerAngles.y + 2f * Input.GetAxis("Mouse X"), -90, 90);   
+            this.localEulerAngles.x = Mathf.Clamp(this.localEulerAngles.x - 2f * Input.GetAxis("Mouse Y"), limitRangeRotateX[0], limitRangeRotateX[1]);
+            this.localEulerAngles.y = Mathf.Clamp(this.localEulerAngles.y + 2f * Input.GetAxis("Mouse X"), limitRangeRotateY[0], limitRangeRotateY[1]);
             this.transform.localEulerAngles = this.localEulerAngles; 
             if (EventSystem.current.IsPointerOverGameObject()) return;
         }
@@ -120,15 +124,15 @@ public class BowCamera : MonoBehaviour
             this.transform.LookAt(CameraToLook.ins.point);
             if (!CommonConfig.isReleaseVersion) {
                 //镜头旋转比值转换
-                Vector3 localEulerAngles = this.transform.localEulerAngles;
-                float angleY = localEulerAngles.y;
-                if (angleY < 180) {
-                    angleY = Mathf.Clamp(angleY * bowRotateConvertRate, 0, 90);
-                } else {
-                    angleY = Mathf.Clamp((angleY - 360) * bowRotateConvertRate, -90, 0);
+                Vector3 localAngles = this.transform.localEulerAngles;
+                localAngles.x = Mathf.Clamp(localAngles.x > 180 ? localAngles.x - 360 : localAngles.x,
+                    limitRangeRotateX[0], limitRangeRotateX[1]);
+                localAngles.y = Mathf.Clamp(localAngles.y > 180 ? localAngles.y - 360 : localAngles.y,
+                    limitRangeRotateY[0], limitRangeRotateY[1]);
+                if (bowCameraFixed != null) {
+                    localAngles = bowCameraFixed.LimitBowAngle(localAngles);
                 }
-                localEulerAngles.y = angleY;
-                this.transform.localEulerAngles = localEulerAngles;
+                this.transform.localEulerAngles = localAngles;
             }
         }
         onAfterLateUpdate?.Invoke();
@@ -252,6 +256,8 @@ public class BowCamera : MonoBehaviour
             bowCamera.onAfterLateUpdate += LateUpdate;
             //切换镜头
             bowCamera.AutoSwitchCamera();
+            
+            InitForLimitBound();
         } 
 
         void LateUpdate() {
@@ -267,5 +273,43 @@ public class BowCamera : MonoBehaviour
                 }
             }
         }
+
+        //边界限制
+        float[] rangeRotateY = {-80, 80};
+        float rangeRotateX = 25;
+        Vector3 vecF;
+        Vector3 vecU;
+        public int outBoundIndex = -1; //-1为未出界
+        void InitForLimitBound() {
+            for (int i = (int)rangeRotateY[0]; i < 0; i++) {
+                Vector3 pos = transform.position + Quaternion.AngleAxis(i, Vector3.up) * transform.forward;
+                pos = camera.WorldToViewportPoint(pos);
+                if (pos.x >= 0) {
+                    rangeRotateY[0] = i;
+                    rangeRotateY[1] = -i;
+                    break;
+                }
+            }
+            rangeRotateX = camera.fieldOfView / 2;
+            vecF = Quaternion.AngleAxis(rangeRotateX, Vector3.right) * Vector3.forward;
+            vecU = Quaternion.AngleAxis(rangeRotateX, Vector3.right) * Vector3.up;
+        }
+        public Vector3 LimitBowAngle(Vector3 outAngle) {
+            float angleY = outAngle.y; 
+            float angleX = outAngle.x; 
+            outAngle.y = Mathf.Clamp(angleY, rangeRotateY[0], rangeRotateY[1]);
+            Vector3 vec = Quaternion.AngleAxis(outAngle.y, vecU) * vecF;
+            float rx = (float)(Math.Asin(vec.y) / Math.PI * 180) * (angleX < 0 ? 1 : -1);
+            if (angleY < rangeRotateY[0]) outBoundIndex = 0;
+            else if (angleY > rangeRotateY[1]) outBoundIndex = 1;
+            else if (angleX < -rangeRotateX) outBoundIndex = 2;
+            else if (angleX > rangeRotateX) outBoundIndex = 3;
+            else outBoundIndex = -1;
+            if (Mathf.Abs(angleX) > Mathf.Abs(rx)) {
+                outAngle.x = rx;
+            }
+            //因为Vector3是struct,传递给函数是值传递而非引用传递
+            return outAngle;
+        }
     }
 }