Jump to content

Recommended Posts

Posted

Hello,

I'm attempting to create a mod with blocks and items rendered using .obj files. I have been able to successfully render a block from an .obj file, but rendering an item is proving to be much more difficult, and it relentlessly shows up as the pink and black texture in game. I cannot figure out what I am doing wrong. 

 

Here is my item's class:

public ItemSonicScrewdriver() {
        setRegistryName("itemsonicscrewdriver");
        setUnlocalizedName(OperationBlueBox.MODID + ".itemsonicscrewdriver");
    }

    @SideOnly(Side.CLIENT)
    public void initModel() {
        ModelLoader.setCustomModelResourceLocation(this, 0, new ModelResourceLocation(getRegistryName(), "inventory"));
    }

 

And here's how I've registered it in my ModItems class, which is then used in my ClientProxy:

@GameRegistry.ObjectHolder("operationbluebox:itemsonicscrewdriver")
    public static ItemSonicScrewdriver itemSonicScrewdriver;

    @SideOnly(Side.CLIENT)
    public static void initModels() {
        itemSonicScrewdriver.initModel();
    }

I've also tried using someone's block states file that seemed to work for them:

Spoiler

{
  "forge_marker": 1,
  "defaults": {
    "textures": {
      "#itemsonicscrewdriver": "operationbluebox:items/sonicscrewdrivertexture"
    },
    "model": "operationbluebox:itemsonicscrewdriver.obj"
  },
  "variants": {
    "normal": [{}],
    "inventory": [{
      "transform": {
        "firstperson": {
          "translation": [0.1, 0, -0.3],
          "rotation": [ { "y": 130}, {"x": 0}, {"z": 0} ],
          "scale": 0.2
        },
        "thirdperson": {
          "translation": [0.02, 0.05, -0.05],
          "rotation": [ { "y": 0}, {"x": -92}, {"z": 0} ],
          "scale": 0.07
        },
        "gui": {
          "translation": [0, -0.1, 0],
          "scale": 0.16
        }
      }
    }]
  }
}

 

And I have made sure to place the .obj and .mtl files in my models/block folder. All help is appreciated.

Posted
10 hours ago, Matryoshika said:

You have to call OBJLoader.INSTANCE.addDomain(MODID) before you register you models

I have done so in my ClientProxy, so I'm sure this can't be the issue ... unless I did it wrong somehow.

@Override
    public void preInit(FMLPreInitializationEvent event) {
        super.preInit(event);

        OBJLoader.INSTANCE.addDomain(OperationBlueBox.MODID);
    }

    @SubscribeEvent
    public static void registerModels(ModelRegistryEvent event) {
        ModBlocks.initModels();
        ModItems.initModels();
    }

 

I also find it weird that after running the Minecraft client, this shows in my console, which makes it seem as though it has loaded the .obj model, even though it does not show up in-game:

[FML]: OBJLoader.MaterialLibrary: key 'Ns' (model: 'operationbluebox:models/block/itemsonicscrewdriver.mtl') is not currently supported, skipping
[10:28:08] [main/INFO] [FML]: OBJModel: A color has already been defined for material 'itemsonicscrewdriver' in 'operationbluebox:models/block/itemsonicscrewdriver.mtl'. The color defined by key 'Ks' will not be applied!
[10:28:08] [main/INFO] [FML]: OBJLoader.MaterialLibrary: key 'Ke' (model: 'operationbluebox:models/block/itemsonicscrewdriver.mtl') is not currently supported, skipping
[10:28:08] [main/INFO] [FML]: OBJLoader.MaterialLibrary: key 'Ni' (model: 'operationbluebox:models/block/itemsonicscrewdriver.mtl') is not currently supported, skipping
[10:28:08] [main/INFO] [FML]: OBJLoader.MaterialLibrary: key 'illum' (model: 'operationbluebox:models/block/itemsonicscrewdriver.mtl') is not currently supported, skipping

 

