BowCameraDoublePlayer.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. using System;
  2. using UnityEngine;
  3. using UnityEngine.EventSystems;
  4. /* 弓的相机 */
  5. public class BowCameraDoublePlayer : MonoBehaviour
  6. {
  7. //[Header("当前脚本属于的玩家是?")]
  8. [HideInInspector]
  9. public PlayerType playerType = PlayerType.FirstPlayer;
  10. AimCrossHair aimCrossHair;
  11. //相机组件
  12. Camera _cameraComp;
  13. Camera cameraComp
  14. {
  15. get
  16. {
  17. if (!_cameraComp) _cameraComp = GetComponent<Camera>();
  18. return _cameraComp;
  19. }
  20. }
  21. //控制的手臂弓
  22. ArmBowDoublePlayer _armBow;
  23. ArmBowDoublePlayer armBow
  24. {
  25. get
  26. {
  27. if (!_armBow) _armBow = GetComponentInChildren<ArmBowDoublePlayer>();
  28. return _armBow;
  29. }
  30. }
  31. //本地欧拉角记录值
  32. Vector3 localEulerAngles;
  33. //触摸检测器
  34. JCUnityLib.TouchChecker touchChecker = new JCUnityLib.TouchChecker();
  35. //触摸模式开关
  36. private bool _isTouchMode = true;
  37. public bool isTouchMode
  38. {
  39. get
  40. {
  41. if (CommonConfig.isReleaseVersion) return false;
  42. return _isTouchMode;
  43. }
  44. set
  45. {
  46. _isTouchMode = value;
  47. }
  48. }
  49. //左右转动范围限制
  50. float[] limitRangeRotateY = { -80, 80 };
  51. //上下转动范围限制
  52. float[] limitRangeRotateX = { -80, 80 };
  53. //禁止逻辑,只用于同步状态和渲染,目前用于联机
  54. [NonSerialized] public bool banLogic = false;
  55. void Awake()
  56. {
  57. localEulerAngles = transform.localEulerAngles;
  58. if (CommonConfig.SpecialVersion1)
  59. {
  60. if (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name.Equals("GameChallenge"))
  61. {
  62. this.cameraComp.fieldOfView = UserSettings.ins.bowRotateConvert.fieldOfView;
  63. }
  64. }
  65. RecordDefaultCameraFieldOfView();
  66. }
  67. void Start()
  68. {
  69. touchChecker.onMoved += delegate (Touch t, bool isOnUI)
  70. {
  71. if (banLogic) return;
  72. if (isOnUI) return;
  73. //触摸控制镜头和拉弓射箭
  74. this.localEulerAngles.x = Mathf.Clamp(this.localEulerAngles.x - t.deltaPosition.y * Time.deltaTime * 5, limitRangeRotateX[0], limitRangeRotateX[1]);
  75. this.localEulerAngles.y = Mathf.Clamp(this.localEulerAngles.y + t.deltaPosition.x * Time.deltaTime * 5, limitRangeRotateY[0], limitRangeRotateY[1]);
  76. this.transform.localEulerAngles = this.localEulerAngles;
  77. };
  78. touchChecker.onEnded += delegate (Touch t, bool isOnUI)
  79. {
  80. if (banLogic) return;
  81. if (!isOnUI) armBow.ADS_fire();
  82. };
  83. //直接使用固定相机
  84. bowCameraFixed = new BowCameraFixed(this);
  85. //获取当前的playerType
  86. Debug.Log("BowCameraDoublePlayer PlayerType:" + playerType);
  87. aimCrossHair = GameController.ins.GetAimCrossHair(playerType);//GameController.ins.aimCrossHairs[playerType == PlayerType.FirstPlayer ? 0 : 1];
  88. //开始时候更新一次2P isTouchMode状态
  89. if (playerType== PlayerType.SecondPlayer && BluetoothAim.ins?.getSmartBowHelper2P() != null) {
  90. var newStatus = BluetoothAim.ins.getSmartBowHelper2P().GetBluetoothStatus();
  91. if (newStatus == SmartBowSDK.BluetoothStatusEnum.None)
  92. {
  93. isTouchMode = true;
  94. }else {
  95. isTouchMode = false;
  96. }
  97. Debug.Log("2P Start isTouchMode:"+ isTouchMode);
  98. }
  99. }
  100. void OnDestroy()
  101. {
  102. }
  103. void Update()
  104. {
  105. //1P,同步使用 BowCamera.isTouchMode
  106. if (playerType == PlayerType.FirstPlayer)
  107. {
  108. isTouchMode = BowCamera.isTouchMode;
  109. }
  110. //更新相机视野
  111. if (cameraComp && !banCameraFieldOfView)
  112. {
  113. cameraComp.fieldOfView = cameraFieldOfView;
  114. }
  115. //if (banLogic) return;
  116. // Debug.Log(GameController.ins.gameStart + " == " + GameController.ins.gameOver + " == " + (!GameController.ins.gameStart || GameController.ins.gameOver));
  117. //满足以下条件则阻止控制输入
  118. if (GameController.ins.gameOver)
  119. {
  120. return;
  121. }
  122. if (GameController.ins.debugInEditor)
  123. {
  124. //// 制作一条射线
  125. //Ray ray = bowCameraFixed.camera.ScreenPointToRay(aimCrossHair.transform.position); // 将屏幕点转换为射线
  126. //Debug.DrawRay(ray.origin, ray.direction * 1000, Color.red);
  127. //// 人物旋转
  128. //transform.LookAt(ray.GetPoint(1000));
  129. //return;
  130. //鼠标控制镜头和拉弓射箭
  131. this.localEulerAngles.x = Mathf.Clamp(this.localEulerAngles.x - 2f * Input.GetAxis("Mouse Y"), limitRangeRotateX[0], limitRangeRotateX[1]);
  132. this.localEulerAngles.y = Mathf.Clamp(this.localEulerAngles.y + 2f * Input.GetAxis("Mouse X"), limitRangeRotateY[0], limitRangeRotateY[1]);
  133. this.transform.localEulerAngles = this.localEulerAngles;
  134. if (EventSystem.current.IsPointerOverGameObject()) return;
  135. }
  136. else if (isTouchMode)
  137. {
  138. //Debug.Log("Start2 isTouchMode:" + isTouchMode);
  139. touchChecker.Update();
  140. }
  141. else
  142. {
  143. if (SB_EventSystem.ins && SB_EventSystem.ins.simulateMouseIsAwaked) return;
  144. //需要-镜头看向九轴姿态虚拟节点
  145. needLookAtPoint = true;
  146. }
  147. }
  148. //需要-镜头看向九轴姿态虚拟节点?
  149. bool needLookAtPoint = false;
  150. //镜头旋转转换比值
  151. float[] _bowRotateConvertRate = null;
  152. float bowRotateConvertRate
  153. {
  154. get
  155. {
  156. if (_bowRotateConvertRate == null)
  157. {
  158. _bowRotateConvertRate = new float[] { UserSettings.ins.bowRotateConvert.GetRate() };
  159. }
  160. return _bowRotateConvertRate[0];
  161. }
  162. }
  163. void LateUpdate()
  164. {
  165. #if UNITY_STANDALONE_WIN || UNITY_EDITOR
  166. if (BleUDP.ins && BleUDP.ins.bluetoothStatusEnum == BluetoothStatusEnum.ConnectSuccess)
  167. {
  168. if (!GameController.ins.gameStart || GameController.ins.gameOver)
  169. {
  170. return;
  171. }
  172. needLookAtPoint = true;
  173. }
  174. #endif
  175. if (needLookAtPoint)
  176. {
  177. needLookAtPoint = false;
  178. //镜头看向九轴姿态虚拟节点
  179. if (playerType == PlayerType.FirstPlayer) {
  180. this.transform.LookAt(CameraToLook.ins.point);
  181. } else {
  182. this.transform.LookAt(CameraToLookNew.ins.point2P);
  183. }
  184. // if (BowQuatDebug.ins) BowQuatDebug.ins.ShowRealBowQuat(this.transform.localEulerAngles);
  185. if (!CommonConfig.isReleaseVersion)
  186. {
  187. //镜头旋转比值转换
  188. Vector3 localAngles = this.transform.localEulerAngles;
  189. localAngles.x = Mathf.Clamp((localAngles.x > 180 ? localAngles.x - 360 : localAngles.x) * bowRotateConvertRate,
  190. limitRangeRotateX[0], limitRangeRotateX[1]);
  191. localAngles.y = Mathf.Clamp((localAngles.y > 180 ? localAngles.y - 360 : localAngles.y) * bowRotateConvertRate,
  192. limitRangeRotateY[0], limitRangeRotateY[1]);
  193. if (bowCameraFixed != null)
  194. {
  195. localAngles = bowCameraFixed.LimitBowAngle(localAngles);
  196. }
  197. this.transform.localEulerAngles = localAngles;
  198. // if (BowQuatDebug.ins) BowQuatDebug.ins.ShowGameBowQuat(this.transform.localEulerAngles);
  199. }
  200. }
  201. onAfterLateUpdate?.Invoke();
  202. }
  203. [NonSerialized] public Action onAfterLateUpdate;
  204. //---------------相机视野的相关操作---------------------
  205. //视野值记录
  206. float cameraFieldOfView = 60;
  207. [NonSerialized] public float defaultCameraFieldOfView = 60;
  208. private void RecordDefaultCameraFieldOfView()
  209. {
  210. defaultCameraFieldOfView = cameraComp.fieldOfView;
  211. cameraFieldOfView = defaultCameraFieldOfView;
  212. }
  213. //禁止相机视野改变
  214. [NonSerialized] public bool banCameraFieldOfView = false;
  215. public void SetCameraFieldOfView(float value)
  216. {
  217. cameraComp.fieldOfView = value;
  218. }
  219. public void SetCameraFieldOfViewRecord(float value)
  220. {
  221. cameraFieldOfView = value;
  222. }
  223. //拉弓时的相机视野值变化
  224. public void updateFollowPullBow()
  225. {
  226. // if (cameraFieldOfView > 40) {
  227. // cameraFieldOfView -= 20 * Time.deltaTime;
  228. // } else {
  229. // cameraFieldOfView = 40;
  230. // }
  231. }
  232. //松开拉弓时的相机视野值变化
  233. public void updateGiveUpPullBow()
  234. {
  235. // if (cameraFieldOfView < 60) {
  236. // cameraFieldOfView += 20 * Time.deltaTime;
  237. // } else {
  238. // cameraFieldOfView = 60;
  239. // }
  240. }
  241. // 2022-04-28
  242. // ------ 添加固定镜头选项后,新增的API ------
  243. bool isArrowFollowing = false;
  244. public void SetArrowFollowing(bool value)
  245. {
  246. isArrowFollowing = value;
  247. cameraComp.enabled = !isArrowFollowing;
  248. AutoSwitchCamera();
  249. }
  250. public bool GetArrowFollowing() {
  251. return isArrowFollowing;
  252. }
  253. bool isScaleAimDisplaying = false;
  254. public void SetScaleAimDisplaying(bool value)
  255. {
  256. isScaleAimDisplaying = value;
  257. AutoSwitchCamera();
  258. }
  259. void AutoSwitchCamera()
  260. {
  261. if (bowCameraFixed == null)
  262. {
  263. cameraComp.enabled = !isArrowFollowing;
  264. Debug.Log(playerType + "_1cameraComp.enabled:" + cameraComp.enabled);
  265. }
  266. else
  267. {
  268. bowCameraFixed.gameObject.SetActive(!isScaleAimDisplaying && !isArrowFollowing);
  269. cameraComp.enabled = isScaleAimDisplaying && !isArrowFollowing;
  270. Debug.Log(playerType + "_2cameraComp.enabled:" + cameraComp.enabled);
  271. }
  272. }
  273. public Camera GetRenderCamera()
  274. {
  275. if (bowCameraFixed == null)
  276. {
  277. return cameraComp;
  278. }
  279. else
  280. {
  281. if (bowCameraFixed.gameObject.activeSelf)
  282. {
  283. return bowCameraFixed.camera;
  284. }
  285. else
  286. {
  287. return cameraComp;
  288. }
  289. }
  290. }
  291. public BowCameraFixed bowCameraFixed = null;
  292. public class BowCameraFixed
  293. {
  294. public GameObject gameObject;
  295. public Transform transform;
  296. public Camera camera;
  297. private UnityStandardAssets.ImageEffects.Blur blur;
  298. //bowCameraComponent
  299. BowCameraDoublePlayer bowCamera;
  300. private Camera targetCamera;
  301. private UnityStandardAssets.ImageEffects.Blur targetBlur;
  302. public BowCameraFixed(BowCameraDoublePlayer _bowCamera)
  303. {
  304. bowCamera = _bowCamera;
  305. if (bowCamera.playerType == PlayerType.FirstPlayer)
  306. {
  307. gameObject = new GameObject("BowCameraFixedFirst");
  308. transform = gameObject.transform;
  309. //复制Camera组件
  310. targetCamera = bowCamera.cameraComp;
  311. camera = gameObject.AddComponent<Camera>();
  312. camera.tag = "MainCamera";
  313. }
  314. else
  315. {
  316. gameObject = new GameObject("BowCameraFixedSecond");
  317. transform = gameObject.transform;
  318. //复制Camera组件
  319. targetCamera = bowCamera.cameraComp;
  320. camera = gameObject.AddComponent<Camera>();
  321. camera.tag = "SecondCamera";
  322. }
  323. GameController.ins.GetAimCrossHair(bowCamera.playerType).mainCamera = camera;
  324. camera.clearFlags = targetCamera.clearFlags;
  325. camera.backgroundColor = targetCamera.backgroundColor;
  326. camera.cullingMask = targetCamera.cullingMask;
  327. camera.fieldOfView = targetCamera.fieldOfView;
  328. camera.nearClipPlane = targetCamera.nearClipPlane;
  329. camera.depth = targetCamera.depth + 0.1f;
  330. camera.renderingPath = targetCamera.renderingPath;
  331. camera.rect = targetCamera.rect;
  332. camera.farClipPlane = targetCamera.farClipPlane;
  333. camera.nearClipPlane = targetCamera.nearClipPlane;
  334. //复制Blur组件
  335. targetBlur = bowCamera.GetComponent<UnityStandardAssets.ImageEffects.Blur>();
  336. if (targetBlur)
  337. {
  338. blur = gameObject.AddComponent<UnityStandardAssets.ImageEffects.Blur>();
  339. blur.enabled = targetBlur.enabled;
  340. blur.blurShader = targetBlur.blurShader;
  341. blur.blurSpread = targetBlur.blurSpread;
  342. blur.iterations = targetBlur.iterations;
  343. }
  344. //设置Transform属性
  345. transform.parent = bowCamera.transform.parent;
  346. transform.localPosition = bowCamera.transform.localPosition;
  347. transform.localScale = bowCamera.transform.localScale;
  348. transform.localRotation = Quaternion.identity;
  349. //监听和驱动LateUpdate
  350. bowCamera.onAfterLateUpdate += LateUpdate;
  351. //切换镜头
  352. bowCamera.cameraComp.enabled = false;
  353. InitForLimitBound();
  354. }
  355. void LateUpdate()
  356. {
  357. if (gameObject.activeSelf)
  358. {
  359. bowCamera.aimCrossHair.UpdatePostionWhenFixedCamera(bowCamera);
  360. }
  361. if (blur)
  362. {
  363. blur.enabled = targetBlur.enabled;
  364. if (blur.enabled)
  365. {
  366. blur.blurShader = targetBlur.blurShader;
  367. blur.blurSpread = targetBlur.blurSpread;
  368. blur.iterations = targetBlur.iterations;
  369. }
  370. }
  371. }
  372. //边界限制
  373. float[] rangeRotateY = { -80, 80 };
  374. float rangeRotateX = 25;
  375. Vector3 vecF;
  376. Vector3 vecU;
  377. public int outBoundIndex = -1; //-1为未出界
  378. void InitForLimitBound()
  379. {
  380. for (int i = (int)rangeRotateY[0]; i < 0; i++)
  381. {
  382. Vector3 pos = transform.position + Quaternion.AngleAxis(i, Vector3.up) * transform.forward;
  383. pos = camera.WorldToViewportPoint(pos);
  384. if (pos.x >= 0)
  385. {
  386. rangeRotateY[0] = i;
  387. rangeRotateY[1] = -i - 4;
  388. break;
  389. }
  390. }
  391. rangeRotateX = camera.fieldOfView / 2;
  392. vecF = Quaternion.AngleAxis(rangeRotateX, Vector3.right) * Vector3.forward;
  393. vecU = Quaternion.AngleAxis(rangeRotateX, Vector3.right) * Vector3.up;
  394. }
  395. public Vector3 LimitBowAngle(Vector3 outAngle)
  396. {
  397. float angleY = outAngle.y;
  398. float angleX = outAngle.x;
  399. outAngle.y = Mathf.Clamp(angleY, rangeRotateY[0], rangeRotateY[1]);
  400. Vector3 vec = Quaternion.AngleAxis(outAngle.y, vecU) * vecF;
  401. float rx = (float)(Math.Asin(vec.y) / Math.PI * 180) * (angleX < 0 ? 1 : -1);
  402. if (angleY < rangeRotateY[0]) outBoundIndex = 0;
  403. else if (angleY > rangeRotateY[1]) outBoundIndex = 1;
  404. else if (angleX < -rangeRotateX) outBoundIndex = 2;
  405. else if (angleX > rangeRotateX) outBoundIndex = 3;
  406. else outBoundIndex = -1;
  407. if (Mathf.Abs(angleX) > Mathf.Abs(rx))
  408. {
  409. outAngle.x = rx;
  410. }
  411. //因为Vector3是struct,传递给函数是值传递而非引用传递
  412. return outAngle;
  413. }
  414. }
  415. }