CharacterMovement.ts 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. import { _decorator, Component, Node, v3, RigidBody, Vec3, find, Camera, SkeletalAnimation,Animation, AnimationClip, Collider, ICollisionEvent } from 'cc';
  2. import { EasyController, EasyControllerEvent } from './EasyController';
  3. const { ccclass, property } = _decorator;
  4. const v3_1 = v3();
  5. @ccclass('tgxCharacterMovement')
  6. export class CharacterMovement extends Component {
  7. @property(Camera)
  8. mainCamera: Camera;
  9. @property
  10. velocity = 1.0;
  11. @property
  12. jumpVelocity = 1.0;
  13. @property
  14. maxJumpTimes: number = 0;
  15. private _curJumpTimes: number = 0;
  16. @property(AnimationClip)
  17. idleAnimClip: AnimationClip;
  18. @property(AnimationClip)
  19. moveAnimClip: AnimationClip;
  20. @property(AnimationClip)
  21. jumpBeginAnimClip: AnimationClip;
  22. @property(AnimationClip)
  23. jumpLoopAnimClip: AnimationClip;
  24. @property(AnimationClip)
  25. jumpLandAnimClip: AnimationClip;
  26. _rigidBody: RigidBody;
  27. _isMoving: boolean = false;
  28. _velocityScale: number = 1.0;
  29. _isInTheAir: boolean = false;
  30. _currentVerticalVelocity: number = 0.0;
  31. private _anim: Animation;
  32. start() {
  33. if (!this.mainCamera) {
  34. this.mainCamera = find('Main Camera')?.getComponent(Camera);
  35. }
  36. this._rigidBody = this.node.getComponent(RigidBody);
  37. this._anim = this.node.getComponent(Animation);
  38. if (this._anim) {
  39. let clipArr = [
  40. this.idleAnimClip,
  41. this.moveAnimClip,
  42. this.jumpBeginAnimClip,
  43. this.jumpLoopAnimClip,
  44. this.jumpLandAnimClip
  45. ];
  46. for (let i = 0; i < clipArr.length; ++i) {
  47. let clip = clipArr[i];
  48. if (clip) {
  49. if (!this._anim.getState(clip.name)) {
  50. this._anim.addClip(clip);
  51. }
  52. }
  53. }
  54. if (this.idleAnimClip) {
  55. this._anim.play(this.idleAnimClip.name);
  56. }
  57. }
  58. EasyController.on(EasyControllerEvent.MOVEMENT, this.onMovement, this);
  59. EasyController.on(EasyControllerEvent.MOVEMENT_STOP, this.onMovementRelease, this);
  60. EasyController.on(EasyControllerEvent.BUTTON, this.onJump, this);
  61. let myCollider = this.getComponent(Collider);
  62. myCollider?.on('onCollisionEnter',(target:ICollisionEvent)=>{
  63. if(target.otherCollider != target.selfCollider){
  64. this.onLand();
  65. }
  66. });
  67. }
  68. onDestroy() {
  69. EasyController.off(EasyControllerEvent.MOVEMENT, this.onMovement, this);
  70. EasyController.off(EasyControllerEvent.MOVEMENT_STOP, this.onMovementRelease, this);
  71. EasyController.off(EasyControllerEvent.MOVEMENT_STOP, this.onJump, this);
  72. }
  73. update(deltaTime: number) {
  74. if (this._isMoving) {
  75. this._tmp.set(this.node.forward);
  76. this._tmp.multiplyScalar(-1.0);
  77. this._tmp.multiplyScalar(this.velocity * this._velocityScale);
  78. if (this._rigidBody) {
  79. this._rigidBody.getLinearVelocity(v3_1);
  80. this._tmp.y = v3_1.y;
  81. this._rigidBody.setLinearVelocity(this._tmp);
  82. }
  83. else {
  84. this._tmp.multiplyScalar(deltaTime);
  85. this._tmp.add(this.node.position);
  86. this.node.setPosition(this._tmp);
  87. }
  88. }
  89. if (this._isInTheAir) {
  90. if(this.jumpBeginAnimClip && this._anim){
  91. let state = this._anim.getState(this.jumpBeginAnimClip.name);
  92. if(state.isPlaying && state.current >= state.duration){
  93. if(this.jumpLoopAnimClip){
  94. this._anim.crossFade(this.jumpLoopAnimClip.name);
  95. }
  96. }
  97. }
  98. if(!this._rigidBody){
  99. this._currentVerticalVelocity -= 9.8 * deltaTime;
  100. let oldPos = this.node.position;
  101. let nextY = oldPos.y + this._currentVerticalVelocity * deltaTime;
  102. if (nextY <= 0) {
  103. this.onLand();
  104. nextY = 0.0;
  105. }
  106. this.node.setPosition(oldPos.x, nextY, oldPos.z);
  107. }
  108. }
  109. }
  110. onLand(){
  111. this._isInTheAir = false;
  112. this._currentVerticalVelocity = 0.0;
  113. this._curJumpTimes = 0;
  114. if (this.moveAnimClip) {
  115. if(this._isMoving){
  116. this._anim.crossFade(this.moveAnimClip.name, 0.5);
  117. }
  118. else{
  119. this._anim.crossFade(this.idleAnimClip.name, 0.5);
  120. }
  121. }
  122. }
  123. private _tmp = v3();
  124. onMovement(degree: number, offset: number) {
  125. let cameraRotationY = 0;
  126. if (this.mainCamera) {
  127. cameraRotationY = this.mainCamera.node.eulerAngles.y;
  128. }
  129. this._velocityScale = offset;
  130. //2D界面是 正X 为 0, 3D场景是 正前方为0,所以需要 - 90 度。(顺时针转90度)
  131. this._tmp.set(0, cameraRotationY + degree - 90 + 180, 0);
  132. this.node.setRotationFromEuler(this._tmp);
  133. if (this._anim) {
  134. if (!this._isMoving && !this._isInTheAir) {
  135. if (this.moveAnimClip) {
  136. this._anim.crossFade(this.moveAnimClip.name, 0.1);
  137. }
  138. }
  139. if (this.moveAnimClip) {
  140. this._anim.getState(this.moveAnimClip.name).speed = this._velocityScale;
  141. }
  142. }
  143. this._isMoving = true;
  144. }
  145. onMovementRelease() {
  146. if (!this._isInTheAir && this.idleAnimClip) {
  147. this._anim?.crossFade(this.idleAnimClip.name, 0.5);
  148. }
  149. this._isMoving = false;
  150. if (this._rigidBody) {
  151. this._rigidBody.setLinearVelocity(Vec3.ZERO);
  152. }
  153. }
  154. onJump(btnName:string) {
  155. console.log(btnName);
  156. if(btnName != 'btn_slot_0'){
  157. return;
  158. }
  159. if (this._curJumpTimes >= this.maxJumpTimes) {
  160. return;
  161. }
  162. if(this._curJumpTimes == 0 || true){
  163. if(this.jumpBeginAnimClip){
  164. this._anim?.crossFade(this.jumpBeginAnimClip.name);
  165. }
  166. }
  167. this._curJumpTimes++;
  168. if(this._rigidBody){
  169. this._rigidBody.getLinearVelocity(v3_1);
  170. v3_1.y = this.jumpVelocity;
  171. this._rigidBody.setLinearVelocity(v3_1);
  172. }
  173. else{
  174. this._currentVerticalVelocity = this.jumpVelocity;
  175. }
  176. this._isInTheAir = true;
  177. }
  178. }