Posted (edited)

The errors are fine. It's just extra fanciness that the ObjLoader won't support
Is the item a purple/black cube?
Or is it just "empty"?

Oh, and you should put the OBjLoader#addDomain call inside the registerModels method, before you call ModBlocks.initModels().

Edited by Matryoshika

Also previously known as eAndPi.

"Pi, is there a station coming up where we can board your train of thought?" -Kronnn

Published Mods: Underworld

Handy links: Vic_'s Forge events Own WIP Tutorials.

Posted (edited)

Check that the obj file is decorated at some point with the field usemtl itemsonicscrewdriver and that the mtl is decorated with the field newmtl itemsonicscrewdriver and that there is a definition for said material. 

 

To rule out whether it is a problem taking root in the way the JSON file is written or a problem in the obj and mtl files, remove temporarily the application of the texture in the JSON file and try to apply the texture in the mtl file instead by decorating at the end of the material definition (in the mtl file) with map_Kd operationbluebox:items/sonicscrewdrivertexture.

 

Edit: Does your object extends from item or from block? Because the model appears to be loaded from the block models according to the log, but the naming used gives the impression that it is an item. If it is a block, it also needs to be registered as an item as far as I'm concerned. Sometimes, when one fails to register the item form of a block, the texture appears well in the inventory and when in hand, but when the block is placed in the world, the texture is purple and black. And no error appears on the log. That's why I ask.

Edited by ctbe
Posted

So my .obj file was exported from blender, and has the field mtllib itemsonicscrewdriver.mtl which seems to work, since it does give information on the .mtl file in the console log. Section of my .obj file:

Spoiler

# Blender v2.78 (sub 0) OBJ File: ''
# www.blender.org
mtllib itemsonicscrewdriver.mtl
o SonicScrewdriverReal
v 0.125000 5.000000 0.125001
v -0.125000 -0.000000 0.125000

And I already did have the map_Kd operationbluebox:items/sonicscrewdrivertexture in my .mtl file. Is this problematic to have the texture applied in both the .mtl file and the .json blockstate file? I tried running the mod once with only the texture defined in the .json, and once with it only defined in the .mtl, but neither worked. My .mtl file:

Spoiler

# Blender MTL File: 'None'
# Material Count: 1

newmtl itemsonicscrewdriver
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
map_Kd operationbluebox:items/sonicscrewdrivertexture

 

 

And I'm trying to register this model as an item only, but I'm also trying to have it use a blockstate file in order to add rotations and other information to the model. 

 

I'm pretty certain that the model isn't working because I've done something wrong with the .json in the blockstates folder, but I'm not entirely sure.

Posted (edited)

Hi there,

 

EDiT:

So, I have to pull back my "having probably the same problem" reply, because I found what was wrong at my side: î 

Thats right. As some might have noticed, my mod may end up with something that starts with "ianus".  And while being sad that nothing worked at my side, I noticed that the blockfile.json for that .obj I created was oddly out of sorting, at the very bottom of its folder, while it should have been somewhere in the middle. 

Turns out, I somehow hit the stargate-key at my keyboard when writing the blockstates filename, so instead of   i   I got an   î  .... now try to spot this with monitors keep on growing and growing. 

 

Anyway, one thing from my original post remains: 

 

Regarding the "no error log", I had a similiar experience, but than one of the veterans from forge pointed out that I do use a forge version where the model problem log output was broken.

At the moment my forge is... 2402. You may try updating, if you haven't, to get some more error output.

 

Now... hoping for helping hands too,

 

Confused Merlin

