UE4 How do I use InstancedStaticMeshes ?

超、凢脫俗 2022-08-19 05:47 81阅读 0赞











1








I created a maze generator and I’m currently trying to figure out how to use an InstancedStaticMeshs in c++. Currently it spawns blueprints extended from a StaticMeshActor and I can only get about 10201 static meshes blueprints before i hit some heavy performance decrease, this is just on a maze alone


So when trying to make a rougelike maze dungeon with rooms and floors there are about ten to twenty times the static meshes. That’s allot of static mesh blueprints. Anyone have example usage ?


alt text





Product Version: 
Not Selected


Tags:
blueprints
c++
instanced mesh




maze101.png (434.8 kB)



more ▼



asked Apr 03 ‘14 at 1:58 AM


SaxonRah gravatar image

SaxonRah 
221  8  10  22








Dieselhead gravatar image 
Dieselhead 
Apr 03 ‘14 at 9:43 PM






I’m only guessing here but I think a game like this would also benefit greatly from level streaming.








SaxonRah gravatar image 
SaxonRah 
Apr 03 ‘14 at 10:51 PM






How would you level stream from actors spawned at run time ?








Dieselhead gravatar image 
Dieselhead 
Apr 04 ‘14 at 2:04 AM






Well thats what you get when browsing this place the last hour of work :)


Sorry, carry on!












1 answer: sort voted first ▼












5





Instanced Static Mesh


You can make a new class, InstancedStaticMeshActor


and add a Instanced Static Mesh Component


Then you spawn that actor


and to add additional instances you use this function in the Instanced Static Mesh Component Class







    1. UFUNCTION(BlueprintCallable, Category=Components|InstancedStaticMesh)


    2. virtual void AddInstance(const FTransform& InstanceTransform);


    3.  


    4.  



That’s pretty much all you need to do!


Here’s my code from the beta, that I used for my own tests, here’s a pic of my tests


In my case I extended a regular SMA so I would see the actor when it spawned :)


Spawning







    1. //Spawninfo


    2. FActorSpawnParameters SpawnInfo;




    3. //SET NO COLLISION FAIL TO TRUE


    4. SpawnInfo.bNoCollisionFail = true;




    5. SpawnInfo.Owner = VictoryEngine->VSelectedActor;




    6. AVictoryVertex3D NewVertex =


    7. GetWorld()->SpawnActor<AVictoryVertex3D>(


    8. AVictoryVertex3D::StaticClass(),


    9. Pos,


    10. FRotator::ZeroRotator,


    11. SpawnInfo


    12. );


    13. if(!NewVertex) return NULL;


    14. if(!NewVertex->InstancedStaticMeshComponent) return NULL;


    15. //~~~~~~




    16. //Mesh


    17. NewVertex->InstancedStaticMeshComponent->SetStaticMesh(VictoryEngine->AssetSM_EngineCube);




    18. //Add Core Instance


    19. FTransform newT = NewVertex->GetTransform();


    20. newT.SetLocation(FVector(0,0,0));


    21. NewVertex->InstancedStaticMeshComponent->AddInstance(newT);




    22. //Scale


    23. NewVertex->SetActorRelativeScale3D(CurrentVerticiesScale);


    24.  


    25.  



