Tilesheets
This commit is contained in:
parent
160c83b199
commit
fc5efd6149
|
@ -1258,6 +1258,10 @@ class ArmoryExporter:
|
|||
if bobject.dupli_type == 'GROUP' and bobject.dupli_group != None:
|
||||
o['group_ref'] = bobject.dupli_group.name
|
||||
|
||||
if bobject.arm_tilesheet != '':
|
||||
o['tilesheet_ref'] = bobject.arm_tilesheet
|
||||
o['tilesheet_action_ref'] = bobject.arm_tilesheet_action
|
||||
|
||||
layer_found = False
|
||||
for l in self.active_layers:
|
||||
if bobject.layers[l] == True:
|
||||
|
@ -2372,6 +2376,8 @@ class ArmoryExporter:
|
|||
make_renderpath.build_node_trees(assets_path)
|
||||
|
||||
def export_particle_systems(self):
|
||||
if len(self.particleSystemArray) > 0:
|
||||
self.output['particle_datas'] = []
|
||||
for particleRef in self.particleSystemArray.items():
|
||||
o = {}
|
||||
psettings = particleRef[0]
|
||||
|
@ -2397,6 +2403,26 @@ class ArmoryExporter:
|
|||
o['size_random'] = 0.0
|
||||
self.output['particle_datas'].append(o)
|
||||
|
||||
def export_tilesheets(self):
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
if len(wrd.arm_tilesheetlist) > 0:
|
||||
self.output['tilesheet_datas'] = []
|
||||
for ts in wrd.arm_tilesheetlist:
|
||||
o = {}
|
||||
o['name'] = ts.name
|
||||
o['tilesx'] = ts.tilesx_prop
|
||||
o['tilesy'] = ts.tilesy_prop
|
||||
o['framerate'] = ts.framerate_prop
|
||||
o['actions'] = []
|
||||
for tsa in ts.arm_tilesheetactionlist:
|
||||
ao = {}
|
||||
ao['name'] = tsa.name
|
||||
ao['start'] = tsa.start_prop
|
||||
ao['end'] = tsa.end_prop
|
||||
ao['loop'] = tsa.loop_prop
|
||||
o['actions'].append(ao)
|
||||
self.output['tilesheet_datas'].append(o)
|
||||
|
||||
def export_worlds(self):
|
||||
worldRef = self.scene.world
|
||||
if worldRef != None:
|
||||
|
@ -2582,14 +2608,11 @@ class ArmoryExporter:
|
|||
log.warn('Object ' + bobject.name + ' - unable to bind materials to vertex data, please separate object by material (select object - edit mode - P - By Material) or enable Deinterleaved Buffers in Armory Player')
|
||||
break
|
||||
|
||||
self.output['particle_datas'] = []
|
||||
self.export_particle_systems()
|
||||
|
||||
self.export_particle_systems()
|
||||
self.output['world_datas'] = []
|
||||
self.export_worlds()
|
||||
|
||||
self.output['grease_pencil_datas'] = []
|
||||
self.export_grease_pencils()
|
||||
self.export_tilesheets()
|
||||
|
||||
if self.scene.world != None:
|
||||
self.output['world_ref'] = self.scene.world.name
|
||||
|
|
|
@ -144,7 +144,12 @@ def make_base(con_mesh, parse_opacity):
|
|||
|
||||
if con_mesh.is_elem('tex'):
|
||||
vert.add_out('vec2 texCoord')
|
||||
vert.write('texCoord = tex;')
|
||||
if mat_state.material.arm_tilesheet_mat:
|
||||
vert.add_uniform('vec2 tilesheetOffset', '_tilesheetOffset')
|
||||
vert.write('texCoord = tex + tilesheetOffset;')
|
||||
else:
|
||||
vert.write('texCoord = tex;')
|
||||
|
||||
if tese != None:
|
||||
# TODO: also includes texCoord1
|
||||
tese.write_pre = True
|
||||
|
|
|
@ -128,6 +128,8 @@ def init_properties():
|
|||
bpy.types.Object.arm_mobile = bpy.props.BoolProperty(name="Mobile", description="Object moves during gameplay", default=True)
|
||||
bpy.types.Object.arm_soft_body_margin = bpy.props.FloatProperty(name="Soft Body Margin", description="Collision margin", default=0.04)
|
||||
bpy.types.Object.arm_animation_enabled = bpy.props.BoolProperty(name="Animation", description="Enable skinning & timeline animation", default=True)
|
||||
bpy.types.Object.arm_tilesheet = bpy.props.StringProperty(name="Tilesheet", description="Set tilesheet animation", default='')
|
||||
bpy.types.Object.arm_tilesheet_action = bpy.props.StringProperty(name="Tilesheet Action", description="Set startup action", default='')
|
||||
# For speakers
|
||||
bpy.types.Speaker.arm_loop = bpy.props.BoolProperty(name="Loop", description="Loop this sound", default=False)
|
||||
bpy.types.Speaker.arm_stream = bpy.props.BoolProperty(name="Stream", description="Stream this sound", default=False)
|
||||
|
@ -288,6 +290,7 @@ def init_properties():
|
|||
('spherical', 'Spherical', 'Spherical'),
|
||||
('cylindrical', 'Cylindrical', 'Cylindrical')],
|
||||
name="Billboard", default='none', description="Track camera")
|
||||
bpy.types.Material.arm_tilesheet_mat = bpy.props.BoolProperty(name="Tilesheet", description="Generate tilesheet shaders", default=False)
|
||||
# For scene
|
||||
bpy.types.Scene.arm_export = bpy.props.BoolProperty(name="Export", description="Export scene data", default=True)
|
||||
bpy.types.Scene.arm_gp_export = bpy.props.BoolProperty(name="Export GP", description="Export grease pencil data", default=True)
|
||||
|
|
|
@ -153,7 +153,7 @@ class ArmRPListItem(bpy.types.PropertyGroup):
|
|||
arm_texture_filter = EnumProperty(
|
||||
items=[('Anisotropic', 'Anisotropic', 'Anisotropic'),
|
||||
('Linear', 'Linear', 'Linear'),
|
||||
('Point', 'Point', 'Point'),
|
||||
('Point', 'Closest', 'Point'),
|
||||
('Manual', 'Manual', 'Manual')],
|
||||
name="Texture Filtering", description="Set Manual to honor interpolation setting on Image Texture node", default='Anisotropic')
|
||||
arm_material_model = EnumProperty(
|
||||
|
|
281
blender/arm/props_tilesheet.py
Normal file
281
blender/arm/props_tilesheet.py
Normal file
|
@ -0,0 +1,281 @@
|
|||
import shutil
|
||||
import bpy
|
||||
import os
|
||||
import json
|
||||
from bpy.types import Menu, Panel, UIList
|
||||
from bpy.props import *
|
||||
|
||||
class ArmTilesheetActionListItem(bpy.types.PropertyGroup):
|
||||
name = bpy.props.StringProperty(
|
||||
name="Name",
|
||||
description="A name for this item",
|
||||
default="Untitled")
|
||||
|
||||
start_prop = bpy.props.IntProperty(
|
||||
name="Start",
|
||||
description="A name for this item",
|
||||
default=0)
|
||||
|
||||
end_prop = bpy.props.IntProperty(
|
||||
name="End",
|
||||
description="A name for this item",
|
||||
default=0)
|
||||
|
||||
loop_prop = bpy.props.BoolProperty(
|
||||
name="Loop",
|
||||
description="A name for this item",
|
||||
default=True)
|
||||
|
||||
class ArmTilesheetActionList(bpy.types.UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
||||
# We could write some code to decide which icon to use here...
|
||||
custom_icon = 'OBJECT_DATAMODE'
|
||||
|
||||
# Make sure your code supports all 3 layout types
|
||||
if self.layout_type in {'DEFAULT', 'COMPACT'}:
|
||||
layout.prop(item, "name", text="", emboss=False, icon=custom_icon)
|
||||
|
||||
elif self.layout_type in {'GRID'}:
|
||||
layout.alignment = 'CENTER'
|
||||
layout.label("", icon = custom_icon)
|
||||
|
||||
class ArmTilesheetActionListNewItem(bpy.types.Operator):
|
||||
# Add a new item to the list
|
||||
bl_idname = "arm_tilesheetactionlist.new_item"
|
||||
bl_label = "Add a new item"
|
||||
|
||||
def execute(self, context):
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
trait = wrd.arm_tilesheetlist[wrd.arm_tilesheetlist_index]
|
||||
trait.arm_tilesheetactionlist.add()
|
||||
trait.arm_tilesheetactionlist_index = len(trait.arm_tilesheetactionlist) - 1
|
||||
return{'FINISHED'}
|
||||
|
||||
class ArmTilesheetActionListDeleteItem(bpy.types.Operator):
|
||||
# Delete the selected item from the list
|
||||
bl_idname = "arm_tilesheetactionlist.delete_item"
|
||||
bl_label = "Deletes an item"
|
||||
|
||||
@classmethod
|
||||
def poll(self, context):
|
||||
""" Enable if there's something in the list """
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
trait = wrd.arm_tilesheetlist[wrd.arm_tilesheetlist_index]
|
||||
return len(trait.arm_tilesheetactionlist) > 0
|
||||
|
||||
def execute(self, context):
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
trait = wrd.arm_tilesheetlist[wrd.arm_tilesheetlist_index]
|
||||
list = trait.arm_tilesheetactionlist
|
||||
index = trait.arm_tilesheetactionlist_index
|
||||
|
||||
list.remove(index)
|
||||
|
||||
if index > 0:
|
||||
index = index - 1
|
||||
|
||||
trait.arm_tilesheetactionlist_index = index
|
||||
return{'FINISHED'}
|
||||
|
||||
class ArmTilesheetActionListMoveItem(bpy.types.Operator):
|
||||
# Move an item in the list
|
||||
bl_idname = "arm_tilesheetactionlist.move_item"
|
||||
bl_label = "Move an item in the list"
|
||||
direction = bpy.props.EnumProperty(
|
||||
items=(
|
||||
('UP', 'Up', ""),
|
||||
('DOWN', 'Down', ""),))
|
||||
|
||||
@classmethod
|
||||
def poll(self, context):
|
||||
""" Enable if there's something in the list. """
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
trait = wrd.arm_tilesheetlist[wrd.arm_tilesheetlist_index]
|
||||
return len(trait.arm_tilesheetactionlist) > 0
|
||||
|
||||
|
||||
def move_index(self):
|
||||
# Move index of an item render queue while clamping it
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
trait = wrd.arm_tilesheetlist[wrd.arm_tilesheetlist_index]
|
||||
index = trait.arm_tilesheetactionlist_index
|
||||
list_length = len(trait.arm_tilesheetactionlist) - 1
|
||||
new_index = 0
|
||||
|
||||
if self.direction == 'UP':
|
||||
new_index = index - 1
|
||||
elif self.direction == 'DOWN':
|
||||
new_index = index + 1
|
||||
|
||||
new_index = max(0, min(new_index, list_length))
|
||||
index = new_index
|
||||
|
||||
|
||||
def execute(self, context):
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
trait = wrd.arm_tilesheetlist[wrd.arm_tilesheetlist_index]
|
||||
list = trait.arm_tilesheetactionlist
|
||||
index = trait.arm_tilesheetactionlist_index
|
||||
|
||||
if self.direction == 'DOWN':
|
||||
neighbor = index + 1
|
||||
#queue.move(index,neighbor)
|
||||
self.move_index()
|
||||
|
||||
elif self.direction == 'UP':
|
||||
neighbor = index - 1
|
||||
#queue.move(neighbor, index)
|
||||
self.move_index()
|
||||
else:
|
||||
return{'CANCELLED'}
|
||||
return{'FINISHED'}
|
||||
|
||||
class ArmTilesheetListItem(bpy.types.PropertyGroup):
|
||||
name = bpy.props.StringProperty(
|
||||
name="Name",
|
||||
description="A name for this item",
|
||||
default="Untitled")
|
||||
|
||||
tilesx_prop = bpy.props.IntProperty(
|
||||
name="Tiles X",
|
||||
description="A name for this item",
|
||||
default=0)
|
||||
|
||||
tilesy_prop = bpy.props.IntProperty(
|
||||
name="Tiles Y",
|
||||
description="A name for this item",
|
||||
default=0)
|
||||
|
||||
framerate_prop = bpy.props.FloatProperty(
|
||||
name="Frame Rate",
|
||||
description="A name for this item",
|
||||
default=4.0)
|
||||
|
||||
arm_tilesheetactionlist = bpy.props.CollectionProperty(type=ArmTilesheetActionListItem)
|
||||
arm_tilesheetactionlist_index = bpy.props.IntProperty(name="Index for my_list", default=0)
|
||||
|
||||
class ArmTilesheetList(bpy.types.UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
||||
# We could write some code to decide which icon to use here...
|
||||
custom_icon = 'OBJECT_DATAMODE'
|
||||
|
||||
# Make sure your code supports all 3 layout types
|
||||
if self.layout_type in {'DEFAULT', 'COMPACT'}:
|
||||
layout.prop(item, "name", text="", emboss=False, icon=custom_icon)
|
||||
|
||||
elif self.layout_type in {'GRID'}:
|
||||
layout.alignment = 'CENTER'
|
||||
layout.label("", icon = custom_icon)
|
||||
|
||||
class ArmTilesheetListNewItem(bpy.types.Operator):
|
||||
# Add a new item to the list
|
||||
bl_idname = "arm_tilesheetlist.new_item"
|
||||
bl_label = "Add a new item"
|
||||
|
||||
def execute(self, context):
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
wrd.arm_tilesheetlist.add()
|
||||
wrd.arm_tilesheetlist_index = len(wrd.arm_tilesheetlist) - 1
|
||||
return{'FINISHED'}
|
||||
|
||||
class ArmTilesheetListDeleteItem(bpy.types.Operator):
|
||||
# Delete the selected item from the list
|
||||
bl_idname = "arm_tilesheetlist.delete_item"
|
||||
bl_label = "Deletes an item"
|
||||
|
||||
@classmethod
|
||||
def poll(self, context):
|
||||
""" Enable if there's something in the list """
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
return len(wrd.arm_tilesheetlist) > 0
|
||||
|
||||
def execute(self, context):
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
list = wrd.arm_tilesheetlist
|
||||
index = wrd.arm_tilesheetlist_index
|
||||
|
||||
list.remove(index)
|
||||
|
||||
if index > 0:
|
||||
index = index - 1
|
||||
|
||||
wrd.arm_tilesheetlist_index = index
|
||||
return{'FINISHED'}
|
||||
|
||||
class ArmTilesheetListMoveItem(bpy.types.Operator):
|
||||
# Move an item in the list
|
||||
bl_idname = "arm_tilesheetlist.move_item"
|
||||
bl_label = "Move an item in the list"
|
||||
direction = bpy.props.EnumProperty(
|
||||
items=(
|
||||
('UP', 'Up', ""),
|
||||
('DOWN', 'Down', ""),))
|
||||
|
||||
@classmethod
|
||||
def poll(self, context):
|
||||
""" Enable if there's something in the list. """
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
return len(wrd.arm_tilesheetlist) > 0
|
||||
|
||||
def move_index(self):
|
||||
# Move index of an item render queue while clamping it
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
index = wrd.arm_tilesheetlist_index
|
||||
list_length = len(wrd.arm_tilesheetlist) - 1
|
||||
new_index = 0
|
||||
|
||||
if self.direction == 'UP':
|
||||
new_index = index - 1
|
||||
elif self.direction == 'DOWN':
|
||||
new_index = index + 1
|
||||
|
||||
new_index = max(0, min(new_index, list_length))
|
||||
index = new_index
|
||||
|
||||
def execute(self, context):
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
list = wrd.arm_tilesheetlist
|
||||
index = wrd.arm_tilesheetlist_index
|
||||
|
||||
if self.direction == 'DOWN':
|
||||
neighbor = index + 1
|
||||
#queue.move(index,neighbor)
|
||||
self.move_index()
|
||||
|
||||
elif self.direction == 'UP':
|
||||
neighbor = index - 1
|
||||
#queue.move(neighbor, index)
|
||||
self.move_index()
|
||||
else:
|
||||
return{'CANCELLED'}
|
||||
return{'FINISHED'}
|
||||
|
||||
def register():
|
||||
|
||||
bpy.utils.register_class(ArmTilesheetActionListItem)
|
||||
bpy.utils.register_class(ArmTilesheetActionList)
|
||||
bpy.utils.register_class(ArmTilesheetActionListNewItem)
|
||||
bpy.utils.register_class(ArmTilesheetActionListDeleteItem)
|
||||
bpy.utils.register_class(ArmTilesheetActionListMoveItem)
|
||||
|
||||
bpy.utils.register_class(ArmTilesheetListItem)
|
||||
bpy.utils.register_class(ArmTilesheetList)
|
||||
bpy.utils.register_class(ArmTilesheetListNewItem)
|
||||
bpy.utils.register_class(ArmTilesheetListDeleteItem)
|
||||
bpy.utils.register_class(ArmTilesheetListMoveItem)
|
||||
|
||||
bpy.types.World.arm_tilesheetlist = bpy.props.CollectionProperty(type=ArmTilesheetListItem)
|
||||
bpy.types.World.arm_tilesheetlist_index = bpy.props.IntProperty(name="Index for my_list", default=0)
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(ArmTilesheetListItem)
|
||||
bpy.utils.unregister_class(ArmTilesheetList)
|
||||
bpy.utils.unregister_class(ArmTilesheetListNewItem)
|
||||
bpy.utils.unregister_class(ArmTilesheetListDeleteItem)
|
||||
bpy.utils.unregister_class(ArmTilesheetListMoveItem)
|
||||
|
||||
bpy.utils.unregister_class(ArmTilesheetActionListItem)
|
||||
bpy.utils.unregister_class(ArmTilesheetActionList)
|
||||
bpy.utils.unregister_class(ArmTilesheetActionListNewItem)
|
||||
bpy.utils.unregister_class(ArmTilesheetActionListDeleteItem)
|
||||
bpy.utils.unregister_class(ArmTilesheetActionListMoveItem)
|
|
@ -52,6 +52,16 @@ class ObjectPropsPanel(bpy.types.Panel):
|
|||
# row.prop(obj, 'arm_instanced')
|
||||
# row.prop(obj, 'arm_instanced')
|
||||
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
layout.prop_search(obj, "arm_tilesheet", wrd, "arm_tilesheetlist", "Tilesheet")
|
||||
if obj.arm_tilesheet != '':
|
||||
selected_ts = None
|
||||
for ts in wrd.arm_tilesheetlist:
|
||||
if ts.name == obj.arm_tilesheet:
|
||||
selected_ts = ts
|
||||
break
|
||||
layout.prop_search(obj, "arm_tilesheet_action", selected_ts, "arm_tilesheetactionlist", "Action")
|
||||
|
||||
class ModifiersPropsPanel(bpy.types.Panel):
|
||||
bl_label = "Armory Props"
|
||||
bl_space_type = "PROPERTIES"
|
||||
|
@ -243,6 +253,7 @@ class MaterialPropsPanel(bpy.types.Panel):
|
|||
|
||||
layout.prop(mat, 'arm_custom_material')
|
||||
layout.prop(mat, 'arm_billboard')
|
||||
layout.prop(mat, 'arm_tilesheet_mat')
|
||||
|
||||
layout.operator("arm.invalidate_material_cache")
|
||||
|
||||
|
@ -1094,6 +1105,50 @@ class ArmLodPanel(bpy.types.Panel):
|
|||
|
||||
layout.prop(mdata, "arm_lod_material")
|
||||
|
||||
class ArmTilesheetPanel(bpy.types.Panel):
|
||||
bl_label = "Armory Tilesheet"
|
||||
bl_space_type = "PROPERTIES"
|
||||
bl_region_type = "WINDOW"
|
||||
bl_context = "object"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
wrd = bpy.data.worlds['Arm']
|
||||
|
||||
rows = 2
|
||||
if len(wrd.arm_tilesheetlist) > 1:
|
||||
rows = 4
|
||||
row = layout.row()
|
||||
row.template_list("ArmTilesheetList", "The_List", wrd, "arm_tilesheetlist", wrd, "arm_tilesheetlist_index", rows=rows)
|
||||
col = row.column(align=True)
|
||||
col.operator("arm_tilesheetlist.new_item", icon='ZOOMIN', text="")
|
||||
col.operator("arm_tilesheetlist.delete_item", icon='ZOOMOUT', text="")
|
||||
|
||||
if wrd.arm_tilesheetlist_index >= 0 and len(wrd.arm_tilesheetlist) > 0:
|
||||
dat = wrd.arm_tilesheetlist[wrd.arm_tilesheetlist_index]
|
||||
row = layout.row()
|
||||
row.prop(dat, "tilesx_prop")
|
||||
row.prop(dat, "tilesy_prop")
|
||||
layout.prop(dat, "framerate_prop")
|
||||
|
||||
layout.label('Actions')
|
||||
rows = 2
|
||||
if len(dat.arm_tilesheetactionlist) > 1:
|
||||
rows = 4
|
||||
row = layout.row()
|
||||
row.template_list("ArmTilesheetList", "The_List", dat, "arm_tilesheetactionlist", dat, "arm_tilesheetactionlist_index", rows=rows)
|
||||
col = row.column(align=True)
|
||||
col.operator("arm_tilesheetactionlist.new_item", icon='ZOOMIN', text="")
|
||||
col.operator("arm_tilesheetactionlist.delete_item", icon='ZOOMOUT', text="")
|
||||
|
||||
if dat.arm_tilesheetactionlist_index >= 0 and len(dat.arm_tilesheetactionlist) > 0:
|
||||
adat = dat.arm_tilesheetactionlist[dat.arm_tilesheetactionlist_index]
|
||||
row = layout.row()
|
||||
row.prop(adat, "start_prop")
|
||||
row.prop(adat, "end_prop")
|
||||
layout.prop(adat, "loop_prop")
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(ObjectPropsPanel)
|
||||
bpy.utils.register_class(ModifiersPropsPanel)
|
||||
|
@ -1132,6 +1187,7 @@ def register():
|
|||
bpy.utils.register_class(ArmNavigationPanel)
|
||||
bpy.utils.register_class(ArmGenLodButton)
|
||||
bpy.utils.register_class(ArmLodPanel)
|
||||
bpy.utils.register_class(ArmTilesheetPanel)
|
||||
|
||||
bpy.types.VIEW3D_HT_header.append(draw_view3d_header)
|
||||
bpy.types.INFO_HT_header.prepend(draw_info_header)
|
||||
|
@ -1177,3 +1233,4 @@ def unregister():
|
|||
bpy.utils.unregister_class(ArmNavigationPanel)
|
||||
bpy.utils.unregister_class(ArmGenLodButton)
|
||||
bpy.utils.unregister_class(ArmLodPanel)
|
||||
bpy.utils.unregister_class(ArmTilesheetPanel)
|
||||
|
|
|
@ -5,6 +5,7 @@ import arm.props_traits_params
|
|||
import arm.props_traits_props
|
||||
import arm.props_traits
|
||||
import arm.props_lod
|
||||
import arm.props_tilesheet
|
||||
import arm.props_exporter
|
||||
import arm.props_renderpath
|
||||
import arm.props
|
||||
|
@ -24,6 +25,7 @@ def register():
|
|||
arm.props_traits_props.register()
|
||||
arm.props_traits.register()
|
||||
arm.props_lod.register()
|
||||
arm.props_tilesheet.register()
|
||||
arm.props_exporter.register()
|
||||
arm.props_renderpath.register()
|
||||
arm.props.register()
|
||||
|
@ -50,6 +52,7 @@ def unregister():
|
|||
arm.props_traits_props.unregister()
|
||||
arm.props_traits.unregister()
|
||||
arm.props_lod.unregister()
|
||||
arm.props_tilesheet.unregister()
|
||||
arm.props_exporter.unregister()
|
||||
arm.props_renderpath.unregister()
|
||||
arm.space_armory.unregister()
|
||||
|
|
Loading…
Reference in a new issue