I’m creating a Unity project for Android mobile devices, similar to a “Instagram/Snapchat” Camera filter app but dedicated for my work, so we can create photos and videos with our own dedicated and private filters.
In the Hierarchy of the project, I have the following elements:
+Main Camera
+Canvas:
- RawImage
- CaptureButton
- FlashButton
- FilterDropdown
- FilterButton
- RecordButton
- StopButton
- CameraController
- PreviewPanel
- FilterManager
The problem is that Im creating this project from basic notions of programming and Unity, and I have 3 scripts in my project:
CameraController.cs
using UnityEngine;
using System;
using NativeGalleryNamespace;
using UnityEngine.UI;
using UnityEngine.UIElements;
public class CameraController : MonoBehaviour
{
private WebCamTexture webCamTexture;
private Texture2D currentPhoto;
private string recordedVideoPath;
public RawImage cameraPreview;
public PreviewController previewController;
private bool isRecording = false;
public void StartCamera()
{
if (!Application.HasUserAuthorization(UserAuthorization.WebCam))
{
Application.RequestUserAuthorization(UserAuthorization.WebCam);
}
if (webCamTexture == null)
{
webCamTexture = new WebCamTexture(1080, 1920, 30);
cameraPreview.texture = webCamTexture;
webCamTexture.Play();
DebugLogger.Log("Cámara inicializada correctamente.");
}
else if (!webCamTexture.isPlaying)
{
webCamTexture.Play();
DebugLogger.Log("Reanudando cámara.");
}
}
public void StopCamera()
{
if (webCamTexture != null && webCamTexture.isPlaying)
{
webCamTexture.Stop();
DebugLogger.Log("Cámara detenida.");
}
}
public void CapturePhoto(Action<Texture2D> onPhotoCaptured)
{
if (webCamTexture != null && webCamTexture.isPlaying)
{
currentPhoto = new Texture2D(webCamTexture.width, webCamTexture.height);
currentPhoto.SetPixels(webCamTexture.GetPixels());
currentPhoto.Apply();
onPhotoCaptured?.Invoke(currentPhoto);
DebugLogger.Log("Foto capturada.");
}
else
{
Debug.LogWarning("No se puede capturar la foto, la cámara no está activa.");
}
}
public void StartRecording()
{
Debug.Log("Grabación iniciada.");
isRecording = true;
}
public void StopRecording(Action<string> onVideoStopped)
{
if (isRecording)
{
isRecording = false;
Debug.Log("Grabación detenida.");
// Lógica para guardar el video si es necesario
recordedVideoPath = "/path/to/simulated/video.mp4";
onVideoStopped?.Invoke(recordedVideoPath);
}
else
{
Debug.LogWarning("No se está grabando.");
}
}
public void SavePhotoToDefaultPath(Action<bool> onComplete)
{
if (currentPhoto != null)
{
NativeGallery.SaveImageToGallery(currentPhoto, "MyAppGallery", "Photo_{0}.png", (success, path) =>
{
if (success)
{
Debug.Log("Foto guardada en la ruta predeterminada: " + path);
onComplete?.Invoke(success);
}
else
{
Debug.LogError("Error al guardar la foto en la ruta predeterminada.");
onComplete?.Invoke(false);
}
});
}
else
{
Debug.LogWarning("No hay foto para guardar.");
onComplete?.Invoke(false);
}
}
public void SavePhotoToCustomPath(Action<bool> onComplete)
{
if (currentPhoto != null)
{
NativeGallery.Permission permission = NativeGallery.RequestPermission(NativeGallery.PermissionType.Write, NativeGallery.MediaType.Image);
if (permission == NativeGallery.Permission.Granted)
{
NativeGallery.SaveImageToGallery(currentPhoto, "MyAppGallery", "CustomPhoto_{0}.png", (success, path) =>
{
if (success)
{
Debug.Log("Foto guardada correctamente en la galería: " + path);
onComplete?.Invoke(true);
}
else
{
Debug.LogError("Error al guardar en la galería.");
onComplete?.Invoke(false);
}
});
}
else
{
Debug.LogError("Permiso denegado para guardar archivos.");
onComplete?.Invoke(false);
}
}
else
{
Debug.LogWarning("No hay foto para guardar.");
onComplete?.Invoke(false);
}
}
}
PreviewController.cs
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Video;
public class PreviewController : MonoBehaviour
{
public GameObject previewPanel;
public RawImage previewImage;
public VideoPlayer videoPlayer;
public CameraController cameraController;
public void ShowPhotoPreview(Texture2D photo)
{
previewPanel.SetActive(true);
videoPlayer.Stop();
videoPlayer.gameObject.SetActive(false);
previewImage.texture = photo;
previewImage.gameObject.SetActive(true);
}
public void ShowVideoPreview(string videoPath)
{
previewPanel.SetActive(true);
previewImage.gameObject.SetActive(false);
videoPlayer.url = videoPath;
videoPlayer.gameObject.SetActive(true);
videoPlayer.Play();
videoPlayer.loopPointReached += OnVideoEnd;
}
private void OnVideoEnd(VideoPlayer vp)
{
videoPlayer.Stop();
Debug.Log("El video ha terminado.");
}
public void OnConfirmButtonPressed()
{
previewPanel.SetActive(false);
videoPlayer.Stop();
cameraController.StartCamera();
}
public void OnCancelButtonPressed()
{
previewPanel.SetActive(false);
videoPlayer.Stop();
cameraController.StartCamera();
}
}
UIController.cs
using UnityEngine;
using UnityEngine.UI;
public class UIController : MonoBehaviour
{
public Button captureButton;
public Button recordButton;
public Button stopButton;
public Button saveDefaultPathButton;
public Button chooseSavePathButton;
public CameraController cameraController;
public PreviewController previewController;
private void Start()
{
captureButton.onClick.AddListener(OnCaptureButtonClicked);
recordButton.onClick.AddListener(OnRecordButtonClicked);
stopButton.onClick.AddListener(OnStopButtonClicked);
saveDefaultPathButton.onClick.AddListener(OnSaveDefaultPathButtonClicked);
chooseSavePathButton.onClick.AddListener(OnChooseSavePathButtonClicked);
stopButton.interactable = false;
}
public void OnCaptureButtonClicked()
{
cameraController.CapturePhoto(previewController.ShowPhotoPreview);
}
public void OnRecordButtonClicked()
{
cameraController.StartRecording();
recordButton.interactable = false;
stopButton.interactable = true;
}
public void OnStopButtonClicked()
{
cameraController.StopRecording(previewController.ShowVideoPreview);
recordButton.interactable = true;
stopButton.interactable = false;
}
public void OnSaveDefaultPathButtonClicked()
{
cameraController.SavePhotoToDefaultPath(success =>
{
Debug.Log(success ? "Foto guardada correctamente." : "Error al guardar la foto.");
});
}
public void OnChooseSavePathButtonClicked()
{
cameraController.SavePhotoToCustomPath(success =>
{
Debug.Log(success ? "Foto guardada en la ruta seleccionada." : "Error al guardar en la ruta.");
});
}
}
Canvas has attached the components:
- “UI Controller (Script)” (with Capture Button, Record Button, Stop Button, Save Default Path Button, Choose Sabe Path Button, Camera Controller and Preview Controller)
- and “Preview Controller (Script)” (Preview Panel, Preview Image, Video Player and Camera Controller)
Now, the problem is that, even if I try to build the scene in my Unity Project or my Android device, the RawImage doesnt works and the Camera doesnt starts.
Also, I have installed NativeCamera into the project to make sure all the Android Camera permissions works perfectly.
Am I doing something wrong? Also, If you see anything bad written or configured in this scripts or you need to check anything of my project, please leave a comment or message.
Thanks for your help! <3