It’s a bit complex, it’s been 2 days I’m struggling and trying to fix this issue.
So basically I’m trying to make a VRchat world which depending on user input load a picture from a URL.
For example if the user input “ok.jpg” the loaded picture will be https://mywebsite.com/ok.jpg
I successfully made a code to load a picture and apply it as texture on plane object using Udon here is the code:
using UdonSharp;
using UnityEngine;
using VRC.SDK3.Image;
using VRC.SDKBase;
using VRC.Udon.Common.Interfaces;
[UdonBehaviourSyncMode(BehaviourSyncMode.None)]
public class displayPictures : UdonSharpBehaviour
{
[SerializeField, Tooltip("URL of the image to load")]
private VRCUrl imageUrl;
[SerializeField, Tooltip("Renderer to show downloaded image on.")]
private new Renderer renderer;
private VRCImageDownloader _imageDownloader;
private IUdonEventReceiver _udonEventReceiver;
private Texture2D _downloadedTexture;
private void Start()
{
_imageDownloader = new VRCImageDownloader();
_udonEventReceiver = (IUdonEventReceiver)this;
// load
LoadImage();
}
private void LoadImage()
{
if (_downloadedTexture != null)
{
renderer.sharedMaterial.mainTexture = _downloadedTexture;
}
else
{
var rgbInfo = new TextureInfo();
rgbInfo.GenerateMipMaps = true;
_imageDownloader.DownloadImage(imageUrl, renderer.material, _udonEventReceiver, rgbInfo);
}
}
public override void OnImageLoadSuccess(IVRCImageDownload result)
{
Debug.Log($"Image loaded: {result.SizeInMemoryBytes} bytes.");
_downloadedTexture = result.Result;
renderer.sharedMaterial.mainTexture = _downloadedTexture;
}
public override void OnImageLoadError(IVRCImageDownload result)
{
Debug.Log($"Image not loaded: {result.Error.ToString()}: {result.ErrorMessage}.");
}
private void OnDestroy()
{
_imageDownloader.Dispose();
}
}
Now as the documentation says, " VRCUrl objects currently cannot be constructed at runtime in Udon", so I thought I could initialize it at compile time but then modify it but didn’t suceeed as it would mean to convert a string into VRCurl object in runtime which is impossible.
One may just answer to this post : “it’s impossible you can’t do, it’s VRchat security measure” Then how do video players and tablets work in VRChat?
Also, to be honest didn’t understand the code of video players, but as I understand they use VRCurl input object which allows to dynamically create VRCurl object? Is that right? If not how can I achieve this?
Would be grateful if someone can point me the right direction
With a video player the end user is providing the full URL.
Certain world with search functionally will populate the URL box with a something, and then the user is told to add thier query to the end.
For a video search world they have a pool of URLs, like NNNN, and a search will temporarily allocate some of those numbers, like say 30 results and an image with thumbnails
I don’t get it.
What I mean here is that I don’t even know how to make a system where the player input a full url and load a picture because I do not know how to edit the VRCurl object once the user spawn into the world.
I don’t know how to allocate something because I do not know how people do to edit it VRCurl object during runtime.
I see the YouTube api work by requesting url like this:
https://api.u2b.cx/search?pool=example10000&input= Type YouTube search query here →
But this is what I don’t know how to do imagine the user input a url here how can I modify this VRCurl object during runtime and have new edited url or simply overwrite it to get new url and load new results
Have you used one of those worlds? That URL you’ve quoted is baked into the world and the user clicks on the address input, that baked URL is already in the input field, and the user adds to it. When the user hits okay on the keyboard, the contents of the input field are a VRCUrl.
I think I just realized something lol.
Since the content of the input field is VRCurl the VRCurl object don’t change itself cuz it points to the content of the text input.
So the only way of doing what I want here is somehow try to hide a part of the text in the input field… and have the user write the rest.
I won’t mark as solution because maybe some people here have better idea on how to achieve this.
So I finally understood that the VRCUrl input will automatically give a VRCUrl object, that you can read.
However it’s impossible to edit an input during runtime as it would imply that we can “=” it to a VRCurl object.
But somehow only the user can write a string for a VRCUrl
VRchat is so limited I hate it I wish we didn’t have that much restriction
You can arbitrarily write to a regular text box and ask user to copy from one and paste into another, that’s what vket does for tracking what world you visited
Well, fun fact you can’t paste in VRCHAT while in VR (or you have to leave your headset to press CTRL + V on your keyboard).
Let me explain how complex is my current issue (sorry for the bad formatting):
Basically, I have an API which generate picture depending on what the user input.
It’s simply a get request for example you can do on https://mygenerativeapi.com/api/?data=USERWRITEWHATEVERHEWANTSTO
To do so I used a VRCUrlInputField with a script which uses SetUrl to each time write in the input field automatically “https://mygenerativeapi.com/api/?” so the user just have to write what comes next. But obviously this would be too good to work as, I quote (from the VRChat documentaiton) :
"The URL must point directly at an image file. URL redirection is not allowed and will result in an error."
Then you could have the idea to have the API directly giving a generated link which point directly to the image file using VRCStringDownloader.LoadUrl (because it doesn’t need to point directly to a .txt file) but the problem with this solution is that you can’t then tell a script to use this URL, as it would imply to turn it into VRCURL so there is as you said that trick of asking he user to copy that string into a VRCUrlInputField but as I said you can’t copy something in vrchat without getting out of the headset (I wish maybe it was possible to make a button which automatically copy and or paste? if it’s possible let me know).
My last ** idea was literally to download the picture diectly from the api but the picuture would be downscaled and in base64 so you can download it as text (using VRCStringDownloader), convert it, apply as texture. But guess what : Method is not exposed to Udon: 'texture.LoadImage(imageBytes)'
How the hell am I supposed to load texture data if I can’t load an image from byte array? Well I simply can’t so even this method can’t be used.
VRChat is made in a way that text will stay text and the only thing you can do is display it as text.
I had a last change, a last possible idea that maybe be crazy… But…
I had this idea from website like my wall of text, you can create a new “walloftext” just by adding a directory to the website that doesn’t exist but in back end it just auto create it.
So my idea is to turn the user input on the API level into an actual direct path image directory but sometimes I’m wondering if this will work as the page will somehow have to load before showing the picture even if it’s on the url requested…
If you have read this far, thank you, and I would be even more grateful if you have at least 1 little idea. I’ll try my API thing and update if it work (currently have no idea how to implement that (I don’t think you can do it just by making a new directory)).
This is a pain tbh, I hope VRchat put less restriction, like at LEAST why would even string loading be allowed without direct path but why it wouldn’t for PICTURES?
Two buttons along the same row as the space bar, the one with the two rectangles on the left is Copy, and the clipboard on the right is your paste button
So when I want to play a video in VRC I go to the video player, click on the URL entry, and the virtual keyboard pops up, and I simply press the paste button on the right.
The VRChat instructions are saying that for image loading, the URL executed on needs to come back with an image. https://mygenerativeapi.com/api/?data=USERWRITEWHATEVERHEWANTSTO so on the first request to that you generate and return an image, and then for other requests (from the other users in the room) you should just return the same image. You can sync the URL after you’ve gotten the image.
https://mygenerativeapi.com/api/?data= is what you should start with, so the user can just add their inputs like butts
I didn’t know about VRCHAT paste in VR to be honest lol.
As for the rest there is something I don’t understand I never done a get request with VRCurl for image loading directly simply because it says it must point directly to an image file, https://mygenerativeapi.com/api/?data=USERWRITEWHATEVERHEWANTSTO ← THIS isn’t pointing directly to an image file right? Even if my API return picture data with no redirection?
MATE… I can’t FUCKING BELIEVE ALL THIS GOD DAMN TIME I HAVE BEEN THINKING THAT YOU COULDN’T LOAD IF IT WASN’T AN IMAGE PATH ENDING WITH COMMIN PICTURE FILE EXTENSION BUT YOU RIGHT IT GOD DAMN WORK YOU DON’T NEED THIS IT JUST WORK HOW IS THAT WASTED LITERALLY… .3 DAY OR SO ON THIS ISSUE . AND NOT SHIT FUCKING WORKS SQDOING.