Edited by ConfusedMerlin
found my problem, and its unlikely to be his too
  • 7 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • So me and a couple of friends are playing with a shitpost mod pack and one of the mods in the pack is corail tombstone and for some reason there is a problem with it, where on death to fire the player will get kicked out of the server and the tombstone will not spawn basically deleting an entire inventory, it doesn't matter what type of fire it is, whether it's from vanilla fire/lava, or from modded fire like ice&fire/lycanites and it's common enough to where everyone on the server has experienced at least once or twice and it doesn't give any crash log. a solution to this would be much appreciated thank you!
    • It is 1.12.2 - I have no idea if there is a 1.12 pack
    • Okay, but does the modpack works with 1.12 or just with 1.12.2, because I need the Forge client specifically for Minecraft 1.12, not 1.12.2
    • Version 1.19 - Forge 41.0.63 I want to create a wolf entity that I can ride, so far it seems to be working, but the problem is that when I get on the wolf, I can’t control it. I then discovered that the issue is that the server doesn’t detect that I’m riding the wolf, so I’m struggling with synchronization. However, it seems to not be working properly. As I understand it, the server receives the packet but doesn’t register it correctly. I’m a bit new to Java, and I’ll try to provide all the relevant code and prints *The comments and prints are translated by chatgpt since they were originally in Spanish* Thank you very much in advance No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. MountableWolfEntity package com.vals.valscraft.entity; import com.vals.valscraft.network.MountSyncPacket; import com.vals.valscraft.network.NetworkHandler; import net.minecraft.client.Minecraft; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.animal.Wolf; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.Entity; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; import net.minecraftforge.event.TickEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.network.PacketDistributor; public class MountableWolfEntity extends Wolf { private boolean hasSaddle; private static final EntityDataAccessor<Byte> DATA_ID_FLAGS = SynchedEntityData.defineId(MountableWolfEntity.class, EntityDataSerializers.BYTE); public MountableWolfEntity(EntityType<? extends Wolf> type, Level level) { super(type, level); this.hasSaddle = false; } @Override protected void defineSynchedData() { super.defineSynchedData(); this.entityData.define(DATA_ID_FLAGS, (byte)0); } public static AttributeSupplier.Builder createAttributes() { return Wolf.createAttributes() .add(Attributes.MAX_HEALTH, 20.0) .add(Attributes.MOVEMENT_SPEED, 0.3); } @Override public InteractionResult mobInteract(Player player, InteractionHand hand) { ItemStack itemstack = player.getItemInHand(hand); if (itemstack.getItem() == Items.SADDLE && !this.hasSaddle()) { if (!player.isCreative()) { itemstack.shrink(1); } this.setSaddle(true); return InteractionResult.SUCCESS; } else if (!level.isClientSide && this.hasSaddle()) { player.startRiding(this); MountSyncPacket packet = new MountSyncPacket(true); // 'true' means the player is mounted NetworkHandler.CHANNEL.sendToServer(packet); // Ensure the server handles the packet return InteractionResult.SUCCESS; } return InteractionResult.PASS; } @Override public void travel(Vec3 travelVector) { if (this.isVehicle() && this.getControllingPassenger() instanceof Player) { System.out.println("The wolf has a passenger."); System.out.println("The passenger is a player."); Player player = (Player) this.getControllingPassenger(); // Ensure the player is the controller this.setYRot(player.getYRot()); this.yRotO = this.getYRot(); this.setXRot(player.getXRot() * 0.5F); this.setRot(this.getYRot(), this.getXRot()); this.yBodyRot = this.getYRot(); this.yHeadRot = this.yBodyRot; float forward = player.zza; float strafe = player.xxa; if (forward <= 0.0F) { forward *= 0.25F; } this.flyingSpeed = this.getSpeed() * 0.1F; this.setSpeed((float) this.getAttributeValue(Attributes.MOVEMENT_SPEED) * 1.5F); this.setDeltaMovement(new Vec3(strafe, travelVector.y, forward).scale(this.getSpeed())); this.calculateEntityAnimation(this, false); } else { // The wolf does not have a passenger or the passenger is not a player System.out.println("No player is mounted, or the passenger is not a player."); super.travel(travelVector); } } public boolean hasSaddle() { return this.hasSaddle; } public void setSaddle(boolean hasSaddle) { this.hasSaddle = hasSaddle; } @Override protected void dropEquipment() { super.dropEquipment(); if (this.hasSaddle()) { this.spawnAtLocation(Items.SADDLE); this.setSaddle(false); } } @SubscribeEvent public static void onServerTick(TickEvent.ServerTickEvent event) { if (event.phase == TickEvent.Phase.START) { MinecraftServer server = net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer(); if (server != null) { for (ServerPlayer player : server.getPlayerList().getPlayers()) { if (player.isPassenger() && player.getVehicle() instanceof MountableWolfEntity) { MountableWolfEntity wolf = (MountableWolfEntity) player.getVehicle(); System.out.println("Tick: " + player.getName().getString() + " is correctly mounted on " + wolf); } } } } } private boolean lastMountedState = false; @Override public void tick() { super.tick(); if (!this.level.isClientSide) { // Only on the server boolean isMounted = this.isVehicle() && this.getControllingPassenger() instanceof Player; // Only print if the state changed if (isMounted != lastMountedState) { if (isMounted) { Player player = (Player) this.getControllingPassenger(); // Verify the passenger is a player System.out.println("Server: Player " + player.getName().getString() + " is now mounted."); } else { System.out.println("Server: The wolf no longer has a passenger."); } lastMountedState = isMounted; } } } @Override public void addPassenger(Entity passenger) { super.addPassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(true)); } } } @Override public void removePassenger(Entity passenger) { super.removePassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is no longer mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(false)); } } } @Override public boolean isControlledByLocalInstance() { Entity entity = this.getControllingPassenger(); return entity instanceof Player; } @Override public void positionRider(Entity passenger) { if (this.hasPassenger(passenger)) { double xOffset = Math.cos(Math.toRadians(this.getYRot() + 90)) * 0.4; double zOffset = Math.sin(Math.toRadians(this.getYRot() + 90)) * 0.4; passenger.setPos(this.getX() + xOffset, this.getY() + this.getPassengersRidingOffset() + passenger.getMyRidingOffset(), this.getZ() + zOffset); } } } MountSyncPacket package com.vals.valscraft.network; import com.vals.valscraft.entity.MountableWolfEntity; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class MountSyncPacket { private final boolean isMounted; public MountSyncPacket(boolean isMounted) { this.isMounted = isMounted; } public void encode(FriendlyByteBuf buffer) { buffer.writeBoolean(isMounted); } public static MountSyncPacket decode(FriendlyByteBuf buffer) { return new MountSyncPacket(buffer.readBoolean()); } public void handle(NetworkEvent.Context context) { context.enqueueWork(() -> { ServerPlayer player = context.getSender(); // Get the player from the context if (player != null) { // Verifies if the player has dismounted if (!isMounted) { Entity vehicle = player.getVehicle(); if (vehicle instanceof MountableWolfEntity wolf) { // Logic to remove the player as a passenger wolf.removePassenger(player); System.out.println("Server: Player " + player.getName().getString() + " is no longer mounted."); } } } }); context.setPacketHandled(true); // Marks the packet as handled } } networkHandler package com.vals.valscraft.network; import com.vals.valscraft.valscraft; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.network.NetworkRegistry; import net.minecraftforge.network.simple.SimpleChannel; import net.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class NetworkHandler { private static final String PROTOCOL_VERSION = "1"; public static final SimpleChannel CHANNEL = NetworkRegistry.newSimpleChannel( new ResourceLocation(valscraft.MODID, "main"), () -> PROTOCOL_VERSION, PROTOCOL_VERSION::equals, PROTOCOL_VERSION::equals ); public static void init() { int packetId = 0; // Register the mount synchronization packet CHANNEL.registerMessage( packetId++, MountSyncPacket.class, MountSyncPacket::encode, MountSyncPacket::decode, (msg, context) -> msg.handle(context.get()) // Get the context with context.get() ); } }  
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.