Yes, in that case, your offset makes sense. I assume you ensured that the package does not get spawned on an obstacle because of the offset.
Regarding the positions, theoretically, you could “forget” the sprites and define positions that are independent from any sprites. With the OnDrawGizmos method, you could even visualise those positions for you (not the player).
Its just that sometimes the position of rock and package coincide because the rocks are also on the roads and I dont want that to happen
How did the rock get on the road? Do you spawn the rocks at random positions or do you know in advance where the rock is? If the latter, remove the position of the rock/road from your array. If the former, your code needs to handle a second array where it keeps track of “allowed” spawn positions.
Depending on how you implemented your idea and how it is supposed to work, a dictionary with all available positions (Vector3) could make sense. They would act as the key. The value could be a Transform. If the value is
null, the position is free. If the value is not
null, the position is occupied by “something”.
As you can see, there are multiple ways to approach your original problem. To solve your remaining problem, you have to organise your data and define rules how your program is supposed to handle certain cases.