Solution to those who may stumble across this in the future: In the end, what I ended up doing was including a proxy page within my own website that Unity then referenced. I will include the code as well as a detailed explanation from another Unity forums user:
website-side:
Downloaded the following packages from npm and added the following code to app.js:
const axios = require('axios');
const bodyParser = require('body-parser');
const cors = require('cors');
// Middleware
app.use(bodyParser.json());
app.use(cors());
app.get('/proxy-google-drive', async (req, res) => {
const { googleDriveLink } = req.query;
if (!googleDriveLink) {
return res.status(400).json({ error: 'Google Drive link is required' });
}
try {
// Proxy the request to the Google Drive link
const response = await axios.get(googleDriveLink, {
responseType: 'stream', // Ensure response is streamed
headers: {
'User-Agent': 'UnityPlayer/5.3.5f1',
'Accept': '*/*'
}
});
// Pipe the response back to the Unity WebGL client
response.data.pipe(res);
} catch (error) {
console.error('Error proxying Google Drive link:', error.message);
res.status(500).json({ error: 'Internal server error' });
}
});
Unity-side:
Added the following code when changing the object texture to the google drive image link:
IEnumerator ProxyGoogleDriveLink(string googleDriveLink)
{
string expressServerURL = "https://langenheim-a07134ab155c.herokuapp.com";
// URL encode the Google Drive link
string encodedLink = UnityWebRequest.EscapeURL(googleDriveLink);
// Create the request URL with the encoded Google Drive link
string requestURL = expressServerURL + "/proxy-google-drive?googleDriveLink=" + encodedLink;
// Create a UnityWebRequest to GET the data
using (UnityWebRequest www = UnityWebRequest.Get(requestURL))
{
// Set the download handler to handle texture data
DownloadHandlerTexture downloadHandlerTexture = new DownloadHandlerTexture();
www.downloadHandler = downloadHandlerTexture;
// Send the request
yield return www.SendWebRequest();
// Check for errors
if (www.result != UnityWebRequest.Result.Success)
{
Debug.LogError("Error: " + www.error);
}
else
{
// Get the downloaded texture
Texture2D texture = downloadHandlerTexture.texture;
// Assign the texture to the object's material
this.gameObject.GetComponent<Renderer>().material.mainTexture = texture;
}
}
}
explanation by user alexsuvorov:
"When accessing a resource served from another domain, CORS headers don’t prevent the content from being downloaded, but they can prevent the content from being accessed from the page code in the browser. Regarding images specifically, CORS headers normally don’t prevent an image from being downloaded from another domain, or displayed on the page using an tag, or even rendered on a (assuming that you are not accessing the internal data of this canvas). However if the domain which is hosting the image doesn’t provide appropriate CORS headers, you will not be able to access the pixel data of the image. This means that normally you can get around the CORS limitations when downloading and displaying the image if you just want to display it without accessing the raw image data. For example it could be displayed on top of your game in a separate HTML element. However, I would assume that you would like to use the downloaded image in a more advanced way, like for example create a texture from this image and put it on a mesh. In this scenario there is no way to download and access the image directly from another server which doesn’t provide appropriate CORS headers.
Nevertheless, as already mentioned, CORS only applies to the browser, and it doesn’t prevent the image from being downloaded from any other software, like for example from a php or a nodejs process which is running on your server. This means that you can make a request to your server, informing it to first download the image from the original server, and then serve it as a response. In this case the image will actually come from your domain and not from the original one, and you can append all the necessary headers to the response if needed. So, technically speaking, this is not really “getting around” the CORS, but rather just re-hosting the requested images from your own server. But in many scenarios this scheme can still be useful.
This can be implemented for example as a simple php page that accepts the url of the remote resource as an argument, i.e. https:///getimage.php?url=https%3A%2F%2F%2Fimage.jpg. Php code then realizes that the https:///image.jpg image was requested, downloads it and serves to the client. Depending on the server setup you can perform streaming of the downloaded data, where it can be served to the client while being downloaded from the original server without delay, or you can cache the downloaded image on your server for future requests, or both. You can totally do this from a nodejs server as well. But the meaning is the same: first the image goes from the original server to your server (where it can be optionally cached) and then it goes from your server to the client browser where the game is currently running. The most appropriate implementation will depend on your specific server setup."
Hope this helps anyone who may be in my position in the future!