ThirdPersonCamera.ts 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import { _decorator, Component, Node, Vec3, v3 } from 'cc';
  2. const { ccclass, property } = _decorator;
  3. const v3_1 = v3();
  4. const v3_2 = v3();
  5. const ROTATION_STRENGTH = 20.0;
  6. @ccclass('ThirdPersonCamera')
  7. export class ThirdPersonCamera extends Component {
  8. @property(Node)
  9. target: Node;
  10. @property
  11. lookAtOffset: Vec3 = v3();
  12. @property
  13. zoomSensitivity: number = 1.0;
  14. @property
  15. lenMin: number = 10.0;
  16. @property
  17. lenMax: number = 100.0; //值越大镜头越远
  18. @property
  19. len: number = 5;
  20. @property
  21. rotateVHSeparately: boolean = false;
  22. @property
  23. tweenTime: number = 0.2;
  24. protected _targetLen: number = 0;
  25. protected _targetAngles: Vec3 = v3();
  26. start() {
  27. this._targetLen = this.len;
  28. this._targetAngles.set(this.node.eulerAngles);
  29. }
  30. setLenFactor(factor: number) {
  31. let len = (this.lenMax - this.lenMin) * factor + this.lenMin;
  32. this._targetLen = len;
  33. }
  34. setTargetAngles(x: number, y: number, z: number) {
  35. this._targetAngles.set(x, y, z);
  36. }
  37. lateUpdate(deltaTime: number) {
  38. if (!this.target) {
  39. return;
  40. }
  41. const t = Math.min(deltaTime / this.tweenTime, 1.0);
  42. //rotation
  43. v3_1.set(this.node.eulerAngles);
  44. Vec3.lerp(v3_1, v3_1, this._targetAngles, t);
  45. this.node.setRotationFromEuler(v3_1);
  46. //lookat
  47. v3_1.set(this.target.worldPosition);
  48. v3_1.add(this.lookAtOffset);
  49. //len and position
  50. this.len = this.len * (1.0 - t) + this._targetLen * t;
  51. v3_2.set(this.node.forward);
  52. v3_2.multiplyScalar(this.len);
  53. v3_1.subtract(v3_2);
  54. this.node.setPosition(v3_1);
  55. }
  56. onCameraRotate(deltaX: number, deltaY: number) {
  57. let eulerAngles = this.node.eulerAngles;
  58. if (this.rotateVHSeparately) {
  59. if (Math.abs(deltaX) > Math.abs(deltaY)) {
  60. deltaY = 0;
  61. }
  62. else {
  63. deltaX = 0;
  64. }
  65. }
  66. this._targetAngles.set(eulerAngles.x + deltaX * ROTATION_STRENGTH, eulerAngles.y + deltaY * ROTATION_STRENGTH, eulerAngles.z);
  67. }
  68. onCameraZoom(view: number) {
  69. // this._targetLen += delta * this.zoomSensitivity;
  70. this._targetLen = view;
  71. if (this._targetLen < this.lenMin) {
  72. this._targetLen = this.lenMin;
  73. }
  74. if (this._targetLen > this.lenMax) {
  75. this._targetLen = this.lenMax;
  76. }
  77. }
  78. }