Good day! I just started studying Unreal Engine 4.12 for a week now. For your discretion - I have little knowledge in C++ programming. (Although I code using PHP so I understanding OOP to some extent) - and, I'm just getting a little familiar with visual scripting (blueprint).
What I want to do is change the players weapon by loading a new static mesh, that static mesh would be from a file path. There are currently no blueprint node that does that, many articles/forums are suggesting to build my own blueprint node.
I've done some research and I have found this: Dynamic Load Object C++ - and it is very promising - but, I have no knowledge of implementing it. I tried opening MyProject.h and pasted it there, I'm not sure what to do next - does it become a function? Or a blueprint node?
I 'am open to other suggestions (or directions) on how to achieve what I wanted. If there are other methods to achieve this, please share and educate me. Thank you very much!
Sincerely,
Chris
That static load is only helper. You can call C++ function only if you mark header of that function by UFUNCTION(...) macro. See this link.
So you can create your function and in it's implementation, you can call that helper. For example:
// Helpers.h
static FORCEINLINE UTexture2D* GetTexture2DByName(const FName& name) {
return LoadObjFromPath<UTexture2D>(name);
}
UFUNCTION(BlueprintCallable, Category = TCF2Helpers)
static UTexture2D* GetTexture2DForBlock(UBuildableBlockInfo* blockInfo);
// Helpers.cpp
UTexture2D* UHelpers::GetTexture2DForBlock(UBuildableBlockInfo* blockInfo)
{
if (!blockInfo)
return nullptr;
const FString baseFolder = TEXT("Texture2D'/Game/Textures/HUD/%s");
if (blockInfo->IsEmptyHand)
return GetTexture2DByName(*FString::Printf(*baseFolder, TEXT("EmptyHand.EmptyHand'")));
// another lines of implementation
}
But you need to ask yourself, if you really need to have it hardcoded. You can specify something like
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Widgets")
TSubclassOf<class UObjectWidget> wInGameMenu;
UPROPERTY(BlueprintReadOnly, Category = "Widgets")
UObjectWidget* InGameMenu;
where in override of function BeginPlay (this is due to creating widget on the fly) I have:
if (wInGameMenu)
{
InGameMenu = CreateWidget<UObjectWidget>(this, wInGameMenu);
}
UObjectWidget is successor of UUserWidget and my widgets (created in Editor) are reparented to have that widget as an inheretance base. I define which widget should be created on archetype of my object which holds it.
I'd implement it like that: (this may be changed if anyone tells me better way)
Create WeaponManager as ActorComponent
Create Weapon as SceneComponent (so you can attach it on skeleton socket)
Every Weapon will have it's own implementation based on same interface (maybe override of some functions defined in common ancestor?)
You can have multiple sub-childs (Energy weapon, shooting weapon etc) so you have correct inheritance and you avoid multiple implementation of same thing.
Every Weapon will define it's mesh and properties - again, if you hardcoded mesh path (it's OK since it is implementation), you can use code like that in the end of that list) or you can set that on archetype, if you'd like to code something in blueprint.
Then in WeaponManager you define all weapons (for example TArray<TSubclassOf<UWeapon>>
Every Weapon should define EWeaponType - enum af all weapons in game, so I can match defined weapons with it's type in TMap and then simply work with it on demand (show, hide, change weapon etc.) That type should be hardcoded to all implementations of weapons.
Load mesh in constructor:
//TerminalObject.h
UCLASS()
class TAUCETIF2_API ATerminalObject : public AStaticMeshActor
{
GENERATED_UCLASS_BODY()
};
// TerminalObject.cpp
ATerminalObject::ATerminalObject(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
static ConstructorHelpers::FObjectFinder<UStaticMesh> mesh(TEXT("StaticMesh'/Game/BuildingObjects/Meshes/terminal.terminal'"));
checkf(mesh.Succeeded(), TEXT("Failed to find mesh"));
auto mc = GetStaticMeshComponent();
checkf(mc, TEXT("Failed to find mesh component"));
mc->SetStaticMesh(mesh.Object);
}
Related
So, I have bound the CombatController to an object called "godObject". In the Start() method, I call init() functions on other classes. I did this so I can control the order in which objects are initialized since, for example, the character controller relies on the grid controller being initialized.
Quick diagram:
-------------------- calls
| CombatController | ----------> CameraController.init();
-------------------- |
| ---> GridController.init();
|
| ---> CharacterController.init();
So, now I have a slight problem. I have multiple properties that I need in every controller. At the moment, I have bound everything to the combat controller itself. That means that, in every controller, I have to get an instance of the CombatController via GameObject.Find("godObject).GetComponent<CombatController>(). To be honest, I don't think this is good design.
My idea now was to create a BaseCombatController that extends MonoBehavior, and then have all other classes like GridController, CharacterController etc. extend the BaseCombatController. It might look like this:
public class BaseCombatController : MonoBehaviour
{
public GameObject activePlayer;
public void setActivePlayer(GameObject player) {
this.activePlayer = player;
}
... more stuff to come ...
}
This way, I could access activePlayer everywhere without the need to create a new instance of the CombatController. However, I'm not sure if this doesn't have possible side effects.
So, lots of text for a simple question, is that safe to do?
I use inheritance in Unity all the time. The trick, like you have in the question, is to allow your base class to inherit from monobehavior. For Example:
public class Base Item : Monobehavior
{
public string ItemName;
public int Price;
public virtual void PickUp(){//pickup logic}
//Additional functions. Update etc. Make them virtual.
}
This class sets up what an item should do. Then in a derived class you can change and extend this behavior.
public class Coin : BaseItem
{
//properties set in the inspector
public override void PickUp(){//override pickup logic}
}
I have used this design pattern a lot over the past year, and am currently using it in a retail product. I would say go for it! Unity seems to favor components over inheritance, but you could easily use them in conjunction with each other.
Hope this helps!
As far as I can see this should be safe. If you look into Unity intern or even Microsoft scripts they all extend/inhert (from) each other.
Another thing you could try would be the use of interfaces, here is the Unity Documentation to them: https://unity3d.com/learn/tutorials/topics/scripting/interfaces if you want to check it out.
You are right that GameObject.Find is pure code smell.
You can do it via the inheritance tree (as discussed earlier) or even better via interfaces (as mentioned by Assasin Bot), or (I am surprised no one mentioned it earlier) via static fields (aka the Singleton pattern).
One thing to add from experience - having to have Inits() called in a specific order is a yellow flag for your design - I've been there myself and found myself drowned by init order management.
As a general advice: Unity gives you two usefull callbacks - Awake() and Start(). If you find yourself needing Init() you are probably not using those two as they were designed.
All the Awakes() are guaranteed (for acvie objects) to run before first Start(), so do all the internal object initialisation in Awake(), and binding to external objects on Start(). If you find yourself needing finer control - you should probably simplify the design a bit.
As a rule of thumb: all objects should have their internal state (getcomponents<>, list inits etc) in order by the end of Awake(), but they shold not make any calls depending on other objects being ready before Start(). Splitting it this way usually helps a lot
I'm righting a script that loads some sprites and want to use it on both UI and in the game.
But there are two types of renderers for each and without any common base class, although they both have Sprite in common!
I want to use both Image and SpriteRenderer, so i want to write sth like this:
class SpriteLoader<T> where T: SomeRendererBaseClass {
T renderer;
void Load(){
renderer.sprite = GetSprite();
}
}
but to use "renderer.sprite" i have to specify T, for which i found no common base class.
If i'm gonna show game characters in UI i should load sprites on Image component, but in the game, i have to do the same behaviour but on SpriteRenderer, and as programmers we don't like duplicate codes.
Just because they both have a sprite doesn't mean anything.
You're going to just have to deal with the fact that the two classes aren't related to each other in the way that you'd like. This is no different than having a Player class that has a name property and trying to find a common parent class with GameObject ("it has a name too!")
The two classes have nothing else in common and should not inherit from some common ancestor (beyond whatever ancestor they do share).
At least they should have a common interface. I've seen that Unity API doesn't use interface at there best like .Net Does
I have a lot of Game Objects I need to Instantiate and put on scene on possible positions.
I have a list of rules where GameObject can be put by player (e.g. small box only at big box, sphere only on small box etc.)
I know I can put every rule into an "if", but I think it's not the most efficienty way. How should I keep a list of rules where can user put GameObjects? How my scripts should check and show possible positions? I will be thankful for any ideas how to start, to make it elegant and efficient.
There are many ways to do this.
What i would prefer is to keep everything organized and configurable per object (looking at the object oriƫnted programming structure).
I suggest defining per object where it can be placed. Here an example.
public yourClass
{
public GameObject ObjectToPlace;
public List<GameObject> ObjectToPlaceOnList;
public bool CanObjectBePlaced(GameObject targetObjectToPlaceUpon)
{
if (ObjectToPlaceOnList.Contains(targetObjectToPlaceUpon))
{
return true;
}
return false;
}
}
Your script may look different ofcourse, based on your current scripts.
Good day! I am new to using Unreal Engine 4 and I have a few questions about how exactly blueprints work. From my understanding of it, every blueprint works like a class. By that I mean one blueprint is much like one class in an OOP programming language.
Please educate me as to - if my assumption is correct or wrong. If wrong, then maybe you could help me achieve what I want in a different method/perspective. I am willing to learn and accept suggestions.
If at some point my understanding is correct - that blueprints are actually individual classes - I would really appreciate it if you could (please) guide as to where to go and how to implement a design that I want to create. This is from a programmers perspective (PHP OOP Programming). Forgive the approach, I'm just using PHP to logically express how I want the class to work. Plus, it is the only OOP programming I know atm.
I want to create a class named: Items. class Item {}
This class is going to handle everything item related, thus we will have to give it a lot of properties/variable. (Below is just an example; Again I'm using PHP as an example.)
class Item {
var $id;
var $name;
var $description;
var $type;
var $subType;
var $mesh;
var $materials;
}
3.) I would like to initiate this class by having two variables as its construct arguments. (We will require itemID and itemType). This is because I will use these two variables to retrieve the item's data which is already available in a data table. I will use those data in the table to populate the class properties/variables. (I'm not sure if I said that right. I hope you understood my point anyway.)
class Item {
var $id;
var $name;
var $description;
var $type;
var $subType;
var $mesh;
var $materials;
function _construct($cons_itemID, $cons_itemType) {
/*-- Start getting the item Data here based on what item and type provided. Then, push that data into the class properties/variables. We will use individual methods/functions to fill other properties/variables later. --*/
}
}
4.) Basically with that design I could easily pass on an item ID to the class and then get the item's name, description, mesh, materials and etc using pointers.
Example:
$weapon = new Item('10001','Weapon');
$weaponMesh = $weapon->getMesh();
$armor = new Item('12345','Armor');
$armorName = $armor->getName();
I'm just having a lot of trouble working with blueprint and achieve this method or even something similar to it. I'm not trying to avoid C++, I would love to learn it but I just don't have the time freedom right now.
Few things I have tried to make it work:
Casting / Casting to class (But I couldn't figure out what the target object will be and how was I going to add input arguments into the class that way? There isn't any input there that I could use.)
Spawn Actor (This one is very promising, I need to dig in deeper into this)
Blueprint Macros? Blueprint Interfaces? (I'm just lost.)
For all those who will help or answer. Thank you!
~ Chris
So far as I know, yes, we can assume that each blueprint can be viewed as class. (Moreover, since UE 4.12 (in UE 4.11 that functionality is marked as experimental I think) you can check Compile blueprints under Project settings -> Packaging. That will create native class for each blueprint.)
You can create either Blueprint or C++ class based on Object (UObject in C++). Then you can specify all properties (or variables in UE editor terminology). In BP you have small advantage: you can mark some properties as Visible at spawn (they must be Public and Visible). So when you are creating new instance of that class, you can explicitly pass values to that properties.
And in BP Construct event, that properties are correctly filled, thus you can set another properties values based on given ID and Type.
In C++ class having different arguments than FObjectInitializer is not possible, thus you don't have that values in time when constructor is executed. But it is not so hard to achieve same functionality, you can find example here: https://answers.unrealengine.com/questions/156055/passing-arguments-to-constructors-in-ue4.html.
Something about list of what you had tried:
Spawn actor - derive from actor only if you intend to have that BP in scene. Actors are subjects to game updates and rendering, so having actor only as data container is very wrong.
BP Macro is same as BP Function except function will be called just like function (so executing necesary actions by function call conventions) and macro will replace it's implementation in place, where you are calling that macro. More exhausting explanation here.
If I would implement your code, I'd do it like I said and then I'll have that class as property in some component and that component would be attached to some actor, which would be placed in scene.
I am writing a simple application to learn some basic Dart programming but I can't work out the structure and inclusions - I get a Duplicate class Point
First of all, I have my main class I called MouseTrack. It initializes the list and will have a loop.
#import('dart:html');
#import('Eye.dart');
class MouseTrace {
List<Eye> eyes;
...
}
Secondly, I have a class called Eye, which is supposed to hold information of of an eye as a circle. It's quite simple:
#library('app:eye');
#import('dart:html'); // without this one, I get no error but I want to have it to use CanvasRenderingContext2D
#import('Point.dart');
class Eye {
Point position;
num radius;
Eye() :
position = new Point() {
}
void draw(CanvasRenderingContext2D context) {
// draws a circle
}
}
And finally Point:
#library('app:point');
class Point {
num x, y;
Point(this.x, this.y);
}
What I want to achieve is 3 separate classes - main, Eye and Point, so I can have instances of Eye in main (for simplicity & nice model) and instances of Point in Eye (for storing position). At least that's how I'm used to doing.
P.S I know I can skip types but I want it there and I guess it's a problem with inclusions rather than the language (and want to fix it so I know how to do it properly).
P.S.S. I have cut off some code so that you don't have to read everything but, if you want, I will post it all.
Problem lies in the app:eye library (in the Eye.dart file). You import dart:html and app:point libraries, but both of them define a Point class. This situation is invalid. You can solve it either by not importing dart:html at all, if you don't need it, or prefixing one of those imports:
#import('dart:html', prefix: 'html');
#import('Point.dart');
In this case, you will have to refer to names from dart:html by using a html. prefix. In your case, if you want to use the CanvasRenderingContext2D class, you will have to write html.CanvasRenderingContext2D instead.