That sounds messy to have all the possible enemy attributes as family instance variables. You probably just want attributes common to all enemies to be in the family and the attributes specific to certain enemies as instance variables of that type. Instance variables overall are the cleanest way to store values per instance.
When you add a dictionary you only get one. To be interchangeable with instance variables you’d want a dictionary per instance, but that’s not super straightforward to do and can make events look more busy.
You can put an object type and a dictionary in a container to have one per instance, but you can’t create a container with a family. Containers let events automatically pick the paired dictionary when you pick a sprite.
Another more manual way is to create a dictionary whenever you create a sprite and store the dictionary’s uid in an instance variable of the sprite. Then you’ll need to pick the dictionary whenever you want to access it in events. You’ll probably want to pick and destroy the dictionary when you destroy the sprite too. This is useful in some situations but generally it makes events harder to read.
So apart from having values per instance.
Variables are nice since they are named and let you catch typos as you write them. They are also cleaner looking to use over dictionary keys.
Dictionaries are accessed by a text string so it’s up to you to avoid typos. Accessing a value with a name you didn’t add to the dictionary will just silently give you a zero which can be a tricky to notice. With a dictionary you can also add things on the fly but that has limited usefulness. It also lets you access values by name if that’s important.
Overall using variables or instance variables are the way to go, especially if you have values per instance.