Switch BP Actor at runtime using UMG

Hi, I’m a complete beginner with Blueprints.

I want to start my Archviz scene and be able to change my couch to another couch, or a chair to a different chair using UMG buttons and widgets.

I followed this tutorial - https://www.youtube.com/watch?v=rfcTM1jfbsM

Although this is for characters I thought it would be the same process.

I followed up until 03:25 into the tutorial when a GetPlayerCharacter Node was placed. When I tried that and compile I get error, “The Blueprint is not an ActorComponent”. Someone told me if you are casting to an object ( like couch) you need to use GetOwner Node, but that doesnt help either.

Any help would be great. Basically I want to start my Archviz scene, walk around and change meshes via UMG buttons.

I tried to use Variant Manager but got so lost.

You need to get a reference to the in-scene Actor whose mesh you want to change. The video is changing meshes on the player character, so it’s getting a reference to the character using the global function GetPlayerCharacter. That won’t work for you because your couch or whatever is not the player character.

Your in-scene objects are most likely StaticMeshActors. You can check their BP class by looking in the World Outliner - the rightmost column should have the class name. If it is a Static Mesh Actor, once you have a reference to it you should be able to directly get its Static Mesh Component and set the mesh on that.

Getting the reference to the specific in-scene StaticMeshActor you want to change is a bit trickier. One way could be to assign a unique Tag to each StaticMeshActor and use GetAllActorsWithTag to get the references (you’d have to cast the output to a StaticMeshActor).

This would be easier to explain with a BP screenshot, but I don’t have access to my editor at the moment…

Thanks so much for the feedback and assistance, it is very much appreciated. I’m going to follow what you said and try work this out. If you could get a chance to send a BP Screenshot when you get some time I would be very grateful, thanks.

Hi, please see attached screenshots of my progress, I’m still getting error messages. I changed the GetPlayerCharacter to Variable called SmallCouchRef and made this an Actor in Variable Details. No idea if this was the right thing to do.

You need to populate “Couch Reference” with a reference to an instance in the game world, i.e. replace your current “Small Couch Ref” with something that outputs the Actor instance reference for the couch you want to modify. Right now, it looks like SmallCouchRef is a variable on your widget BP that has no value assigned to it, hence the cast node is showing “Accessed None.”

Here’s a doc page with some basic examples of how to get references to Actors in the level: https://docs.unrealengine.com/en-US/Gameplay/HowTo/FindingActors/Blueprints/index.html. It implements the “finding” in a Character BP, but you could do it in a widget BP if you want (although it would probably be cleaner to do it in a Character or Controller).

I have a BP with the Static Mesh of a couch called BP_Furniture_01. Inside the Widget Blueprint I cast from BP_Furniture_01 from object to Small Couch Ref. In the details panel of Small Couch Ref I set the Variable type to BP_Furniture_01 which is wrong I guess (Please see 1st attached pic) What do I need to replace Small couch Ref with? you say something that outputs the Actor Instance reference for the couch?
I also have a screenshot of Couch Reference and its Details panel, I have also made variable type BP_Furniture_01, is this also incorrect? This is probably the easiest thing to do if you know Blueprints, but I have no clue, so Im struggling. When you say replace your current “Small couch Ref” with something that outputs the Actor Instance reference for the couch, I dont know what do to. I have zero Blueprint knowledge. I tried following the tutorial you linked but makes no sense to me. Any chance you could show me visually what you mean?
Thanks for your patience and ongoing help.

You’re setting the type of the variable to BP_Furniture_01, but the value is None - you need to get a reference to an actual in-game object to populate it. Incidentally, since the type of SmallCouchRef is BP_Furniture_01, you don’t need to cast to it - casting means converting types, so you’re attempting to convert SmallCouchRef to an object of the same type, which is unnecessary.

I put together a quick example. I created a new BP inheriting from Actor, called BP_MeshSwitcher. Added a StaticMeshComponent and set the mesh to a bathtub static mesh. Then I added a “SwitchMesh” event that takes a static mesh as an argument:

I dragged two of them into the level. Then in the widget BP event graph, I used Get All Actors of Class to call SwitchMesh on all of them:

Now when I click the button I hooked up, all of the bathtubs turn into classic leather sofas.

This is a simple setup, so 1) It changes ALL of the BP_MeshSwitcher instances in the level, and 2) It sets them all to a single mesh specified in the widget BP. I’ll make another post on how to address those.

Here’s a way to deal with 2) and select a specific “alternate” mesh for each instance:

  1. On the BP_MeshSwitcher, create a variable of type StaticMesh (object ref) called AlternateMesh. This is the variable that will be used to determine what the mesh will change to. Make it Instance Editable and Expose on Spawn. This means you can set its value on a per-instance basis after you drag it into the level, i.e. every instance of BP_MeshSwitcher in the level can have a different alternate mesh:

  1. I am going to implement this such that we can switch back to the original mesh if we want. To do that, we need to store the original mesh asset reference so the BP knows what to change back to. Create another variable of type StaticMesh called OriginalMesh (it doesn’t have to be Instance Editable or Exposed on Spawn). Then on BeginPlay for BP_MeshSwitcher, populate OriginalMesh with the value of the StaticMeshComponent’s StaticMesh variable (Note: I renamed the Static Mesh Component to “StaticMeshComponent” for clarity):

  1. Then set up the “SwitchMesh” event to toggle between the two meshes. I put comments in the graph to try to explain the logic.

  1. Now you can drag multiple instances of BP_MeshSwitcher into the level. To set the original mesh of an instance, select it in the level, then select its Static Mesh Component and choose a Static Mesh for it:

To set its Alternate Mesh, select the Actor node itself (where your AlternateMesh variable is located) and choose some other mesh:

Now when I press the button to call SwitchMesh on all of the BP_MeshSwitchers in the level, they each switch to their assigned AlternateMesh, and calling SwitchMesh again changes them back to the original:

5alt.jpg
image_166152.jpg

Note, this is just a simple way to do it - you could also set things up to cycle over an array of meshes, or have the user specify a mesh, but that would be more complicated.

Hi followed your screenshots, but Im lost at at the SwitchMesh, for the NewMesh Input I place in the SwitchMesh what must it be a Boolean? Cause I cannot connect the NewMesh from SwitchMesh to the New Mesh In Set Static Mesh? Please see Screenshot attached

It must be static Mesh instead of Boolean?

Here is one way to get access to a specific BP_MeshSwitcher instance:

  1. Select an instance in the level and scroll down to the “Actor” section. Then under Tags (you might need to expand the property list) hit the + sign and add a tag name:

  1. Use the “Get All Actors with Tag” node to get all actors with the “Mesh1” tag. The node outputs an array of Actor types, so we need to cast them to the BP_MeshSwitcher type in order to call SwitchMesh:

You can assign the same tag to multiple BP_MeshSwitchers so that a single button changes a subset of meshes. You can also add a different tag to other instances so that different buttons change the mesh(es) on different actors:

You probably get the idea. This isn’t the most elegant way to do this, but it’s hopefully simple enough for someone who doesn’t want to get too into Blueprints.

Yes, change the type to Static Mesh (object reference). Easiest way is probably to start typing “Static Mesh” when the Variable Type selection pop-up appears:

Thanks alot for the help, it is very much appreciated.