Hello. I want to show the phone camera feed on a visual element. I’m trying to assign it, but VisualElement’s background style is not accepting a WebCamTexture object.
There is no WebCamTexture as a constructor. So I can’t assign a WebCamTexture object reference to a VisualElement.
You should be able to cast Texture to Texture2D: Texture2D tex2D = (Texture2D)YourTexture;
Or maybe you could use a spearate Image element. Assigning it to the “image” property should work since that one takes a Texture and WebCamTexture is derived from the Texture class so it should work.
There is no direct casting from WebCamTexture to Texture2D. So first, I have cast from WebCamTexture to Texture. Then I cast from Texture to Texture2D. And as a result, It is giving an invalid casting error from Texture to Texture2D.
In the UI Builder, there is no Image element.
Normally, I should be able to pass WebCamTexture object reference to VisualElement. Because If I can’t, It won’t update the image, and I can’t see the camera feed.
There is something that I don’t know. But I could not figure it out.
Here is an updated version which also sets the background of a visual element. Though we have to copy the texture manually every frame.
using System;
using UnityEngine;
using UnityEngine.UIElements;
public class WebcamTest : MonoBehaviour
{
protected UIDocument _document;
public UIDocument Document
{
get
{
if (_document == null)
{
_document = this.GetComponent<UIDocument>();
}
return _document;
}
}
protected WebCamTexture _webcam;
Texture2D _texture2D;
void Start()
{
// Find device an bort if none was found, else use first.
var devices = WebCamTexture.devices;
if (devices.Length == 0)
return;
// Get webcam texture from webcam
var name = devices[0].name;
Debug.Log($"Using Webcam {name}");
_webcam = new WebCamTexture(name);
_webcam.Play();
// Apply to image
var img = Document.rootVisualElement.Q<Image>();
if (img != null)
{
img.image = _webcam;
}
// Now about that bg image
_texture2D = new Texture2D(
_webcam.width, _webcam.height,
TextureFormat.ARGB32, 1, false);
// Make the texture 2D the bg image.
var bgImage = Document.rootVisualElement.style.backgroundImage.value;
bgImage.texture = _texture2D;
Document.rootVisualElement.style.backgroundImage = bgImage;
}
private void Update()
{
// Sadly we have to copy from the webcam to the texture2D manually.
// Maybe this could be avoided if there is a way to hook up the webcam
// texture to a render texture (backgroundImage has a renderTexture target).
Graphics.CopyTexture(_webcam, _texture2D);
}
}
I hope Graphics.CopyTexture uses Graphics.Blit() to copy the texture and does not read and write every pixel as that would be slow.