There is another reason why I like to use unpacked. With unpacked, there is no temptation (and accidental possibility) of treating the whole array name as a variable, and make an erroneous assignment. There is also no possibility of bit-bleeding from one element to another, when you may be thinking you are accessing B bits of element N, but in reality you may be accessing K bits of element N and B-K bits of element N+-1..
My philosophy is to keep only the things that belong together as a "unit of information" in the packed dimension. Everything else in the unpacked dimension. The default thinking should be unpacked, and pack only what you need to.
For example, if I have 9 ports, each with 21 bits of information, I would like to declare it as :
input logic [20:0] p1 [9];
The 20:0
part constitutes a unit of information, assigned and sampled together (nominally). Splitting those bits apart will destroy the protocol or the character of the port. On the other hand, changing the number of ports from 9 to, say, 16, is not going to affect the nature of the information in each port, so the 9 ports really belong in the unpacked dimension in my mind.
Hope that might give you a paradigm to think along... In this paradigm, you would be surprised how many things start to appear unpacked that you always thought were packed !!