x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Instancing interface to TScriptInterface property

I have two properties:

 UPROPERTY()
     TScriptInterface<ICoordinateSystem> CoordinateSystem;

 UPROPERTY(EditAnywhere)
     TSubclassOf<UCoordinateSystem> CoordinateSystemType;

How can I instantiate CoordinateSystemType to CoordinateSystem? I have tried different ways like

 CoordinateSystem = NewObject<ICoordinateSystem>((UObject *) GetTransientPackage(), *CoordinateSystemType);

 CoordinateSystem = NewObject<UCoordinateSystem>((UObject *) GetTransientPackage(), *CoordinateSystemType);

 CoordinateSystem = Cast<ICoordinateSystem>(NewObject<UCoordinateSystem>((UObject *) GetTransientPackage(), *CoordinateSystemType));

but none of them compiles saying something like it can't convert UObject* to ICoordinateSystem* or ICoordinateSystem* to UObject* in either NewObject or TScriptInterface = operator.

Product Version: UE 4.11
Tags:
more ▼

asked May 30 '16 at 08:26 AM in C++ Programming

avatar image

GPSProlapse
11 1 4 6

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

2 answers: sort voted first

Not sure if you are still looking for an answer to this, but since Ive just struggled through it might as well have an answer here for you or anyone else

I assume you you have some existing pointer to an object type that implements ICoordinateSystem

Try this:

 MyTypeThatImplements* myPtr = blah;

 if (myPtr->GetClass()->ImplementsInterface(UCoordinateSystem::StaticClass()))
 {
     CoordinateSystem.SetInterface(Cast<ICoordinatSystem>(myPtr));
     CoordinateSystem.SetObject(myPtr);
 }

This will correctly instantiate your TScriptInterface property

You can then call ICoordinateSystem interface methods as

 if (CoordinateSystem != nullptr)
 {
     CoordinateSystem->Execute_MyInterfaceMethod(myPtr);
 }

HTH

more ▼

answered Jun 18 '16 at 10:55 PM

avatar image

SolarVelocity
596 31 77 51

avatar image GPSProlapse Jun 19 '16 at 02:40 PM

Actually no, I want to create an instance of type in CoordinateSystemType and store it to CoordinateSystem.

avatar image SolarVelocity Jun 19 '16 at 04:06 PM

First up, UCoordinateSystem is a wrapper class for the ICoordinateSystem ... I do not think you should be using it as a reference type (if you followed the interface implementation for UE4 approach)

So you have a class or set of classes that implements ICoordinateSystem?

All of those classes extend UObject.

Your CoordinateSystemType class should restrict to the lowest base class that will include the set of all coordinate system types (e.g.)

 TSubclassOf<UObject> CoordinateSystemType;

You can then create an instance of your coordinate system type

 CoordinateSystemType = NewObject<UObject>(this, MyTypeThatImplements::StaticClass());

And then assign it to the CoordinateSystem interface pointer as detailed above.

You cant just create an instance of an interface you have to create an instance of a class that implements that interface then you can cast that object to your interface type.

avatar image GPSProlapse Jun 19 '16 at 06:31 PM

You cant just create an instance of an interface you have to create an instance of a class that implements that interface then you can cast that object to your interface type.

That is obvious :/ Your solution is same as simply making type property type UClass. With such approach you get none of possible benefits like limitations for editor UI. So you will be able to set its value to some class which doesn't implement interface at all. Also TSubclassOf is type to store classes, not objects. So you can't store UObject objects there, but you can store any type extending UObject so it's same as simple UClass variable. Anyway I am not trying to instantiate interface, I am trying to instantiate a type, passed from editor, limited to types implementing interface.

avatar image SolarVelocity Jun 19 '16 at 08:12 PM

The problem you have is that I dont think there is an easy way to get a list of all types that implement an interface directly or inherit the interface from a base class. I do not think you can use the UCoordinateSystem wrapper type in this manner to filter your type list, but im no expert, and its not really clear what youre trying to do from your question.

The TSubclassOf member variable you have must use a type that is lowest common denominator of classes that implement ICoordinateSystem, I just gave UObject as an example, if there is no common base class then you will be stuck with UObject.

If you are able to obtain the type that is appropriate then you need to create an instance of it using NewObject and then do as I have indicated to populate the TScriptInterface.

You cant assign an object instance cast to your interface type straight to the TScriptInterface as it has an Interface component and an object component. You have to set both otherwise you get the UObject* error you mention.

avatar image GwigreBox Aug 26 '16 at 01:01 PM

You can have only the class that implement your interface by adding something like this:

 UPROPERTY(EditDefaultsOnly, meta = (MustImplement = "CoordinateSystem"))
 TArray<UClass*> CoordinateSystemType;

avatar image GPSProlapse Aug 26 '16 at 06:36 PM

Satan bless you, good man, first sane comment! Anyway, looks like an answer. ^^

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
 IAimable* aimable = ... 
 TScriptInterface<IAimable> ayyyy;
 ayyyy.SetInterface(aimable);
 ayyyy.SetObject(reinterpret_cast<UObject*>(aimable)); //UInterface instances are always UObjects so this is safe
 dude->startAim(ayyyy); //you then free to use that TScriptInterface object as you please

more ▼

answered Mar 25 '18 at 08:19 PM

avatar image

Arty-McLabin
925 20 44 64

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question