| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- import { _decorator, Component, Node, MotionStreak, Color, Texture2D } from 'cc';
- const { ccclass, property } = _decorator;
- /**
- * 子弹拖尾控制器
- * 负责管理子弹的拖尾效果
- */
- @ccclass('BulletTrailController')
- export class BulletTrailController extends Component {
-
- @property({
- type: MotionStreak,
- tooltip: '拖尾组件引用'
- })
- public motionStreak: MotionStreak | null = null;
- private secondaryStreak: MotionStreak | null = null;
-
- // 拖尾配置
- private trailConfig = {
- fadeTime: 0.5, // 拖尾消失时间
- minSeg: 1, // 最小分段
- stroke: 30, // 拖尾宽度
- fastMode: false // 快速模式
- };
-
- // 预设颜色
- private trailColors = {
- default: new Color(255, 255, 0, 255), // 黄色
- white: new Color(255, 255, 255, 255), // 白色
- fire: new Color(255, 100, 0, 255), // 橙红色
- gold: new Color(255, 200, 80, 255), // 金黄(更接近外黄效果)
- ice: new Color(0, 200, 255, 255), // 冰蓝色
- poison: new Color(100, 255, 0, 255), // 毒绿色
- electric: new Color(200, 0, 255, 255) // 紫色
- };
-
- onLoad() {
- this.initializeTrail();
- }
-
- /**
- * 初始化拖尾效果
- */
- private initializeTrail() {
- if (!this.motionStreak) {
- // 尝试从子节点中查找MotionStreak组件
- this.motionStreak = this.getComponentInChildren(MotionStreak);
-
- if (!this.motionStreak) {
- // 尝试从当前节点获取
- this.motionStreak = this.getComponent(MotionStreak);
- }
- }
-
- if (this.motionStreak) {
- this.applyTrailConfig();
- }
- }
-
- /**
- * 应用拖尾配置
- */
- private applyTrailConfig() {
- if (!this.motionStreak) return;
-
- this.motionStreak.fadeTime = this.trailConfig.fadeTime;
- this.motionStreak.minSeg = this.trailConfig.minSeg;
- this.motionStreak.stroke = this.trailConfig.stroke;
- this.motionStreak.fastMode = this.trailConfig.fastMode;
- // 保持当前颜色,不在通用配置中强制重置为白色,避免覆盖武器专属颜色
- }
-
- /**
- * 设置拖尾颜色
- * @param colorType 颜色类型
- */
- public setTrailColor(colorType: 'default' | 'white' | 'fire' | 'ice' | 'poison' | 'electric') {
- if (!this.motionStreak) return;
-
- const color = this.trailColors[colorType];
- if (color) {
- this.motionStreak.color = color;
- }
- }
-
- /**
- * 设置自定义拖尾颜色
- * @param color 颜色
- */
- public setCustomTrailColor(color: Color) {
- if (!this.motionStreak) return;
-
- this.motionStreak.color = color;
- }
-
- /**
- * 设置拖尾宽度
- * @param width 宽度
- */
- public setTrailWidth(width: number) {
- if (!this.motionStreak) return;
-
- this.trailConfig.stroke = width;
- this.motionStreak.stroke = width;
- }
-
- /**
- * 设置拖尾消失时间
- * @param fadeTime 消失时间
- */
- public setTrailFadeTime(fadeTime: number) {
- if (!this.motionStreak) return;
-
- this.trailConfig.fadeTime = fadeTime;
- this.motionStreak.fadeTime = fadeTime;
- }
- /**
- * 设置拖尾最小分段(越小越平滑,减少三角形感)
- * @param minSeg 最小分段
- */
- public setTrailMinSeg(minSeg: number) {
- if (!this.motionStreak) return;
- this.trailConfig.minSeg = minSeg;
- this.motionStreak.minSeg = minSeg;
- }
-
- /**
- * 设置拖尾纹理
- * @param texture 纹理
- */
- public setTrailTexture(texture: Texture2D) {
- if (!this.motionStreak) return;
-
- this.motionStreak.texture = texture;
- if (this.secondaryStreak) {
- this.secondaryStreak.texture = texture;
- }
- }
- /**
- * 设置快速模式(拖尾响应更灵敏)
- */
- public setFastMode(enabled: boolean) {
- if (!this.motionStreak) return;
- this.trailConfig.fastMode = enabled;
- this.motionStreak.fastMode = enabled;
- }
- /**
- * 预设:火焰喷射拖尾(用于秋葵导弹)
- */
- public applyPresetRocket() {
- if (!this.motionStreak) return;
- // 颜色:火焰橙红
- this.setTrailColor('fire');
- // 更粗的拖尾,形成喷焰柱效果
- this.setTrailWidth(36);
- // 更短的消失时间,拖尾更紧凑
- this.setTrailFadeTime(0.14);
- // 更小的分段让曲线更贴合,避免顶部太宽的三角形感
- this.setTrailMinSeg(0.05);
- // 启用快速模式,响应更快
- this.setFastMode(true);
- // 在下一帧再次强制颜色,防止其他初始化流程覆盖颜色(例如材质或默认值)
- this.scheduleOnce(() => {
- if (this.motionStreak) {
- this.motionStreak.color = this.trailColors.fire;
- }
- }, 0);
- }
-
- /**
- * 启用拖尾效果
- */
- public enableTrail() {
- if (this.motionStreak) {
- this.motionStreak.enabled = true;
- }
- }
-
- /**
- * 禁用拖尾效果
- */
- public disableTrail() {
- if (this.motionStreak) {
- this.motionStreak.enabled = false;
- }
- }
-
- /**
- * 重置拖尾效果
- */
- public resetTrail() {
- if (this.motionStreak) {
- this.motionStreak.reset();
- }
- if (this.secondaryStreak) {
- this.secondaryStreak.reset();
- }
- }
- onDestroy() {
- // 清理资源
- this.motionStreak = null;
- this.secondaryStreak = null;
- }
- /** 创建或获取次级拖尾(用于双层效果) */
- private getOrCreateSecondaryStreak(): MotionStreak | null {
- if (!this.motionStreak) return null;
- if (this.secondaryStreak && this.secondaryStreak.isValid) return this.secondaryStreak;
- try {
- const hostNode = this.motionStreak.node;
- // 为次级拖尾创建一个子节点,避免与主拖尾同节点可能产生的覆盖/冲突
- const child = new Node('TrailEffectSecondary');
- hostNode.addChild(child);
- this.secondaryStreak = child.addComponent(MotionStreak);
- // 复制基础纹理与参数
- this.secondaryStreak.texture = this.motionStreak.texture;
- this.secondaryStreak.minSeg = this.trailConfig.minSeg;
- this.secondaryStreak.fadeTime = this.trailConfig.fadeTime;
- this.secondaryStreak.stroke = this.trailConfig.stroke;
- this.secondaryStreak.fastMode = this.trailConfig.fastMode;
- return this.secondaryStreak;
- } catch (e) {
- console.warn('[BulletTrailController] 创建次级拖尾失败:', e);
- return null;
- }
- }
- /**
- * 预设:双层喷焰(边缘橙红,中心白色)
- */
- public applyPresetRocketDualLayer() {
- if (!this.motionStreak) return;
- // 主拖尾:中心白色,稍窄
- this.setTrailWidth(24);
- this.setTrailFadeTime(0.5);
- this.setTrailMinSeg(1);
- this.setFastMode(false);
- this.setTrailColor('white');
- // 次级拖尾:边缘橙红,更宽
- const secondary = this.getOrCreateSecondaryStreak();
- if (secondary) {
- secondary.stroke = 30;
- secondary.fadeTime = 0.5;
- secondary.minSeg = 1;
- secondary.fastMode = false;
- // 使用金黄色增强外层可见性
- secondary.color = this.trailColors.gold;
- }
- // 保护色:下一帧再次写入
- this.scheduleOnce(() => {
- if (this.motionStreak && this.motionStreak.isValid) {
- this.motionStreak.color = this.trailColors.white;
- }
- if (this.secondaryStreak && this.secondaryStreak.isValid) {
- this.secondaryStreak.color = this.trailColors.gold;
- }
- }, 0);
- }
- }
|