Megafunk / MassSample

My understanding of Unreal Engine 5's experimental ECS plugin with a small sample project.
MIT License
681 stars 112 forks source link

Passing per instance Material data from a Processor to Instanced Static Meshes. #35

Closed PreyK closed 1 year ago

PreyK commented 2 years ago

Hello :) In epic's video overview of Mass, there's a mention of the possibility to pass custom data to the entity's material. I'm currently using my own homebrew ECS for my farming game where a lot of stuff needs to grow at once, I'm using a HISM with per-instance material data that controls the growth of the plants. However, I'd love to just use mass instead, it has better performance than mine and I wouldn't have to maintain my own system.

On the article with the video at the bottom of the page, there's a part about it It took me some tries to be able to send the Custom Data to the material from a Processor but in the end it was just a couple of lines of code. But no sample or any further explanation.

Does anyone have any ideas or insight on how to do this? I'd love to contribute back a demo of this if I manage to get it working :) Thanks for this repo btw, it was already a huge help. And my apologies if it's off, haven't found anywhere else I could ask about this, hope it's okay but feel free to delete it if it isn't

image image

Megafunk commented 1 year ago

Looks like FMassInstancedStaticMeshInfo::AddBatchedCustomData<>() is the ticket. The CitySample has quite a few uses of it for the crowd animation and traffic.

PreyK commented 1 year ago

Looked into the City Sample, managed to get it to work! https://www.youtube.com/watch?v=nC-SskL4r9I What confused me is that you only need to call ISMInfo.AddBatchedCustomData(MyFragment.MyCustomData) once from a UMassObserverProcessor at initialization. From there on, you modify MyFragment.MyCustomData from anywhere, the modified custom data is automatically represented in the ISM, you don't need to explicitly update the ISM's custom data (looks like it's just a ref wich is quite amazing). Will make a PR with a demo 👍

Ji-Rath commented 1 year ago

Looked into the City Sample, managed to get it to work! https://www.youtube.com/watch?v=nC-SskL4r9I What confused me is that you only need to call ISMInfo.AddBatchedCustomData(MyFragment.MyCustomData) once from a UMassObserverProcessor at initialization. From there on, you modify MyFragment.MyCustomData from anywhere, the modified custom data is automatically represented in the ISM, you don't need to explicitly update the ISM's custom data (looks like it's just a ref wich is quite amazing). Will make a PR with a demo 👍

Really cool stuff! But I believe when you set a processor to 'bAutoRegisterWithProcessingPhases' it causes the observer to run every tick. Please correct me if I am wrong, that is just my observation.

Megafunk commented 1 year ago

Ack!!! You are right, Ji-Rath! It seems that you have to call AddBatchedCustomData every frame after all unless I am missing something. It appears the city sample does that as well.

EDIT: refactor pushed that changes it to a regular processor

PreyK commented 1 year ago

Looked into the City Sample, managed to get it to work! https://www.youtube.com/watch?v=nC-SskL4r9I What confused me is that you only need to call ISMInfo.AddBatchedCustomData(MyFragment.MyCustomData) once from a UMassObserverProcessor at initialization. From there on, you modify MyFragment.MyCustomData from anywhere, the modified custom data is automatically represented in the ISM, you don't need to explicitly update the ISM's custom data (looks like it's just a ref wich is quite amazing). Will make a PR with a demo 👍

Really cool stuff! But I believe when you set a processor to 'bAutoRegisterWithProcessingPhases' it causes the observer to run every tick. Please correct me if I am wrong, that is just my observation.

Are you sure? Based on epic's video it shouldn't.

Setting bAutoRegisterWithProcessingPhases to true is the same as ticking it in your Project Settings -> Mass -> Processor CDOs or in your project's DefaultMass.ini As far as I understand from epic's video it should just register that processor for its processing phase (automatically adds that processor to the world for the processing phase its valid) https://youtu.be/f9q8A-9DvPo?t=492

image

Since it's an observer processor that "observes" Operation = EMassObservedOperation::Add; it should only run when entities are added? image

Based on stuff I experimented with AddBatchedCustomData just adds a custom data pointer reinterpreted as floats. (like ISM custom float data) image

Once we added it to the entity, in theory, we shouldn't need to touch it anymore but I'd definitely kill for some official documentation on this rn :D

Megafunk commented 1 year ago

MassObservers actually have bAutoRegisterWithProcessingPhases set to false in their parent class and are designed to be called only from the observer manager when their watched fragments are alerted to changes by things like deferred fragment adds, etc. By setting it to true your observer processor kind of just runs ever frame AND with observer changes.