场景:
Fabric官方自定义粒子教程生成的粒子太过单调,仅仅只是教会你自定义纹理贴图?这一点都不合理。而本教程旨在能够给粒子添加更多的属性,并且能够在游戏运行时创建含有特定数据的粒子,比如粒子的生命周期❤️!
准备:
需要的几个类(按照自己习惯取名):
1 2 3
| CustomPtcEffect.java【自定义粒子效果(拿来传递参数的)】 CustomPtc.java 【自定义的粒子,这个类主要拿来使用参数的】 然后就是一些其它需要你注册粒子的地方。
|
如果你需要熟练掌握,那么你还得了解一些CODEC(序列化)的知识。
开始:
经过前面的准备,以及可以开始了🚙!
一,编写主要类
CustomPtcEffect.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
public class CustomPtcEffect implements ParticleEffect { public static final PacketCodec<ByteBuf, CustomPtcEffect> PACKET_CODEC = PacketCodec.of( (val, buf) -> { buf.writeInt(val.lifeTick); }, buf -> new CustomPtcEffect(null, buf.readInt()) ); private static final Codec<Integer> TICK_CODEC = Codec.INT; private final ParticleType<CustomPtcEffect> type; private final Integer lifeTick;
public CustomPtcEffect(ParticleType<CustomPtcEffect> type, Integer lifeTick) { this.type = type; this.lifeTick = lifeTick; }
public static MapCodec<CustomPtcEffect> createCodec(ParticleType<CustomPtcEffect> type) { return TICK_CODEC.<CustomPtcEffect>xmap(t -> new CustomPtcEffect(type, t), ptcEffect -> ptcEffect.lifeTick).fieldOf("tick"); }
public static PacketCodec<? super ByteBuf, CustomPtcEffect> createPacketCodec(ParticleType<CustomPtcEffect> type) { return PACKET_CODEC.xmap(t -> new CustomPtcEffect(type, t.lifeTick), ptcEffect -> ptcEffect); }
@Override public ParticleType<CustomPtcEffect> getType() { return this.type; }
public Integer getLifeTick() { return this.lifeTick; } }
|
CustomPtc.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
|
public class CustomPtc extends SpriteBillboardParticle { private final CustomPtcEffect parameters; private final SpriteProvider sprite;
protected CustomPtc(ClientWorld clientWorld, double d, double e, double f, CustomPtcEffect parameters, SpriteProvider sprite) { super(clientWorld, d, e, f); this.parameters = parameters; this.sprite = sprite; this.setMaxAge(parameters.getLifeTick()); this.setSprite(sprite); }
@Override public ParticleTextureSheet getType() { return ParticleTextureSheet.PARTICLE_SHEET_OPAQUE; }
@Environment(EnvType.CLIENT) public static class Factory implements ParticleFactory<CustomPtcEffect> { private final SpriteProvider spriteProvider;
public Factory(SpriteProvider spriteProvider) { this.spriteProvider = spriteProvider; }
public Particle createParticle(CustomPtcEffect effect, ClientWorld clientWorld, double d, double e, double f, double g, double h, double i) { return new CustomPtc(clientWorld, d, e, f, effect, this.spriteProvider); } } }
|
二,注册:
刚才已经完成了类的编写,那么现在来注册这它们吧!
1,注册服务端粒子效果类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public static final ParticleType<CustomPtcEffect> CUSTOM_PTC_EFFECT = register("custom_ptc_effect", true, CustomPtcEffect::createCodec, CustomPtcEffect::createPacketCodec);
private static <T extends ParticleEffect> ParticleType<T> register( String name, boolean alwaysShow, Function<ParticleType<T>, MapCodec<T>> codecGetter, Function<ParticleType<T>, PacketCodec<? super RegistryByteBuf, T>> packetCodecGetter ) { return Registry.register(Registries.PARTICLE_TYPE, Identifier.of(MOD_ID,name), new ParticleType<T>(alwaysShow) { @Override public MapCodec<T> getCodec() { return codecGetter.apply(this); } @Override public PacketCodec<? super RegistryByteBuf, T> getPacketCodec() { return packetCodecGetter.apply(this); } }); }
|
2,注册客户端粒子类
这里很简单!
1
| ParticleFactoryRegistry.getInstance().register(TrParticle.CUSTOM_PTC_EFFECT, CustomPtc.Factory::new);
|
三,提示(使用):
该方法注册的粒子不能通过指令生成,只能在代码里面生成,就像这样⬇️:
1
| world.addParticle(new CustomPtcEffect(TrParticle.CUSTOM_PTC_EFFECT,15),pos.x,pos.y,pos.z,0,0,0);
|
踩坑: