Environments (export-ed variables) are passed only "downwards" (from parent to child process), not upwards.
This means that if you want to run the sub-script from the main-script as a process, the sub-script must write the names-and-values somewhere so that the parent process (the main script) can read and process them.
There are many ways to do this, including simply printing them to standard output and having the parent script eval the result:
eval $(./sub_script)
There are numerous pitfalls to this (including, of course, that the sub-script could print rm -rf $HOME and the main script would execute that—of course the sub-script can simply do that directly, but it's even easier to accidentally print something bad than to accidentally do something bad, so this serves as an illustration). Note that the sub-script must carefully quote things:
#! /bin/sh
# sub-script
echo a=value for a
When evaled, this fails because value for a gets split on word boundaries and evals to running for a with a=value set. The sub-script must use something more like:
echo a=\'value for a\'
so that the main script's eval $(./sub_script) sees a quoted assignment.
If the sub-script needs to send output to standard output, it will need to write its variable settings elsewhere (perhaps to a temporary file, perhaps to a file descriptor set up in the main script). Note that if the output is sent to a file—this includes stdout, really—the main script can read the file carefully (rather than using a simple eval).
Another alternative (usable only in some, not all, cases) is to source the sub-script from the main script. This allows the sub-script to access everything from the main script directly. This is usually the simplest method, and therefore often the best. To source a sub-script you can use the . command:
#! /bin/sh
# main script
# code here
. ./sub_script # run commands from sub_script
# more code here