Both solutions are fine.
Most of the UI components have other UI components inside - slider is made of scrollbar and a border image, LineEdit is using text inside as element.
You can inherit text as well and add more functionality to it, expose that as attributes.
Do you expect to have a high level of script interop? I make data-driven games so in most cases I can avoid the script part, and lose the benefits of hotloading, not that I usually notice.
My opinion only: generally I would consider/recommend deriving from LogicComponent.
In one special case I derive from Urho3D::Object, but its my gamestate manager top level object, near the application object, and not like the things it controls.
What does it mean to expose something as an attribute? I was reading docs, and they’re explaining how to use URHO3D_ATTRIBUTE for the serialization. What does it mean to register an attribute? For now, I know how to register a factory and a subsystem and I understand why we need to do it. However, I’m puzzled when it comes to attributes.
You can add your own “properties” of an object (a component or UI element) using attributes. When you save your scene or UI layout, attributes of your object are saved too. You can have animated attributes using AttributeAnimation. If you make a multiplayer game for example, attributes are serialized over the network and can be synchronized to every player. You can edit attributes of an object in the Editor:
Notice the “Attribute inspector” on the right - these are the attributes of a Text UI element. Using URHO3D_ATTRIBUTE macros you register an attribute to call methods of your object (or access a variable directly). For example, when you change “Text” attribute, it calls Text::SetTextAttr() internally, which changes the actual text of the element then does internal things to display the updated string.
@Pencheff, thank you for this elaborate answer. Besides the use in the editor and for (de)serialization, is there any other need to register attributes? For example, can I animate my custom Object based class attributes without using URHO3D_ATTRIBUTE?
I’m not really trying to avoid using it I just want to see what it is used for. I want to understand better how Urho3D works. So, my next question would be, when and why one should use RegisterAttribute method?
Thank you, everyone. I’ve decided to publically inherit from Text and Window classes. I’m doing a mini-roguelike framework, so my game does not use scene system at all. Sometimes in the future, I’ll probably rather inherit from Sprite than from Text, but for now, I’m ok with this solution.
If anyone is interested, I’ve decided to implement my own “viewport”. Basically, my world map is a UI window inside another UI window. The latter behaves as a viewport for the containing window. So far so good
In my experience, it is rarely necessary to inherit from the UI leaf classes to accomplish something in Urho3D.
I’m not sure how ‘doing a mini-roguelike framework’ would preclude using a scene manager and require inheriting from Text and Window. This seems like an ideal candidate for a scene manager, with the Urho2D system sitting on top if it’s a 2D roguelike.
As for your world map window, this is a good candidate for a scene that is rendered to texture then displayed as a sprite in a UI element. For example, in this prototype world-map screen shot from my own game:
The world map is its own separate scene that renders to a texture. The texture is then drawn as a Sprite inside a Window. No need to inherit from anything to implement it, it works with Urho3D right out of the box. This can of course be done with any scene: a 3D one as in my example, or a 2D one with sprites for a 2D world map, as in this prototype of mine:
(This had the cool benefit of being able to reuse the rendered texture for the in-world map table graphic.)
Typically, the only Objects I ever need to inherit from are: directly from Object (for subsystem-like systems) and from Component (or, more commonly, LogicComponent). For everything else, basic Urho3D objects are usually sufficient.
The problem with the Urho2D is that it does not allow me to use text letters as sprites. I know that a possible solution would be to use some kind of texture atlas with letters. However, I wanted to have letters out of the box. I really don’t need the physics system, collision checking, etc. That is why I opted for using only the UI elements.
Yeah, that’s why I’ve asked this question, cause it seems to me that I’ve read somewhere that one does not need to inherit from the Urho3D classes, only from Object and LogicComponent, as you say.
You can use the Text3D component to handle drawing entities as letters. Text3D puts a bit of text ‘into the world’ at a specified location by attaching it to a Node. You can see it in action in the 32_Urho2DConstraints sample, as well as in a few of the 3D ones where it is used to put a title above an object in the 3D world. In 2D, it can be used to simply draw text at the location of a scene node.
The reason I recommend using a scene, is you get all of the various scene management stuff (culling, batching, etc…), plus if/when you decide to mix non-letter sprites into it, ie for landscape graphics and such, then it’s easy.
Note, you will have to do some thinking about sizing (viewport, ortho camera, font size) and spacing, but that should be pretty easy to handle. Objects are Nodes, meaning they can have attached components for logic and functionality, etc… You can use Z coordinate of Node position to handle layer draw sorting.
While we’re at it, what’s the recommended way to do the inheritance in Lua scripting? Is this kind of inheritance ok, for example?
EDIT: I’ve just realized that Node is a userdata in Lua, so there’s no option to do an inheritance by means of tables. I was wondering how one goes about adding a special purpose functions to game entites. For example, if I have a hammer entity, how do I add some method to this entity? The only thing that comes to my mind is to have a wrapper table and a Urho3D hammer node as a member of this wrapper table and than to add methods to this table. Is this a viable solution? The bonus of this solution is that it allows inheritance via tables.