CLI tool
yasirkula/UnityNativeCamera avatar
yasirkula/UnityNativeCamera

UnityNativeCamera hands your Unity app a file path, not a camera preview

A native Unity plugin to take pictures/record videos with device camera on Android & iOS

719 stars78 forksC#MIT

At a glance

What is it?
A C# Unity plugin that opens the native camera on Android and iOS, folds runtime permissions into the capture call, and returns the captured file path through a callback. The trade-off is that the capture screen belongs to the operating system, and several parameters are advisory.
Who is it for?
Adopt UnityNativeCamera when you are shipping an Android or iOS Unity title, you want the operating system's own capture screen, and a file path on disk is enough for your workflow. Skip it if the product needs a live preview inside the engine, a Windows or Linux player, or capture parameters that are guaranteed to hold on every device.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 29 days ago.
What is it written in?
Mainly C#, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the plugin actually replaces in a Unity project

Unity projects that need camera work on a phone usually pick one of two routes: keep everything inside the engine, or hand the job to the platform. UnityNativeCamera takes the second route. It is a C# plugin whose stated job is to take pictures and record videos natively with the device camera on Android and iOS, and the project is explicit that other platforms are not supported. Editor behaviour exists only so you can preview the flow, and it leans on Unity's Editor-only API, which the README links out to the Unity documentation.

That narrowness is the point. This is not a general media toolkit and it does not give you a live preview surface, a frame decoder, or a place to composite overlays in Unity. It hands the capture screen to the operating system and gives you back a path once the user returns. If your design calls for shaders running over live pixels or a custom in-game viewfinder, this is the wrong shape of tool, and no configuration flag will turn it into one.

Two static entry points and one asynchronous callback

The public surface is small: two static capture methods and a pair of guard calls. NativeCamera.TakePicture opens the camera, waits for the user to take a picture, and then invokes the CameraCallback you passed, on the main thread. The callback receives a string holding the path of the captured image, or null if the user cancelled the operation. The operation is asynchronous, so the rest of your code keeps running while the camera is open, and the callback is the only signal that an image exists.

NativeCamera.RecordVideo follows the same shape for video, taking a Quality value of Default, Low, Medium or High, an optional maxDuration in seconds, and an optional maxSizeBytes cap. Two guards are worth wiring into your UI before the first tap. NativeCamera.DeviceHasCamera returns false when the device has no camera, and in that case TakePicture and RecordVideo will not execute at all. NativeCamera.IsCameraBusy returns true while the camera is open, and a second capture request made at that moment is ignored rather than queued for later.

Runtime permissions are folded into the capture call

Both capture methods call NativeCamera.RequestPermissionAsync on your behalf, so the plugin does not hand you a silently broken camera on a locked-down device. The underlying reason is Android 6.0 Marshmallow, which turned service access into a runtime grant instead of a build-time manifest entry.

The same two calls are public if you want to check or prompt earlier, for example to disable a capture button until the user has agreed. NativeCamera.CheckPermission takes a bool that says whether you are checking for taking a picture or for recording video, and the isPicturePermission argument has no effect on iOS. NativeCamera.RequestPermissionAsync takes a PermissionCallback and the same bool, and returns the result asynchronously. The README recommends showing a short explanation before the system prompt appears, so that the user understands why the permission is needed and does not tap Deny or Don't ask again.

Five install routes, and the package metadata that lands in your project

The README lists five ways to install the plugin, so you can pick the one that matches how your project already handles dependencies. The quickest path for an existing Unity project is the NativeCamera.unitypackage asset from the releases page, brought in through Assets, Import Package. The second option is to clone or download the repository and move the Plugins folder into your Unity project's Assets folder. The third is the Asset Store listing, which the project maintains alongside the open source copy.

The Package Manager route installs straight from a git URL, which is the option to reach for when packages are tracked as text files in source control. For a scripted or CI environment, the project documents the OpenUPM route, which expects openupm-cli to be installed already; the command it gives is `openupm add com.yasirkula.nativecamera`.

Whichever route you take, the plugin ends up in your project as a Unity package with its own manifest, and that manifest is what tells the Package Manager the package name, the display name, and the version you pinned:

json
{
  "name": "com.yasirkula.nativecamera",
  "displayName": "Native Camera",
  "version": "1.5.2",
  "author": {
    "name": "yasirkula",
    "email": "[email protected]",
    "url": "https://github.com/yasirkula"
  },
  "documentationUrl": "https://github.com/yasirkula/UnityNativeCamera",
  "changelogUrl": "https://github.com/yasirkula/UnityNativeCamera/releases",
  "licensesUrl": "https://github.com/yasirkula/UnityNativeCamera/blob/master/LICENSE.txt",
  "description": "This plugin helps you take pictures/record videos natively with your device's camera on Android and iOS. It has built-in support for runtime permissions, as well."
}

After installation, Android needs no manual setup. The legacy manual setup page is kept only for reference. On iOS you either fill in the Camera Usage Description and Microphone Usage Description values in Project Settings under yasirkula and Native Camera, or you follow the manual setup wiki page.

