Another way to look at this is if you have say a physical button that the user can toggle on or off and it is lit up by code. Doing this is processed by procedural code then the code will know what state the button is and if any processing limitations will be slow in processing if the button is on or off as could be indicated by slow transition to respond to the light going on or off.
Now using OOP code the code that controls the light being on or off is would in general isolated from the processing of the state of the button and can lead to the the button showing on with the light on yet the processing code still thinking it is off. IE the code has no fixed static processing path and as such can lose state of if the button is on or off. This can lead to the button being off and the underliying code thinking it is on as they desync. Sorry if not the best explanation but is based upon a example I've seen in real life. The example was a phone busy/not busy button and the lovely C++ object oriented code got into a kefufle thinking the butotn was on when it was not after the operator had played track and feild on the button tapping away at it real fast out of bordem. The next result was the call processing system thought the phone was not busy when it was and tried to route a call which it was unable to do and the upshot was the entire phone system crashed.
OOP has it's uses, but it also has it's downsides, like all approaches it is the right tool for the job. Just that error handerling in OOP can get more complex than boring old procedural code which is alot easier to deal with, when it comes to exceptions as the processing state is static.
Another way to look at it is physical gears - procedural code is a fixed gear and OOP is a gear cog that can change in size and whilst you will see the end result you have no idea what size the dynamic OOP cog is.
Realy can be a hard one to explain without examples and it does lack a classic Hello World example.