using System; using UnityEngine; using UnityEngine.EventSystems; /* 弓的相机 */ public class BowCameraDoublePlayer : MonoBehaviour { //[Header("当前脚本属于的玩家是?")] [HideInInspector] public PlayerType playerType = PlayerType.FirstPlayer; AimCrossHair aimCrossHair; //相机组件 Camera _cameraComp; Camera cameraComp { get { if (!_cameraComp) _cameraComp = GetComponent(); return _cameraComp; } } //控制的手臂弓 ArmBowDoublePlayer _armBow; ArmBowDoublePlayer armBow { get { if (!_armBow) _armBow = GetComponentInChildren(); return _armBow; } } //本地欧拉角记录值 Vector3 localEulerAngles; //触摸检测器 JCUnityLib.TouchChecker touchChecker = new JCUnityLib.TouchChecker(); //触摸模式开关 private bool _isTouchMode = true; public bool isTouchMode { get { if (CommonConfig.isReleaseVersion) return false; return _isTouchMode; } set { _isTouchMode = value; } } //左右转动范围限制 float[] limitRangeRotateY = { -80, 80 }; //上下转动范围限制 float[] limitRangeRotateX = { -80, 80 }; //禁止逻辑,只用于同步状态和渲染,目前用于联机 [NonSerialized] public bool banLogic = false; void Awake() { localEulerAngles = transform.localEulerAngles; if (CommonConfig.SpecialVersion1) { if (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name.Equals("GameChallenge")) { this.cameraComp.fieldOfView = UserSettings.ins.bowRotateConvert.fieldOfView; } } RecordDefaultCameraFieldOfView(); } void Start() { touchChecker.onMoved += delegate (Touch t, bool isOnUI) { if (banLogic) return; if (isOnUI) return; //触摸控制镜头和拉弓射箭 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) { if (banLogic) return; if (!isOnUI) armBow.ADS_fire(); }; //直接使用固定相机 bowCameraFixed = new BowCameraFixed(this); //获取当前的playerType Debug.Log("BowCameraDoublePlayer PlayerType:" + playerType); aimCrossHair = GameController.ins.GetAimCrossHair(playerType);//GameController.ins.aimCrossHairs[playerType == PlayerType.FirstPlayer ? 0 : 1]; //开始时候更新一次2P isTouchMode状态 if (playerType== PlayerType.SecondPlayer && BluetoothAim.ins?.getSmartBowHelper2P() != null) { var newStatus = BluetoothAim.ins.getSmartBowHelper2P().GetBluetoothStatus(); if (newStatus == SmartBowSDK.BluetoothStatusEnum.None) { isTouchMode = true; }else { isTouchMode = false; } Debug.Log("2P Start isTouchMode:"+ isTouchMode); } } void OnDestroy() { } void Update() { //1P,同步使用 BowCamera.isTouchMode if (playerType == PlayerType.FirstPlayer) { isTouchMode = BowCamera.isTouchMode; } //更新相机视野 if (cameraComp && !banCameraFieldOfView) { cameraComp.fieldOfView = cameraFieldOfView; } //if (banLogic) return; // Debug.Log(GameController.ins.gameStart + " == " + GameController.ins.gameOver + " == " + (!GameController.ins.gameStart || GameController.ins.gameOver)); //满足以下条件则阻止控制输入 if (GameController.ins.gameOver) { return; } if (GameController.ins.debugInEditor) { //// 制作一条射线 //Ray ray = bowCameraFixed.camera.ScreenPointToRay(aimCrossHair.transform.position); // 将屏幕点转换为射线 //Debug.DrawRay(ray.origin, ray.direction * 1000, Color.red); //// 人物旋转 //transform.LookAt(ray.GetPoint(1000)); //return; //鼠标控制镜头和拉弓射箭 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; } else if (isTouchMode) { //Debug.Log("Start2 isTouchMode:" + isTouchMode); touchChecker.Update(); } else { if (SB_EventSystem.ins && SB_EventSystem.ins.simulateMouseIsAwaked) return; //需要-镜头看向九轴姿态虚拟节点 needLookAtPoint = true; } } //需要-镜头看向九轴姿态虚拟节点? bool needLookAtPoint = false; //镜头旋转转换比值 float[] _bowRotateConvertRate = null; float bowRotateConvertRate { get { if (_bowRotateConvertRate == null) { _bowRotateConvertRate = new float[] { UserSettings.ins.bowRotateConvert.GetRate() }; } return _bowRotateConvertRate[0]; } } void LateUpdate() { if (needLookAtPoint) { needLookAtPoint = false; //镜头看向九轴姿态虚拟节点 if (playerType == PlayerType.FirstPlayer) { this.transform.LookAt(CameraToLook.ins.point); } else { this.transform.LookAt(CameraToLookNew.ins.point2P); } // if (BowQuatDebug.ins) BowQuatDebug.ins.ShowRealBowQuat(this.transform.localEulerAngles); if (!CommonConfig.isReleaseVersion) { //镜头旋转比值转换 Vector3 localAngles = this.transform.localEulerAngles; localAngles.x = Mathf.Clamp((localAngles.x > 180 ? localAngles.x - 360 : localAngles.x) * bowRotateConvertRate, limitRangeRotateX[0], limitRangeRotateX[1]); localAngles.y = Mathf.Clamp((localAngles.y > 180 ? localAngles.y - 360 : localAngles.y) * bowRotateConvertRate, limitRangeRotateY[0], limitRangeRotateY[1]); if (bowCameraFixed != null) { localAngles = bowCameraFixed.LimitBowAngle(localAngles); } this.transform.localEulerAngles = localAngles; // if (BowQuatDebug.ins) BowQuatDebug.ins.ShowGameBowQuat(this.transform.localEulerAngles); } } onAfterLateUpdate?.Invoke(); } [NonSerialized] public Action onAfterLateUpdate; //---------------相机视野的相关操作--------------------- //视野值记录 float cameraFieldOfView = 60; [NonSerialized] public float defaultCameraFieldOfView = 60; private void RecordDefaultCameraFieldOfView() { defaultCameraFieldOfView = cameraComp.fieldOfView; cameraFieldOfView = defaultCameraFieldOfView; } //禁止相机视野改变 [NonSerialized] public bool banCameraFieldOfView = false; public void SetCameraFieldOfView(float value) { cameraComp.fieldOfView = value; } public void SetCameraFieldOfViewRecord(float value) { cameraFieldOfView = value; } //拉弓时的相机视野值变化 public void updateFollowPullBow() { // if (cameraFieldOfView > 40) { // cameraFieldOfView -= 20 * Time.deltaTime; // } else { // cameraFieldOfView = 40; // } } //松开拉弓时的相机视野值变化 public void updateGiveUpPullBow() { // if (cameraFieldOfView < 60) { // cameraFieldOfView += 20 * Time.deltaTime; // } else { // cameraFieldOfView = 60; // } } // 2022-04-28 // ------ 添加固定镜头选项后,新增的API ------ bool isArrowFollowing = false; public void SetArrowFollowing(bool value) { isArrowFollowing = value; cameraComp.enabled = !isArrowFollowing; AutoSwitchCamera(); } public bool GetArrowFollowing() { return isArrowFollowing; } bool isScaleAimDisplaying = false; public void SetScaleAimDisplaying(bool value) { isScaleAimDisplaying = value; AutoSwitchCamera(); } void AutoSwitchCamera() { if (bowCameraFixed == null) { cameraComp.enabled = !isArrowFollowing; Debug.Log(playerType + "_1cameraComp.enabled:" + cameraComp.enabled); } else { bowCameraFixed.gameObject.SetActive(!isScaleAimDisplaying && !isArrowFollowing); cameraComp.enabled = isScaleAimDisplaying && !isArrowFollowing; Debug.Log(playerType + "_2cameraComp.enabled:" + cameraComp.enabled); } } public Camera GetRenderCamera() { if (bowCameraFixed == null) { return cameraComp; } else { if (bowCameraFixed.gameObject.activeSelf) { return bowCameraFixed.camera; } else { return cameraComp; } } } public BowCameraFixed bowCameraFixed = null; public class BowCameraFixed { public GameObject gameObject; public Transform transform; public Camera camera; private UnityStandardAssets.ImageEffects.Blur blur; //bowCameraComponent BowCameraDoublePlayer bowCamera; private Camera targetCamera; private UnityStandardAssets.ImageEffects.Blur targetBlur; public BowCameraFixed(BowCameraDoublePlayer _bowCamera) { bowCamera = _bowCamera; if (bowCamera.playerType == PlayerType.FirstPlayer) { gameObject = new GameObject("BowCameraFixedFirst"); transform = gameObject.transform; //复制Camera组件 targetCamera = bowCamera.cameraComp; camera = gameObject.AddComponent(); camera.tag = "MainCamera"; } else { gameObject = new GameObject("BowCameraFixedSecond"); transform = gameObject.transform; //复制Camera组件 targetCamera = bowCamera.cameraComp; camera = gameObject.AddComponent(); camera.tag = "SecondCamera"; } GameController.ins.GetAimCrossHair(bowCamera.playerType).mainCamera = camera; camera.clearFlags = targetCamera.clearFlags; camera.backgroundColor = targetCamera.backgroundColor; camera.cullingMask = targetCamera.cullingMask; camera.fieldOfView = targetCamera.fieldOfView; camera.nearClipPlane = targetCamera.nearClipPlane; camera.depth = targetCamera.depth + 0.1f; camera.renderingPath = targetCamera.renderingPath; camera.rect = targetCamera.rect; camera.farClipPlane = targetCamera.farClipPlane; camera.nearClipPlane = targetCamera.nearClipPlane; //复制Blur组件 targetBlur = bowCamera.GetComponent(); if (targetBlur) { blur = gameObject.AddComponent(); blur.enabled = targetBlur.enabled; blur.blurShader = targetBlur.blurShader; blur.blurSpread = targetBlur.blurSpread; blur.iterations = targetBlur.iterations; } //设置Transform属性 transform.parent = bowCamera.transform.parent; transform.localPosition = bowCamera.transform.localPosition; transform.localScale = bowCamera.transform.localScale; transform.localRotation = Quaternion.identity; //监听和驱动LateUpdate bowCamera.onAfterLateUpdate += LateUpdate; //切换镜头 bowCamera.cameraComp.enabled = false; InitForLimitBound(); } void LateUpdate() { if (gameObject.activeSelf) { bowCamera.aimCrossHair.UpdatePostionWhenFixedCamera(bowCamera); } if (blur) { blur.enabled = targetBlur.enabled; if (blur.enabled) { blur.blurShader = targetBlur.blurShader; blur.blurSpread = targetBlur.blurSpread; blur.iterations = targetBlur.iterations; } } } //边界限制 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 - 4; 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; } } }