EnoxSoftware / CVVTuberExample

CVVTuberExample(Computer Vision Virtual YouTuber Example) is an example project of controlling 3D humanoid model ("Unity-chan!" Model) using WebCamTexture.
https://assetstore.unity.com/packages/templates/tutorials/cv-vtuber-example-118186
89 stars 10 forks source link

Cannot switch camera on PC and unity editor #3

Closed huihut closed 5 years ago

huihut commented 5 years ago

On the PC, I have several camera devices, and each camera's WebCamDevice.isFrontFacing is true, so I can't switch the camera in the WebCamTextureCVVTuberExample scene. (Switching the camera is still initialized with the first camera. this and this)

1. "FaceRig Virtual Camera"
2. "DroidCam Source 3"
3. "c922 Pro Stream Webcam" (I want to use it)
4. "Logi Capture"

So, is it possible to provide an interface in WebCamTextureToMatHelper that allows me to switch to the next camera on the PC instead of using webCamTextureToMatHelper.requestedDeviceName = "c922 Pro Stream Webcam";

WebCamTextureMatSourceGetter.cs

public virtual void ChangeCamera()
{

#if UNITY_EDITOR || UNITY_STANDALONE
            // webCamTextureToMatHelper.NextCamera();  // Your interface
#elif UNITY_ANDROID
            if (!webCamTextureToMatHelper.IsFrontFacing ()) {
                rearCameraRequestedFPS = webCamTextureToMatHelper.requestedFPS;
                webCamTextureToMatHelper.Initialize (!webCamTextureToMatHelper.IsFrontFacing (), rearCameraRequestedFPS, webCamTextureToMatHelper.rotate90Degree);
            } else {                
                webCamTextureToMatHelper.Initialize (!webCamTextureToMatHelper.IsFrontFacing (), 15, webCamTextureToMatHelper.rotate90Degree);
            }
#else
            webCamTextureToMatHelper.requestedIsFrontFacing = !webCamTextureToMatHelper.IsFrontFacing ();
#endif
}
EnoxSoftware commented 5 years ago

You should replace the current code with this.

        public virtual void ChangeCamera ()
        {
            #if UNITY_EDITOR || UNITY_STANDALONE
            string deviceName = webCamTextureToMatHelper.GetDeviceName ();
            int nextCameraIndex = -1;
            for (int cameraIndex = 0; cameraIndex < WebCamTexture.devices.Length; cameraIndex++) {
                if (WebCamTexture.devices [cameraIndex].name == deviceName) {
                    nextCameraIndex = ++cameraIndex % WebCamTexture.devices.Length;
                    break;
                }
            }
            if (nextCameraIndex != -1) {
                webCamTextureToMatHelper.requestedDeviceName = nextCameraIndex.ToString ();
            } else {
                webCamTextureToMatHelper.requestedIsFrontFacing = !webCamTextureToMatHelper.IsFrontFacing ();
            }
            #elif UNITY_ANDROID
            if (!webCamTextureToMatHelper.IsFrontFacing ()) {
                rearCameraRequestedFPS = webCamTextureToMatHelper.requestedFPS;
                webCamTextureToMatHelper.Initialize (!webCamTextureToMatHelper.IsFrontFacing (), rearCameraRequestedFPS, webCamTextureToMatHelper.rotate90Degree);
            } else {                
                webCamTextureToMatHelper.Initialize (!webCamTextureToMatHelper.IsFrontFacing (), 15, webCamTextureToMatHelper.rotate90Degree);
            }
            #else
            webCamTextureToMatHelper.requestedIsFrontFacing = !webCamTextureToMatHelper.IsFrontFacing ();
            #endif
        }
huihut commented 5 years ago

Thanks, but you should change if (nextCameraIndex == -1) to if (nextCameraIndex != -1).

Then it can switch every camera on the PC.

Thank you so much.

huihut commented 5 years ago

also, should this and this be exchanged?

EnoxSoftware commented 5 years ago

I wrote this code for the following reasons, but it is not always necessary.

huihut commented 5 years ago

I mean, rearCameraRequestedFPS is assigned but not used when using Android's rear camera.

WebCamTextureMatSourceGetter.cs#L124

            if (!webCamTextureToMatHelper.IsFrontFacing ()) {
                rearCameraRequestedFPS = webCamTextureToMatHelper.requestedFPS;
                webCamTextureToMatHelper.Initialize (!webCamTextureToMatHelper.IsFrontFacing (), 15, webCamTextureToMatHelper.rotate90Degree);
            } else {                
                webCamTextureToMatHelper.Initialize (!webCamTextureToMatHelper.IsFrontFacing (), rearCameraRequestedFPS, webCamTextureToMatHelper.rotate90Degree);
            }

Should it be as follows?

            if (!webCamTextureToMatHelper.IsFrontFacing ()) {
                rearCameraRequestedFPS = webCamTextureToMatHelper.requestedFPS;
                // rear camera uses requested fps
                webCamTextureToMatHelper.Initialize (!webCamTextureToMatHelper.IsFrontFacing (), rearCameraRequestedFPS, webCamTextureToMatHelper.rotate90Degree);
            } else {         
                // front camera uses 15fps
                webCamTextureToMatHelper.Initialize (!webCamTextureToMatHelper.IsFrontFacing (), 15, webCamTextureToMatHelper.rotate90Degree);
            }
EnoxSoftware commented 5 years ago

I'm sorry for the confusion. This code has this meaning.

            if (!webCamTextureToMatHelper.IsFrontFacing ()) { 
                // When the rear camera is active.
                // stores current fps.
                rearCameraRequestedFPS = webCamTextureToMatHelper.requestedFPS;
                // switch the rear camera to the front (uses 15 fps).
                webCamTextureToMatHelper.Initialize (!webCamTextureToMatHelper.IsFrontFacing (), 15, webCamTextureToMatHelper.rotate90Degree);
            } else {        
                // When the front camera is active.
                // switch the front camera to the rear (uses stored rearCameraRequestedFPS).        
                webCamTextureToMatHelper.Initialize (!webCamTextureToMatHelper.IsFrontFacing (), rearCameraRequestedFPS, webCamTextureToMatHelper.rotate90Degree);
            }
huihut commented 5 years ago

oh, I understand, sorry to misunderstand you.