All the cast really does is that it checks that UserObject is of type MySimClass and then copies the reference, so I doubt that this will be a bottleneck.
A performance hit might occur if the types on both sides were not the same and type conversion had to be done. For example, if MySimClass had a base class MySimBase and we tried to cast the same object like this:
MySimBase mySimObject = (MySimBase)RigidBody.UserObject;
then it would have to climb the inheritance tree to check that the cast was valid.
Generics would get rid of the type check, but it's a small gain and would be confusing to those that don't use the UserObject.
Storing the reference in UserObject should be fine. Another way I can think of would be to use a Dictionary of <RigidBody, MySimClass> pairs.
I'd recommend running a profiler such as SlimTune (http://code.google.com/p/slimtune/
) to see where most of the time is spent.