python3dursina

Ursina - Custom model refuses to be textured


I'm using Ursina in Python 3.8

I have a custom model that I made for an entity. I have a texture for that model, exported from my 3D modeling tool as a .png image. I tried applying the texture like this: Entity(model='monolith', scale=0.2, name='monolith', position=(50,0,100), collider='mesh', color=color.dark_gray, texture='/models/monolith')

In-game, the model is just solid black. I tried this with a different model, same result - nothing with a custom model is showing its texture.

How can I get Ursina to texture my custom models?

For this specific example, I'm using a .obj file, but I've seen this issue with .fbx, .glb, and .stl 3D objects
If it helps to know, I made my 3D model with this online tool.

Complete code:

from classes.constants import *
fsmode = getinput("Fullscreen? [Y/N] > ")

if (fsmode == "Y"):fsmode = True
else:fsmode = False

import time as systime, socket, socketserver, random
from ursina import *
import ursina.audio as audio
from ursina.prefabs.first_person_controller import FirstPersonController
from ursina.prefabs.health_bar import HealthBar
from ursina.shaders import *
from threading import Thread as thread

from classes.class_override import *
from classes.custom_classes import *

grav=1
player_model = "/models/player"
pcolor = color.rgb(185, 185, 135)
remoteplayer_color = color.rgb(145, 185, 145)
remoteplayer_disconnected = color.rgb(25,25,25,25)
stored_camera_y = 0
duty_cycle=0
remote_player_connected = False
r_player_justconnected = False
paused = False
block_outgoing_updates = False

app = Ursina(development_mode=False, show_ursina_splash_screen=True,fullscreen=fsmode,title="Reality Simulator (now with Portals!)")

random.seed(0)
Entity.default_shader = lit_with_shadows_shader

ground = Entity(model='plane', collider='box', scale=128, texture='grass', texture_scale=(4,4), name="ground")
ground2 = Entity(model='plane', collider='box', scale=128, texture='grass', texture_scale=(4,4), name="ground", position=(128,0,128))
ground_brick = Entity(model='plane', collider='box', scale=128, texture='grass', texture_scale=(4,4), name="ground", position=(0,0,128))
ground_brick2 = Entity(model='plane', collider='box', scale=128, texture='grass', texture_scale=(4,4), name="ground", position=(128,0,0))
spawning_platform = Entity(model='cube', collider='box', scale=(3,0.5,3), texture='brick', position=(0,0,-10))

editor_camera = EditorCamera(enabled=False, ignore_paused=True, move_speed=30)

player = FirstPersonController(model=player_model, z=-10, y=0.5, color=pcolor, origin_y=0.12, gravity=grav, speed=8, jump_height = 4, height=3, collider='mesh', name="player", cursor=Entity(parent=camera.ui, model='quad', color=color.pink, scale=.001, rotation_z=45))
# player_healthbar = HealthBar(max_value=player.max_hp, animation_duration=0.1, value=player.max_hp, parent=camera.ui)
p2 = Entity(model=player_model, color=remoteplayer_disconnected, scale=1, name='remote_player', x=-5,y=0,z=-5, rotation_y=180)
# sim_symbol = Entity(model='diamond', collider='mesh', color=color.green, name='sim_symbol', parent=player, position=(0,6,0), scale=(.5,1,.5), visible=False)
player.visible_self = False
# player = FirstPersonController(model=player_model, z=-10, color=color.orange, origin_y=-.5, speed=8)
# player.collider = MeshCollider(player, Vec3(0,1,0), Vec3(1,2,1))

arm = Entity(model='portal_gun_2', parent=camera, position=(.5,-.25,0.45), scale=.004, origin_z=-.5, rotation_z=0, on_cooldown=False, name="gun", color=pcolor, texture='/textures/w_portalgun.png')
portal_gun_showcase = Entity(model=('portal_gun.fbx'), position=(25,2,-5), scale=.05, origin_z=-.5, rotation_z=0, on_cooldown=False, name="pgun_showcase", collider='box', texture=('/textures/w_portalgun.png'))

def genstairs():
    stairs(128,0.3,7,30)

thread(name="stair_gen", target=genstairs).start()

def update():
    global player, stored_camera_y, duty_cycle
    duty_cycle += 1

    if (block_outgoing_updates):
        arm.color=color.rgb(25,25,25,25)
    else:
        arm.color=pcolor

    if held_keys['escape']:
        os.abort()

    if held_keys['x']:
        player.y += 10

    if (held_keys['left shift'] and not held_keys['control']):
        player.speed = player.sprint_speed
    elif (player.speed == player.sprint_speed):player.speed=8

    if player.get_position()[1] < -20:
        prot = player.rotation
        destroy(player)
        player = FirstPersonController(model=player_model, z=-10, color=pcolor, speed=8, rotation=prot, origin_y=0.12, gravity=grav, jump_height = 4, height=3, collider='mesh', name=player_model)
        player.visible_self = False
        print("info: player reset")

