import { _decorator, CCBoolean, CCFloat, Collider, Component, isValid, ITriggerEvent, Material, MeshRenderer, Node, PhysicsSystem, Quat, RigidBody, tween, Tween, Vec3 } from 'cc'; import { EventDispatcher } from 'db://assets/core_tgx/easy_ui_framework/EventDispatcher'; import { GameEvent } from '../Enum/GameEvent'; import { GameUtil } from '../GameUtil'; const { ccclass, property,executeInEditMode } = _decorator; export enum EnemyStatus { LIFE, DIE } @ccclass('EnemyComponent') @executeInEditMode export class EnemyComponent extends Component { @property(RigidBody) rigidBody: RigidBody = null!; @property(Node) head: Node = null!; @property(Node) leftHand: Node = null!; @property(Node) rightHand: Node = null!; @property(Node) leftFoot: Node = null!; @property(Node) rightFoot: Node = null!; @property(Node) eyeRender: Node = null!; @property(Node) bodyRender: Node = null!; @property(Material) hitEyeMaterial: Material = null!; // 击中眼睛的材质 @property(Material) hitMaterial: Material = null!; // 击中时身体的材质 currentHp: number = 0; status: EnemyStatus = EnemyStatus.LIFE; speed: number = 50; headshot: boolean = false; tigger: Collider = null!; protected onLoad(): void { this.tigger = this.node.getComponent(Collider)!; } start() { this.status = EnemyStatus.LIFE; this.tigger = this.node.getComponent(Collider)!; this.rigidBody.isKinematic = true; this.registerEvent(); } private registerEvent() { this.tigger.on('onTriggerEnter', this.onTriggerEnter, this); EventDispatcher.instance.on(GameEvent.EVENT_CAMERA_SHOOT_ENEMY, this.onShootEnemy, this); } private unRegisterEvent() { this.tigger.off('onTriggerEnter', this.onTriggerEnter, this); } protected onTriggerEnter(event: ITriggerEvent): void { } private async onShootEnemy(hitNode: Node) { // 检查是否是当前怪物节点被击中 if (this.node === hitNode && this.status === EnemyStatus.LIFE) { this.status = EnemyStatus.DIE; // 修改所有部位材质为击中材质 this.changeMaterial(); this.playHitTwitch(); await GameUtil.delay(0.5); this.rigidBody.isKinematic = false; this.rigidBody.isDynamic = true; await GameUtil.delay(0.3); this.node.destroy(); } } private changeMaterial() { if (!this.bodyRender || !this.hitMaterial) return; const renderer = this.bodyRender.getComponent(MeshRenderer); const eyeRenderer = this.eyeRender.getComponent(MeshRenderer); if (renderer) { renderer.material = this.hitMaterial; } if (eyeRenderer) { eyeRenderer.material = this.hitEyeMaterial; } } // 中枪抽搐效果 playHitTwitch() { // 抖动参数配置 const shakeConfig = { head: { times: 5, duration: 0.12 }, leftHand: { times: 6, duration: 0.1 }, rightHand: { times: 6, duration: 0.15 }, leftFoot: { times: 5, duration: 0.13 }, rightFoot: { times: 5, duration: 0.13 } }; // 生成随机抖动值 const getRandomShake = () => (10 + Math.random() * 10) * (Math.random() > 0.5 ? 1 : -1); // 创建抖动动画函数 const createShakeTween = (node: Node, config: { times: number, duration: number }) => { const t = tween(node); for (let i = 0; i < config.times; i++) { const euler = new Vec3(); node.rotation.getEulerAngles(euler); const shakeValue = getRandomShake(); const newEuler = new Vec3(euler.x + shakeValue, euler.y + shakeValue, euler.z); const newRotation = new Quat(); Quat.fromEuler(newRotation, newEuler.x, newEuler.y, newEuler.z); t.to(config.duration, { rotation: newRotation }); } return t; }; // 头部抖动 createShakeTween(this.head, shakeConfig.head).start(); // 左手抖动 createShakeTween(this.leftHand, shakeConfig.leftHand).start(); // 右手抖动 createShakeTween(this.rightHand, shakeConfig.rightHand).start(); // 左腿抖动 createShakeTween(this.leftFoot, shakeConfig.leftFoot).start(); // 右腿抖动 createShakeTween(this.rightFoot, shakeConfig.rightFoot).start(); } protected onDestroy(): void { Tween.stopAllByTarget(this.node); this.unRegisterEvent(); } }