The Android build error that traces back to two pinned toolchain versions

Android setup used to be the part of this plugin that cost people an afternoon, and the project now states that no manual setup is required there. The trouble has not vanished, it has moved into version alignment.

The build failure the FAQ leads with comes from the D8 dexer and reads "D8: java.lang.NullPointerException Failed to transform NativeCamera-.aar". The project's answer is that the plugin is using Gradle version 7.5.1 and Android Gradle plug-in version 7.4.2, and that your Unity version has to be compatible with those. If your project pins a different toolchain, the fix belongs in your Unity Android build settings rather than in the plugin itself.

A second Android failure shows up at runtime instead. If Logcat reports "java.lang.ClassNotFoundException: com.yasirkula.unity.NativeCamera" and the plugin really is up to date, the documented fix is to enable the Custom Proguard File option in Player Settings and keep the plugin's classes from being stripped.

ProGuard, the manifest override, and muted iOS audio

One Android runtime error is easy to misread as a plugin bug. If the functions return Permission.Denied even though the user has already granted the camera, the project asks you to declare WRITE_EXTERNAL_STORAGE manually in Plugins/Android/AndroidManifest.xml using a replace attribute, so your own declaration wins over the one the plugin merges in.

On iOS the setup choice is a pair of strings in the project settings. The automated route fills in the Camera Usage Description and Microphone Usage Description values under Project Settings, yasirkula, Native Camera, which saves hand-editing the plist for every build. The manual route is a wiki page.

There is one more iOS behaviour to plan around. The project keeps a forum thread for support, and one of the entries there covers audio coming out muted after a call to NativeCamera.RecordVideo. If a video pipeline ships with silent clips, that thread is the place the project points you to rather than an issue tracker.

Parameters that the device vendor can quietly ignore

Several parameters are best-effort, and the documentation is unusually direct about it. The PreferredCamera argument selects the rear or front camera by default, and the note says this only works if the device vendor has added that capability to the camera, with issue 126 cited as the running example. A handset with a single camera, or a multi-camera module without a usable front and rear switch, will ignore the choice without raising an error.

The same caveat covers video limits. maxDuration caps the recording in seconds and maxSizeBytes caps it in bytes, but the documentation says the behaviour of both depends on whether the device vendor added that capability, so a phone may record past your limit. maxSizeBytes has no effect on iOS at all. In the other direction, maxSize on TakePicture only scales the returned image on iOS, where a larger picture is downscaled for performance, and its default is SystemInfo.maxTextureSize. The saveAsJPEG option likewise has no effect on Android, so a JPEG versus PNG choice only matters on Apple devices.

A narrow release history and a permissive licence

Maintenance here is small in scope but current. The last push was on 2026-09-24, the same day release v1.5.2 was tagged, and the earlier tags are v1.5.1 from 2026-05-10 and v1.5.0 from 2025-04-07. The repository is not archived, and the top level holds a package.json carrying a version field alongside the Plugins folder and the licence file.

The licence is MIT, so the code itself carries no per-seat or per-title fee. The plugin is also published on the Asset Store, and that store purchase is a separate arrangement from the open source copy rather than a requirement for it.

The upgrade cost is therefore low in effort and low in risk for the code path itself: pinning a specific version is a matter of one number in package.json or a specific asset from the releases page. What actually costs time is the device matrix, since every vendor caveat in the parameter documentation can only be confirmed on real hardware.

Editorial conclusion

Adopt UnityNativeCamera when you are shipping an Android or iOS Unity title, you want the operating system's own capture screen, and a file path on disk is enough for your workflow. Skip it if the product needs a live preview inside the engine, a Windows or Linux player, or capture parameters that are guaranteed to hold on every device. Before you commit, test on real hardware that front and rear camera selection works on the phones you target, and confirm that your Unity version lines up with Gradle 7.5.1 and Android Gradle plug-in 7.4.2.

Frequently asked questions

Does UnityNativeCamera work in the Unity editor or on desktop platforms?

Only Android and iOS are supported. Editor functionality is for preview purposes and uses Unity's Editor-only API, so a Windows, macOS or Linux build gets no camera support from UnityNativeCamera.

How do I fix the D8 NullPointerException when building an Android Unity project with UnityNativeCamera?

The plugin uses Gradle version 7.5.1 and Android Gradle plug-in version 7.4.2, so the project states that your Unity version must be compatible with those versions.

How does UnityNativeCamera handle runtime permissions?

TakePicture and RecordVideo call NativeCamera.RequestPermissionAsync automatically. You can also call NativeCamera.CheckPermission and NativeCamera.RequestPermissionAsync yourself, and the isPicturePermission argument has no effect on iOS.

Is UnityNativeCamera still being updated?

The last push was on 2026-09-24, and release v1.5.2 was tagged on the same day. Earlier tags are v1.5.1 from 2026-05-10 and v1.5.0 from 2025-04-07.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. yasirkula/UnityNativeCamera on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/yasirkula-unitynativecamera.svg)](https://hysenlabs.com/projects/yasirkula-unitynativecamera)

Was this useful?