mouse.visible = False
mouse.locked = True
app.run()

Solution

  • You can try Entity.flip_faces() function in ursina after adding this you code will look like this:

    from classes.constants import *
    fsmode = getinput("Fullscreen? [Y/N] > ")
    
    if (fsmode == "Y"):fsmode = True
    else:fsmode = False
    
    import time as systime, socket, socketserver, random
    from ursina import *
    import ursina.audio as audio
    from ursina.prefabs.first_person_controller import FirstPersonController
    from ursina.prefabs.health_bar import HealthBar
    from ursina.shaders import *
    from threading import Thread as thread
    
    from classes.class_override import *
    from classes.custom_classes import *
    
    grav=1
    player_model = "/models/player"
    pcolor = color.rgb(185, 185, 135)
    remoteplayer_color = color.rgb(145, 185, 145)
    remoteplayer_disconnected = color.rgb(25,25,25,25)
    stored_camera_y = 0
    duty_cycle=0
    remote_player_connected = False
    r_player_justconnected = False
    paused = False
    block_outgoing_updates = False
    
    app = Ursina(development_mode=False, show_ursina_splash_screen=True,fullscreen=fsmode,title="Reality Simulator (now with Portals!)")
    
    random.seed(0)
    Entity.default_shader = lit_with_shadows_shader
    
    ground = Entity(model='plane', collider='box', scale=128, texture='grass', texture_scale=(4,4), name="ground")
    ground2 = Entity(model='plane', collider='box', scale=128, texture='grass', texture_scale=(4,4), name="ground", position=(128,0,128))
    ground_brick = Entity(model='plane', collider='box', scale=128, texture='grass', texture_scale=(4,4), name="ground", position=(0,0,128))
    ground_brick2 = Entity(model='plane', collider='box', scale=128, texture='grass', texture_scale=(4,4), name="ground", position=(128,0,0))
    spawning_platform = Entity(model='cube', collider='box', scale=(3,0.5,3), texture='brick', position=(0,0,-10))
    
    editor_camera = EditorCamera(enabled=False, ignore_paused=True, move_speed=30)
    
    player = FirstPersonController(model=player_model, z=-10, y=0.5, color=pcolor, origin_y=0.12, gravity=grav, speed=8, jump_height = 4, height=3, collider='mesh', name="player", cursor=Entity(parent=camera.ui, model='quad', color=color.pink, scale=.001, rotation_z=45))
    # player_healthbar = HealthBar(max_value=player.max_hp, animation_duration=0.1, value=player.max_hp, parent=camera.ui)
    p2 = Entity(model=player_model, color=remoteplayer_disconnected, scale=1, name='remote_player', x=-5,y=0,z=-5, rotation_y=180)
    # sim_symbol = Entity(model='diamond', collider='mesh', color=color.green, name='sim_symbol', parent=player, position=(0,6,0), scale=(.5,1,.5), visible=False)
    player.visible_self = False
    # player = FirstPersonController(model=player_model, z=-10, color=color.orange, origin_y=-.5, speed=8)
    # player.collider = MeshCollider(player, Vec3(0,1,0), Vec3(1,2,1))
    
    arm = Entity(model='portal_gun_2', parent=camera, position=(.5,-.25,0.45), scale=.004, origin_z=-.5, rotation_z=0, on_cooldown=False, name="gun", color=pcolor, texture='/textures/w_portalgun.png')
    portal_gun_showcase = Entity(model=('portal_gun.fbx'), position=(25,2,-5), scale=.05, origin_z=-.5, rotation_z=0, on_cooldown=False, name="pgun_showcase", collider='box', texture=('/textures/w_portalgun.png'))
    
    arm.flip_faces()
    portal_gun_showcase.flip_faces()
    
    def genstairs():
        stairs(128,0.3,7,30)
    
    thread(name="stair_gen", target=genstairs).start()
    
    def update():
        global player, stored_camera_y, duty_cycle
        duty_cycle += 1
    
        if (block_outgoing_updates):
            arm.color=color.rgb(25,25,25,25)
        else:
            arm.color=pcolor
    
        if held_keys['escape']:
            os.abort()
    
        if held_keys['x']:
            player.y += 10
    
        if (held_keys['left shift'] and not held_keys['control']):
            player.speed = player.sprint_speed
        elif (player.speed == player.sprint_speed):player.speed=8
    
        if player.get_position()[1] < -20:
            prot = player.rotation
            destroy(player)
            player = FirstPersonController(model=player_model, z=-10, color=pcolor, speed=8, rotation=prot, origin_y=0.12, gravity=grav, jump_height = 4, height=3, collider='mesh', name=player_model)
            player.visible_self = False
            print("info: player reset")
    
    mouse.visible = False
    mouse.locked = True
    app.run()