I have witnessed and participated in many online debates about OOP. The proponents of OOP usually do not know how to write proper procedural code. It is possible to write procedural code that is highly modular. It is possible to separate code and data and ensure that functions can only write to their own data store. It is possible to implement the concept of inheritance using procedural code. More importantly, procedural code is slimmer, faster and easier to debug.
If you build single-file modules with strict naming conventions, procedural code is easier to write and maintain than OO and it will do the same or more and faster. And don't forget that when your application runs, it is always procedural no matter how many classes feature in your script.
Then you have the issue of languages like PHP, which are not truly Object Oriented and rely on hacks to fake stuff like multiple inheritance. The big shots who influence the direction of the language have turned PHP into a patchwork of inconsistent rules that have become too big for what it initially intended. When I see developers write huge templating classes for what was intended as a procedural templating language, I can't help but smile.
If you compare properly-written OO code with poorly-written procedural code, then you will always come to the wrong conclusion. Very few projects warrant an Object Oriented design. If you are IBM and manage a huge project that needs to be maintained for years by multiple developers, go for Object Oriented. If you are writing a small blog or shopping website for a client, think twice.
To answer the original question, OOP is hard because it does not solve real-life programming dilemmas without resorting to solutions that are 100 times more complicated than they should be. One of the most powerful solutions to many programming problems is the judicious use of global data. Yet the new-wave university graduates will tell you that it is a big no-no. Globally-available data is dangerous only if you are a clumsy programming bunny. If you have a strict set of rules in place and proper naming conventions, you can get away with having all of your data global.
It should be a mandatory requirement for any Object Oriented programmer to know how to write a chess-playing application in assembler for a maximum available memory of 16K. They would then learn how to trim the fat, cut the laziness and generate ingenious solutions.