For example I have torch that checks on a first frame of the game if it is raining and if it’s not I want to have a gameobject with fire particles on it.
For garbage collection, is it better to create object that I need (spawn fire on torch if its not raining), or destroy object I don’t need (destroy fire object on torch if it’s raining)? Or there is not major difference and I should do what is more convenient for my workflow?
Always better to change some object’s position (you don’t want it on sight? take it to (-1000, -1000, -1000) position, for instance) to get rid of it than destroying it. Likewise, better to instantiate everything on startup and place objects someplace you don’t see them rather than Instantiating in runtime.
It happens in awake. So I don’t care about runtime performance impact. I care about vram usage and garbage collection that might trigger during gameplay.
For garbage collection it is better to spawn new object only if you need it and never destroy it. The best memory strategy for all times was and always will be to allocate all required memory when program starts and free it when program exits. But modern programs are often too complex for that. So I suggest narrow it down to scene or even episode of scene (if scenes are too big or you have open world game) level. Create objects what you will need along with scene and destroy them when scene is unloaded.
As for unity, instantiation and destruction of game objects are very slow operations and you should adjust your strategy to avoid those whenever possible.