Announcement

Collapse
No announcement yet.

C++ and Blueprint Interaction Problems, Pointers?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    C++ and Blueprint Interaction Problems, Pointers?

    Hey guys.
    I fought and fought but now I think I'm stuck. Hope you can give me a hint.
    The basic structure that I'm working on:

    A - There's a C++ 'MyController' class. It also includes an Array of custom MyStructs.
    B - Then there's a C++ MyInterface which I use to provide functionality to interact with the MyController class.
    C - I create a MyBlueprint based on MyActor which includes MyInterface.
    D - The MyInterface functions should be accessible via blueprint. So I'm using BlueprintNativeEvent and BlueprintCallable UFunctions.

    Now it gets difficult: Certain events need to access data from a certain MyStruct.
    But I cannot find out how blueprint handles pointers at all...
    I want to use a pointer to MyStruct to make sure it's always the most current version.

    First it seemed easy to do that. But everything I try gives me compiler errors.


    I tried it using function arguments based on what I found in Actor.h:

    Code:
    	/** Event when an actor no longer overlaps another actor, and they have separated. */
    	UFUNCTION(BlueprintImplementableEvent, meta=(FriendlyName = "ActorEndOverlap"), Category="Collision")
    	virtual void ReceiveActorEndOverlap(class AActor* OtherActor);
    
    // I thought I'd just do the same thing.
    
    	/** Event when an actor no longer overlaps another actor, and they have separated. */
    	UFUNCTION(BlueprintImplementableEvent, meta = (FriendlyName = "On My Event"), Category = "MyStuff")
    	void OnMyEvent(struct MyStruct* Parameter1);
    
    // Compiler Error: Inappropriate '*' on variable of type 'MyStruct', cannot have an exposed pointer to this type (move it inside the CPP block).
    What can I do to make it work? Or, after all, why doesn't it work? ...
    I'm out of ideas. Thanks for helping.

    EDIT - addition:

    How can I use BlueprintImplementableEvent and BlueprintCallable in one interface?
    Seems like a logic thing to do. But I keep getting this error:
    Code:
    Blueprint implementable interfaces cannot contain BlueprintCallable functions that are not BlueprintImplementableEvents.  
    Use CannotImplementInterfaceInBlueprint on the interface if you wish to keep this function.
    Alright. Then again I cannot use CannotImplementInterfaceInBlueprint as I want to use BlueprintImplementableEvent...
    Is there another solution or do I have to split this up into two interfaces?! (That would be pretty ugly...)
    Last edited by jbjhjm; 04-08-2014, 01:46 AM.

    #2
    No anwers? ...
    I found no true solution but gained some new knowledge and a workaround.
    Pointers to classes work, pointers to structs won't.
    So by using a class instead of struct, plus avoiding any BlueprintCallables, I was able to fix the problems.
    Still if anyone knows more about this, please tell me.

    Comment


      #3
      The Unreal property system that Blueprints are built on top only support passing pointers to non-UObjects, you can only pass them 'by value'. Is MyStruct a UCLASS (ie derived from UObject) or is it a USTRUCT? Inside MyController do you have TArray<MyStruct> or TArray<MyStruct*>? If the former, it's a bit dangerous to pass by reference anyway because any modification to the array size will probably result in the pointer being invalidated! Could you pass your structs around by value?
      Lead Programmer - UE4 Animation/Physics/Audio Team - Epic Games
      Twitter: @EpicJamesG

      Comment


        #4
        I'm glad you found a workaround! Interfaces and Blueprints can get a little squirrely, so there are a few points I want to bring up regarding your original post.

        First, if your struct is a USTRUCT you should be able to pass it by reference rather than using a pointer. You'll see this all over the place with FHitResult (see Actor.h). So I expect this would work for you:

        Code:
        	/** Event when an actor no longer overlaps another actor, and they have separated. */
        	UFUNCTION(BlueprintImplementableEvent, meta = (FriendlyName = "On My Event"), Category = "MyStuff")
        	void OnMyEvent(struct MyStruct& Parameter1);
        I tried a similar example here locally without issue. As a side note, the "move it inside the CPP block" advice in the error message is spurious legacy text. I've added a task to our database to fix that up.

        Second, in an interface function, you can use BlueprintCallable if it's also a BlueprintImplementableEvent or BlueprintNativeEvent. This is consistent with the interface concept, where you want your implementing class to be able to implement the interface's functions as it sees fit.

        Also, the CannotImplementInterfaceInBlueprint flag only restricts the ability for a Blueprint to implement your interface. Native classes would still be able to implement it with that flag, and any BPs derived from those classes should work fine as well.

        I hope that clears things up a little!
        Senior Engine Programmer, UE4, Epic Games
        Twitter:
        @Byooler

        Comment


          #5
          Thanks Jeff! Valueable information, will play around with that!

          Originally posted by JamesG View Post
          The Unreal property system that Blueprints are built on top only support passing pointers to non-UObjects, you can only pass them 'by value'. Is MyStruct a UCLASS (ie derived from UObject) or is it a USTRUCT? Inside MyController do you have TArray<MyStruct> or TArray<MyStruct*>? If the former, it's a bit dangerous to pass by reference anyway because any modification to the array size will probably result in the pointer being invalidated! Could you pass your structs around by value?
          MyStruct is a UStruct. The Array is a TArray<MyStruct>, in my case it's like the master storage for MyStructs.
          In this particular case I can be sure the array won't be changed after I begin to get pointers.
          But you're right, in different cases I should be careful with that

          I could pass them by value.
          But they might be updated in every frame and I'd need to pass them to several actors which base their actions on information they gather from the MyStructs.
          I think it would be rather inefficient and wasteful to pass them by value...?

          Comment

          Working...
          X