Actor-Pointer-UPROPERTY

Hi,

I have a question:

How do other programmers achieve the most simple thing a human can imagine?

(Now that I have chosen this introduction, the chance of getting your attention will rise about approximately 1% :slight_smile: )

I want to:

  • Edit/assign an actor-property in the editor (more detailed: in the blueprint defaults panel)
  • or in a component (more detailed: in any editor panel. blueprint defaults or in the scene).

Code:

Case 1:

class UMyActorComponent : public UActorComponent
{

UPROPERTY(EditAnyWhere, BlueprintReadWrite)
AActor* MyActor;

}

Case 2:

class AMyActor : public AActor
{

UPROPERTY(EditAnyWhere, BlueprintReadWrite)
AActor* MyActor

}

After this, there is a dropdown-box for UMyActorComponent::MyActor and AMyActor::MyActor in the editor, where I can select a world-actor.

However, I can not select any actor as the choice is being canceled immediately.

This happens in the **component **and if I try to change the property in a blueprint.

Anyone knows, what I am doing wrong, and what I am supposed to do to get a reference of a level-actor in a blueprint or a component ?

This should be really very easy :/!

Thanks

I think that if you want a reference to actor in the level you need to place your object in the level first and the reference the other actor from the Details tab.

Yep, it doesn’t make sense to try to reference a specific instance of an actor from a blueprint. A blueprint is just that, a specification for something. It is not connected with any particular level and so you can’t reference anything within a level from the graph.

Hello Ogniok,

yes, of course, that is what I want to do. Reference an actor which is already in the level.

The problem is, that is not clear when I am allowed to edit a reference, and when not.

What are the rules for this behavior ?

What I have found out so far:

  • if the property is part of an actor in the level, I can edit the property with **some **actors in the level
  • if the property is part of an actor in a blueprint, I can never edit it
  • if the property is part of a component. I can never edit it

Why can I not “just” enter a reference for all situations ?

There must be a reason :slight_smile:

Right now I can set the actor-reference with an own unique-name implementation. But why not using native methods, if they are meant for it ? For example, if I am changing an actor-name, all properties referencing it would also be changed which would be the far better way.

Hello kamrann,

That makes perfectly sense as a base-rule.

That does not explain, why I can never edit actor-references in components, or are allowed to set only some level-actors, though.

(And a small detail: it would be nice, if I would not even be allowed to open the dropdown-box and select anything, if choices are being discarded after the selection anyway …which is confusing)

Hm, on second thought: If I want to reference a single-level-actor in multiple blueprints from a design perspective:
Would it not be nice, if I could just use an Actor-Pointer-UPROPERTY for it “nevertheless” ? I think, that this is not a constructed scenario.

Otherwise I am left with my unique-actor-label implementation which I feel is a little bit overhead for something an engine could offer.

Nothing dramatic but it just “does not feel right”.

I have not noticed this problem. So long as you are editing the details panel of an actor/component which is placed in your level, I believe you should be able to reference other placed actors. If you can’t, I think that would be a bug.

I agree completely, this should be changed.

I don’t entirely follow you. Generally speaking, you should avoid writing blueprints which have a hard dependency on the existence of a particular instance of an actor. If you keep needing to do this, I’d say there is something wrong with your approach.

I guess the exception would be if you have a particular actor of which there will always be one instance in every level of your game - for example, an actor which acts as a manager for an in-game system you have. In that case I’d suggest adding a (public) variable somewhere which is globally accessible, in a custom Game Mode perhaps. You initialize this within InitGame/BeginPlay, then in your other blueprints you can call GetGameMode, cast it to your custom mode, and access the actor through the variable.

Well, I tried it out again on a different system and had indeed no problems selecting any actor-instance in the detail-panel. That. Is. Weird. Will try to reproduce this.

[/QUOTE]

The use-case is something like this:

I have multiple character-instances in the scene, which have a relationship to other scene-actors, for example a unique communication actor. In most cases, a character-instance has a relationship to one default-communication-actor. There can be other communication-actors, but this is a special-case. So, if I drop multiple character-instances into the scene, I would have to set the relationship to this communication actor each time in the detail panel. So I see a blueprint-actorinstance-property as a workflow-improvement. (The assignment of the communication-actor-property would be also not necessary, but optional.)

I am not sure what the best way would be to have default-relationsships.

You could have your characters derive from a base class or blueprint, which in its BeginPlay event found the actor which should be used as the default (perhaps by searching for actors of a specified class) and assigned it to the property. Perhaps you should also consider spawning your characters through code/blueprint rather than placing them in your level. This approach is generally more scalable when it comes to wanting to create new levels. If you do it this way, you can set up the default references using some heuristic as you spawn them.

Yes, that would be a clean way I guess. I also thought about having two properties - one is the default-blueprint - and the other the instance.

The instance-property could be assigned in the construction-script by finding instances of the blueprint.

But I must admit, that I do not really see the point in disallowing editing instances in blueprints, since I would “left that to the implementator”.
This is mainly because I think the above workflow is more complicated than it could be… because “it is only one property…” ? :

Really nothing critical…

I’m trying to do a similar thing - I want to set an Actor pointer to another Actor within the same blueprint, and the editor won’t do it. IMHO this is a significant limitation on building reusable blueprints.

If i understood correctly we have the same issue.

I am coding a boardgame blueprint in c++. the board will be filled with 5 different type of tiles. my tiles are other blueprints i want to duplicate.
To pass this to my friend and let him chose which tiles i just created :

UPROPERTY(EditAnyWhere, BlueprintReadWrite, Category = “Maze”)
AActor* tileType1;
…
UPROPERTY(EditAnyWhere, BlueprintReadWrite, Category = “Maze”)
AActor* tileType5;

But within the board blueprint i can’t fill in the actors values. I tried to make them child actor components but doesn’t work neither.

Not quite the same thing. OP is tring to reference instances of spawned actors. But you are trying to reference “types of something”.
If you have 5 different types of tiles that you want to use as a model to build a board, you don’t need to spawn 5 tile actors. What you need are 5 tile classes to chose from when spawning a new one.

Therefore, you should create 5 childs of a tile parent class, and then reference those five classes in your UPROPERTIES.

So, you need a Blueprint called “ParentTile_BP”, plus 5 blueprints that are parented to this BP (i.e TileGrass_BP, TileWater_BP, etc…). Each of these 5 child blueprints would have its attributes customized to be the type of tile that you want.

Then, you need to reference those classes in UPROPERTIES by using the type TSubclassOf<AActor>, instead of AActor*. (if your ParentTile is in C++, even better, you can TSubclassOf<AParentTile> instead.)

i.e :
UPROPERTY(blablabla)
TSubclassOf<AActor> TileType1;

(or probably even better, using an enum: )
UPROPERTY(blablabla)
TMap<ETileType, TSubclassOf<AParentTile>> TileTypes;

Then, every time you want a tile, spawn a new actor of the class of the tile that you want.

Edited: Last UPROPERTY is of course a TMap, not a TArray

1 Like