PostgreSQL - Generate unique name on insert based on other columns
You can achieve this with triggers and trigger procedures (trigger functions). Read Tutorial on triggers and from PostgreSQL documentation 40.9. Trigger Procedures. The following is the code for both the procedure and the trigger (there might be even more elegant ways to form the procedure):

CREATE OR REPLACE FUNCTION create_people() RETURNS trigger AS $$
    DECLARE
    u_num integer;
    BEGIN
    u_num := (SELECT count(*) FROM people WHERE NEW.name = people.name AND NEW.surname = people.surname);
    NEW.uname := NEW.name || NEW.surname || CASE u_num WHEN 0 THEN '' ELSE u_num::text END;
    RETURN NEW;
        END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER create_people BEFORE INSERT ON people
    FOR EACH ROW EXECUTE PROCEDURE create_people();


DISCLAIMER: As mentioned in the comments you should carefully plan on how to handle the possible deletes and updates on uname before using a solution based on this trigger on any production environment.