Transfer ownership with std::move: unique_ptr p2 = std::move(p1);. After the move, p1 is empty (holds nullptr) and p2 owns the resource. The object isn't copied, just the ownership.
Moving lets you return unique_ptr from functions or store them in containers. The resource travels with its owner. When the final owner dies, the resource is freed. Pass unique_ptr to functions by value to transfer ownership in, or by reference to let the function use without taking ownership.
The type system documents who owns what.