I decided to change the schedule of this newsletter a bit. I will write those long newsletters less often, and instead write more often short bits like this one. They will contain all kinds tips, news, and other light stuff.
This time I thought to explain Blueprint inheritance and offer couple of tips on how to use them.
Inheritance
One of the most power features in object oriented programming is inheritance. What this means is that any class can be used as a parent for a child class, and child has all the features (variables, functions, interfaces etc) of parent class and then its own features on top of that. This is a common feature found in most of the modern programming languages like C++, C#, Python, Java etc. Since Blueprints are basically a simplified visual version of C++, also Blueprints have inheritance.
One may ask what's the point in inheritance, why not just make separate classes. There are very good reasons for inheritance. Class inheritance allows you to make general classes, and then make specialized versions of them through inheritance. A good example is a general Vehicle class that is used as parent for more specialized classes like Car, Boat, Aeroplane, Bicycle, etc. Vehicle class contains features that are common to all vehicles, and since e.g. Car class inherits Vehicle, it already has all those features automatically. Then you just have to define features specific to a car in the Car class.
All this also helps to create hierarchical structures of these classes. Because of the inheritance you know that every Car class instance is a Vehicle instance, too, because Vehicle class is its parent. Car class could be a parent of Truck, Station wagon and SUV classes, and they then not only a Car but Vehicle, too. This makes it easy to identify the purpose of classes and make different checks easier. Instead of checking individually every different special case, you can just check whether an instance is Vehicle or Car, for example.
Making a child class
Making parent and child classes is not that complicated, but you should think your class hierarchy first, and what features you implement on general classes or specialized ones. That is especially important in multiplayer game, where you have think carefully how the inherited features are processed if the actor is replicated. You create inheriting child class like any other actor - remember that every BP actor is automatically a child of Actor class. Just right click the Content Browser to bring up the context menu, and choose Create Basic Asset - Blueprint Class. You can choose one of the basic classes, or any class on the hierarchical list that contains in-built classes and all custom classes you have already created.
You can change the inheritance of you own classes later, if necessary, by reparenting them. Just choose Reparent Blueprint from File menu. But this is something that you should think carefully, because it can break your class, and any other classes and game mechanics that happen to use it. UE Editor does not automatically adapt your code to new changes, and you may find errors in several Blueprints.
Every Blueprint shows its immediate parent class in the right corner of the Blueprint. By default UE Editor does not show inherited variables and functions. You have to activate that in the editor, and I recommend to put it always on when starting a new project. That will save you from all kinds of confusing situations.
When you implement a child class, you should understand that all variables and functions from parent class exist in child class, and they work just like any other variable or function, basically. There are certain things that you have to do carefully. If you create an event or function with same name as in parent class, you override it. It means, that the event or function (with that name) in parent class is not called at all, and only the code in child class is executed. This is really easy to forget when you put Event Tick in your child class. If parent class has Event Tick in its graph, then that Event Tick (in parent class) is not executed.
When creating a function this is easier to remember, since function list has a button and list of overridable functions. In every case, if you want that parent event or function is also executed, you have to include a parent call in your event or function. You can add that node by right clicking your event node, and then choosing from context menu Add call to parent function. Then you can put that node in your graph.
But is is not necessary to call parent function. Sometimes you may want to totally override the function or event in parent class. It depends on what you want to achieve. On the other hand, if you do not override a parent function, then it will called.
There is one peculiar thing about inherited functions. Even if the function is listed as a function in parent class, and it happens to return no parameters, it will be inherited as an event. So, if you override it in child class, it will appear as a custom event in the Event Graph. That's why I usually write every function in such way, that it returns at least a Success (boolean) parameter. Then it will always be a real function when inherited. Function that return nothing, is not really a function. It is usual in many programming languages that function always returns something (like 1 or true) to show that it has been executed successfully.
This should give the basic idea of how inheritance works and demystify it a little. However, inheritance can get complicated in large hierarchies especially when you are dealing with network code and replication.