Alright so in terms of dynamically adding an image, a hack around I found to be useful is making a new widget and removing its canvas, adding an image and setting its screen size to ‘desired’ so no matter how big or small the image is, the view is not restricted. Go to the graph part of the widget and create a slate brush variable with any default texture. Go back to the designer, click on the image and navigate to Appearance -> Brush part of the image properties and bind the brush to your slate brush variable. This way, you can set the image to change dynamically when later created.
When you want to create this said image, just use the ‘create new widget’ node, add it to viewport or as a child of another container and add it to an array for reference or add a tag variable to it to find it later using ‘Get all actors of class’ node, you can drag off the widget reference from the create widget node and set the slate brush variable to change the image texture dynamically. In your example of the bullet, you’d create a userwidget of an overlay container, with the bullet’s image inside it then you’d create the image widgets as children for the overlay container with the right Z depth to overlay your bullet with the effects you want. You can create any combination of widget components without use of canvas in a widget blueprint with the screen size being ‘desired’ and dynamically create it without much hassle. Shame there isn’t an easier way to create an image, but this way is robust and tested and I haven’t had a problem with it. Hopefully that helps. Any questions, I am happy to answer or clarify.