.h







    1. // Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.




    2. //Power




    3. #pragma once




    4. #include VictoryVertex3D.generated.h






    5. /**


    6. An instance of a StaticMesh in a level


    7. Note that PostInitializeComponents() is not called for StaticMeshActors


    8. /


    9. UCLASS()


    10. class AVictoryVertex3D : public AStaticMeshActor


    11. {


    12. GENERATED_UCLASS_BODY()




    13. UPROPERTY()


    14. TSubobjectPtr<UInstancedStaticMeshComponent> InstancedStaticMeshComponent;






    15. UPROPERTY()


    16. UStaticMesh* SMAsset_Cube;




    17. };


    18.  



.cpp







    1. // Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.




    2. #include VictoryGame.h




    3. //


    4. // VictoryVertex3D




    5. //MAKE SEPARATE CLASSES OF THIS IF YOU WANT TO CHANGE THE MESH


    6. //


    7. AVictoryVertex3D::AVictoryVertex3D(const class FPostConstructInitializeProperties& PCIP)


    8. : Super(PCIP)


    9. {


    10. //Mesh


    11. static ConstructorHelpers::FObjectFinder<UStaticMesh> StaticMeshOb_torus(TEXT(StaticMesh’/Engine/EngineMeshes/Cube.Cube’”));


    12. SMAsset_Cube = StaticMeshOb_torus.Object;




    13. //create new object


    14. InstancedStaticMeshComponent = PCIP.CreateDefaultSubobject < UInstancedStaticMeshComponent > (this, TEXT(InstancedStaticMeshComponentCOMP));


    15. InstancedStaticMeshComponent.AttachTo(RootComponent);




    16. //Not Made some reason?


    17. if (!InstancedStaticMeshComponent) return;


    18. //~~~~~~




    19. //Set to Asset


    20. InstancedStaticMeshComponent->SetStaticMesh(SMAsset_Cube);




    21. InstancedStaticMeshComponent->bOwnerNoSee = false;


    22. InstancedStaticMeshComponent->bCastDynamicShadow = false;


    23. InstancedStaticMeshComponent->CastShadow = false;


    24. InstancedStaticMeshComponent->BodyInstance.SetObjectType(ECC_WorldDynamic);




    25. //Visibility


    26. InstancedStaticMeshComponent->SetHiddenInGame(false);




    27. //Mobility


    28. InstancedStaticMeshComponent->SetMobility(EComponentMobility::Movable);




    29. //Collision


    30. InstancedStaticMeshComponent->BodyInstance.SetCollisionEnabled(ECollisionEnabled::QueryOnly);


    31. InstancedStaticMeshComponent->BodyInstance.SetObjectType(ECC_WorldDynamic);


    32. InstancedStaticMeshComponent->BodyInstance.SetResponseToAllChannels(ECR_Ignore);


    33. InstancedStaticMeshComponent->BodyInstance.SetResponseToChannel(ECC_WorldStatic, ECR_Block);


    34. InstancedStaticMeshComponent->BodyInstance.SetResponseToChannel(ECC_WorldDynamic, ECR_Block);




    35. //~~~~~~~~~~






    36. if (!StaticMeshComponent) return;




    37. //Mobility


    38. StaticMeshComponent->SetMobility(EComponentMobility::Movable);




    39. //Collision


    40. StaticMeshComponent->BodyInstance.SetCollisionEnabled(ECollisionEnabled::QueryOnly);


    41. StaticMeshComponent->BodyInstance.SetObjectType(ECC_WorldDynamic);


    42. StaticMeshComponent->BodyInstance.SetResponseToAllChannels(ECR_Ignore);


    43. StaticMeshComponent->BodyInstance.SetResponseToChannel(ECC_WorldStatic, ECR_Block);


    44. StaticMeshComponent->BodyInstance.SetResponseToChannel(ECC_WorldDynamic, ECR_Block);


    45. }


    46.  


    47.  


    48.  


    49.  


    50.  


    51.  


    52.  





more ▼



answered Apr 03 ‘14 at 8:24 PM


Rama gravatar image

Rama 
7.7k  346  136  507








SaxonRah gravatar image 
SaxonRah 
Apr 03 ‘14 at 10:51 PM






Thanks mate! You are the best :) !









oOo.DanBO.oOo gravatar image 
oOo.DanBO.oOo 
May 11 ‘14 at 6:51 PM






i have a few problems when i try this solution. my objects get spawned in the world. but it seems they dont have a material applied even if i apply it in the code.


so for me the main difference is that instead of TSubobjectPtr MyBlock; i use this: TSubobjectPtr MyBlock;


and of course also in cpp for the pcip createabstractdefaul…..


but then the block has no material :<








Rama gravatar image 
Rama 
May 13 ‘14 at 7:32 AM






you’ll have to post your code for us to help you


also, it’d be better to post your issue as a separate topic so we can focus just on your issue :)


:)


Rama









Neil.Griffiths gravatar image 
Neil.Griffiths 
Jul 01 ‘14 at 12:15 AM






I know I’m late to this party but I’m guessing this is because your material isn’t set up to work on Instanced Meshes. Open up your material in the Material Editor (by double-clicking it in the Resource Browser) and set the property. :)










DJ_Lectr0 gravatar image 
DJ_Lectr0 
Aug 05 ‘14 at 10:58 PM






What if I needed to apply an instanced Material with a parameter wich is different for every instance? Would I just override AddInstance? And how would I get the static mesh created in there?









DJ_Lectr0 gravatar image 
DJ_Lectr0 
Aug 06 ‘14 at 12:06 AM






And also: How can I enable collision with my character??









Hyperloop gravatar image 
Hyperloop 
Aug 23 ‘14 at 2:10 AM






Rama, first off, thanks for being so active and helpful in the community I swear every third post I find turns out to be from you :D


I’m trying to solve this exact problem for myself as well and I have two quick(ish) questions:



  1. Does implementing this class help solve the issue of not being able to get a reference to a specific instance of a static mesh component during runtime? I’m running into that limitation, and it’s a dealbreaker because I need to be able to spawn AND destroy instances of the static mesh at runtime based on player interaction, but I can’t seem to do that via blueprints :/



2: If I place multiple instances of this actor into the world, do they each reference the SAME mesh, thereby helping to limit draw calls?


That’s the other huge issue I am hitting as I try to solve this with blueprints: Each instance of a BP that contains an instanced mesh isn’t inheriting or ‘grouping’/batching with the other instances even though it’s the same mesh. Functionally, that means I can’t make use of instanced meshes unless they ALL spawn from the same blueprint….and if they all spawn in the same BP, I can’t get a reference to a single instance to destroy it so it’s kind of useless for what I need to do :/


Your reply here was the closest thing I have found that might be a solution, I’m not a coder (yet) so I wanted to ask those Questions before I dive in and learn how to implement this :D








Hyperloop gravatar image 
Hyperloop 
Aug 23 ‘14 at 6:43 AM






Editing my post in regards to the first question: it would seem that in 4.4 they have JUST added the ability to do this!


“InstancedStaticMeshComponents now set the FHitResult.Item property with the index an instance hit by a collision event. This can be used with the above functions to remove a specific instance and replace it with a real StaticMeshComponent to provide interactivity with Foliage or other behavior.”


This is great news!


Still not sure how/if multiple Blueprints can have objects that are references to the same static mesh.










Plorax gravatar image 
Plorax 
Oct 08 ‘14 at 5:19 AM






What is an SMA ?


Sorry, I’m not familiar with the acronyms.


Also, is this code still valid for UE 4.4 ?


Please can someone point me in the right direction or show me a sample project doing the same InstanceStaticMesh thingy..








SaxonRah gravatar image 
SaxonRah 
Oct 08 ‘14 at 6:21 AM






SMA is StaticMeshActor.


I haven’t updated this project to 4.4 so im not entirely sure,but it should.


Are you making sure you are adding an instance of it ?










PhoenixFalcon gravatar image 
PhoenixFalcon 
Nov 22 ‘15 at 7:59 PM






Hi, I am trying to add InstancedStaticMeshComponent using the code above. It works for single component. However when I try to add three different instanced mesh componentes they all look the same. For example the first added mesh is floor, the second and the third are cubes. Everything is rendered as floor mesh.









PhoenixFalcon gravatar image 
PhoenixFalcon 
Nov 29 ‘15 at 7:44 PM 
Newest






Turns out the problem is with this line static ConstructorHelpers::FObjectFinder StaticMeshOb_torus(TEXT(“StaticMesh’/Engine/EngineMeshes/Cube.Cube’”)); I removed static and it seems to be working.




















1








I created a maze generator and I’m currently trying to figure out how to use an InstancedStaticMeshs in c++. Currently it spawns blueprints extended from a StaticMeshActor and I can only get about 10201 static meshes blueprints before i hit some heavy performance decrease, this is just on a maze alone


So when trying to make a rougelike maze dungeon with rooms and floors there are about ten to twenty times the static meshes. That’s allot of static mesh blueprints. Anyone have example usage ?


alt text





Product Version: 
Not Selected


Tags:
blueprints
c++
instanced mesh




maze101.png (434.8 kB)



more ▼



asked Apr 03 ‘14 at 1:58 AM


SaxonRah gravatar image

SaxonRah 
221  8  10  22








Dieselhead gravatar image 
Dieselhead 
Apr 03 ‘14 at 9:43 PM






I’m only guessing here but I think a game like this would also benefit greatly from level streaming.








SaxonRah gravatar image 
SaxonRah 
Apr 03 ‘14 at 10:51 PM






How would you level stream from actors spawned at run time ?








Dieselhead gravatar image 
Dieselhead 
Apr 04 ‘14 at 2:04 AM






Well thats what you get when browsing this place the last hour of work :)


Sorry, carry on!












1 answer: sort voted first ▼












5





Instanced Static Mesh


You can make a new class, InstancedStaticMeshActor


and add a Instanced Static Mesh Component


Then you spawn that actor


and to add additional instances you use this function in the Instanced Static Mesh Component Class







    1. UFUNCTION(BlueprintCallable, Category=Components|InstancedStaticMesh)


    2. virtual void AddInstance(const FTransform& InstanceTransform);


    3.  


    4.  



That’s pretty much all you need to do!


Here’s my code from the beta, that I used for my own tests, here’s a pic of my tests


In my case I extended a regular SMA so I would see the actor when it spawned :)


Spawning







    1. //Spawninfo


    2. FActorSpawnParameters SpawnInfo;




    3. //SET NO COLLISION FAIL TO TRUE


    4. SpawnInfo.bNoCollisionFail = true;




    5. SpawnInfo.Owner = VictoryEngine->VSelectedActor;




    6. AVictoryVertex3D NewVertex =


    7. GetWorld()->SpawnActor<AVictoryVertex3D>(


    8. AVictoryVertex3D::StaticClass(),


    9. Pos,


    10. FRotator::ZeroRotator,


    11. SpawnInfo


    12. );


    13. if(!NewVertex) return NULL;


    14. if(!NewVertex->InstancedStaticMeshComponent) return NULL;


    15. //~~~~~~




    16. //Mesh


    17. NewVertex->InstancedStaticMeshComponent->SetStaticMesh(VictoryEngine->AssetSM_EngineCube);




    18. //Add Core Instance


    19. FTransform newT = NewVertex->GetTransform();


    20. newT.SetLocation(FVector(0,0,0));


    21. NewVertex->InstancedStaticMeshComponent->AddInstance(newT);




    22. //Scale


    23. NewVertex->SetActorRelativeScale3D(CurrentVerticiesScale);


    24.  


    25.  



.h







    1. // Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.




    2. //Power




    3. #pragma once




    4. #include VictoryVertex3D.generated.h






    5. /**


    6. An instance of a StaticMesh in a level


    7. Note that PostInitializeComponents() is not called for StaticMeshActors


    8. /


    9. UCLASS()


    10. class AVictoryVertex3D : public AStaticMeshActor


    11. {


    12. GENERATED_UCLASS_BODY()




    13. UPROPERTY()


    14. TSubobjectPtr<UInstancedStaticMeshComponent> InstancedStaticMeshComponent;






    15. UPROPERTY()


    16. UStaticMesh* SMAsset_Cube;




    17. };


    18.  



.cpp







    1. // Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.




    2. #include VictoryGame.h




    3. //


    4. // VictoryVertex3D




    5. //MAKE SEPARATE CLASSES OF THIS IF YOU WANT TO CHANGE THE MESH


    6. //


    7. AVictoryVertex3D::AVictoryVertex3D(const class FPostConstructInitializeProperties& PCIP)


    8. : Super(PCIP)


    9. {


    10. //Mesh


    11. static ConstructorHelpers::FObjectFinder<UStaticMesh> StaticMeshOb_torus(TEXT(StaticMesh’/Engine/EngineMeshes/Cube.Cube’”));


    12. SMAsset_Cube = StaticMeshOb_torus.Object;




    13. //create new object


    14. InstancedStaticMeshComponent = PCIP.CreateDefaultSubobject < UInstancedStaticMeshComponent > (this, TEXT(InstancedStaticMeshComponentCOMP));


    15. InstancedStaticMeshComponent.AttachTo(RootComponent);




    16. //Not Made some reason?


    17. if (!InstancedStaticMeshComponent) return;


    18. //~~~~~~




    19. //Set to Asset


    20. InstancedStaticMeshComponent->SetStaticMesh(SMAsset_Cube);




    21. InstancedStaticMeshComponent->bOwnerNoSee = false;


    22. InstancedStaticMeshComponent->bCastDynamicShadow = false;


    23. InstancedStaticMeshComponent->CastShadow = false;


    24. InstancedStaticMeshComponent->BodyInstance.SetObjectType(ECC_WorldDynamic);




    25. //Visibility


    26. InstancedStaticMeshComponent->SetHiddenInGame(false);




    27. //Mobility


    28. InstancedStaticMeshComponent->SetMobility(EComponentMobility::Movable);




    29. //Collision


    30. InstancedStaticMeshComponent->BodyInstance.SetCollisionEnabled(ECollisionEnabled::QueryOnly);


    31. InstancedStaticMeshComponent->BodyInstance.SetObjectType(ECC_WorldDynamic);


    32. InstancedStaticMeshComponent->BodyInstance.SetResponseToAllChannels(ECR_Ignore);


    33. InstancedStaticMeshComponent->BodyInstance.SetResponseToChannel(ECC_WorldStatic, ECR_Block);


    34. InstancedStaticMeshComponent->BodyInstance.SetResponseToChannel(ECC_WorldDynamic, ECR_Block);




    35. //~~~~~~~~~~






    36. if (!StaticMeshComponent) return;




    37. //Mobility


    38. StaticMeshComponent->SetMobility(EComponentMobility::Movable);




    39. //Collision


    40. StaticMeshComponent->BodyInstance.SetCollisionEnabled(ECollisionEnabled::QueryOnly);


    41. StaticMeshComponent->BodyInstance.SetObjectType(ECC_WorldDynamic);


    42. StaticMeshComponent->BodyInstance.SetResponseToAllChannels(ECR_Ignore);


    43. StaticMeshComponent->BodyInstance.SetResponseToChannel(ECC_WorldStatic, ECR_Block);


    44. StaticMeshComponent->BodyInstance.SetResponseToChannel(ECC_WorldDynamic, ECR_Block);


    45. }


    46.  


    47.  


    48.  


    49.  


    50.  


    51.  


    52.  





more ▼



answered Apr 03 ‘14 at 8:24 PM


Rama gravatar image

Rama 
7.7k  346  136  507








SaxonRah gravatar image 
SaxonRah 
Apr 03 ‘14 at 10:51 PM






Thanks mate! You are the best :) !









oOo.DanBO.oOo gravatar image 
oOo.DanBO.oOo 
May 11 ‘14 at 6:51 PM






i have a few problems when i try this solution. my objects get spawned in the world. but it seems they dont have a material applied even if i apply it in the code.


so for me the main difference is that instead of TSubobjectPtr MyBlock; i use this: TSubobjectPtr MyBlock;


and of course also in cpp for the pcip createabstractdefaul…..


but then the block has no material :<








Rama gravatar image 
Rama 
May 13 ‘14 at 7:32 AM






you’ll have to post your code for us to help you


also, it’d be better to post your issue as a separate topic so we can focus just on your issue :)


:)


Rama









Neil.Griffiths gravatar image 
Neil.Griffiths 
Jul 01 ‘14 at 12:15 AM






I know I’m late to this party but I’m guessing this is because your material isn’t set up to work on Instanced Meshes. Open up your material in the Material Editor (by double-clicking it in the Resource Browser) and set the property. :)










DJ_Lectr0 gravatar image 
DJ_Lectr0 
Aug 05 ‘14 at 10:58 PM






What if I needed to apply an instanced Material with a parameter wich is different for every instance? Would I just override AddInstance? And how would I get the static mesh created in there?









DJ_Lectr0 gravatar image 
DJ_Lectr0 
Aug 06 ‘14 at 12:06 AM






And also: How can I enable collision with my character??









Hyperloop gravatar image 
Hyperloop 
Aug 23 ‘14 at 2:10 AM






Rama, first off, thanks for being so active and helpful in the community I swear every third post I find turns out to be from you :D


I’m trying to solve this exact problem for myself as well and I have two quick(ish) questions:



  1. Does implementing this class help solve the issue of not being able to get a reference to a specific instance of a static mesh component during runtime? I’m running into that limitation, and it’s a dealbreaker because I need to be able to spawn AND destroy instances of the static mesh at runtime based on player interaction, but I can’t seem to do that via blueprints :/



2: If I place multiple instances of this actor into the world, do they each reference the SAME mesh, thereby helping to limit draw calls?


That’s the other huge issue I am hitting as I try to solve this with blueprints: Each instance of a BP that contains an instanced mesh isn’t inheriting or ‘grouping’/batching with the other instances even though it’s the same mesh. Functionally, that means I can’t make use of instanced meshes unless they ALL spawn from the same blueprint….and if they all spawn in the same BP, I can’t get a reference to a single instance to destroy it so it’s kind of useless for what I need to do :/


Your reply here was the closest thing I have found that might be a solution, I’m not a coder (yet) so I wanted to ask those Questions before I dive in and learn how to implement this :D








Hyperloop gravatar image 
Hyperloop 
Aug 23 ‘14 at 6:43 AM






Editing my post in regards to the first question: it would seem that in 4.4 they have JUST added the ability to do this!


“InstancedStaticMeshComponents now set the FHitResult.Item property with the index an instance hit by a collision event. This can be used with the above functions to remove a specific instance and replace it with a real StaticMeshComponent to provide interactivity with Foliage or other behavior.”


This is great news!


Still not sure how/if multiple Blueprints can have objects that are references to the same static mesh.










Plorax gravatar image 
Plorax 
Oct 08 ‘14 at 5:19 AM






What is an SMA ?


Sorry, I’m not familiar with the acronyms.


Also, is this code still valid for UE 4.4 ?


Please can someone point me in the right direction or show me a sample project doing the same InstanceStaticMesh thingy..








SaxonRah gravatar image 
SaxonRah 
Oct 08 ‘14 at 6:21 AM






SMA is StaticMeshActor.


I haven’t updated this project to 4.4 so im not entirely sure,but it should.


Are you making sure you are adding an instance of it ?










PhoenixFalcon gravatar image 
PhoenixFalcon 
Nov 22 ‘15 at 7:59 PM






Hi, I am trying to add InstancedStaticMeshComponent using the code above. It works for single component. However when I try to add three different instanced mesh componentes they all look the same. For example the first added mesh is floor, the second and the third are cubes. Everything is rendered as floor mesh.









PhoenixFalcon gravatar image 
PhoenixFalcon 
Nov 29 ‘15 at 7:44 PM 
Newest






Turns out the problem is with this line static ConstructorHelpers::FObjectFinder StaticMeshOb_torus(TEXT(“StaticMesh’/Engine/EngineMeshes/Cube.Cube’”)); I removed static and it seems to be working.









发表评论

表情:
评论列表 (有 0 条评论,81人围观)

还没有评论,来说两句吧...

相关阅读