Integrating devkitPro for native plugins in Unity 3DS

IMPORTANT!!!
This method currently only works in emulator, because it crashes on 3ds hardware. I am still looking into this issue so until I get it fixed you should probably hold off on doing this, unless you want to start writing a dkp plugin that may or may not be able to be used on an actual 3ds in the future... lol


As most of us know, Unity for 3DS is somewhat limited with quite a few features of the 3ds. This functionality can be expanded by using native plugins written in C or C++ that work as libraries to be used in your game.

More recently, I've found a way to write code using devkitpro and compiling it to be able to be used inside of Unity! And I would like to share it here as a basic tutorial to get started for those who are interested.

As of now I've only tried reading and writing to the SDMC, but this could potentially open the door to the many features of devkitpro and its homebrew libraries to use any low level 3DS service that isn't exposed in Unity. I think this could be a break through a barrier that has been a huge headache for devs using this engine for 3ds.

We will cover some of the essential dos and don'ts I've come across, workarounds for some stuff, and the general setup needed




What you need
  • devkitpro
  • devkitARM toolchain
  • Basic C/C++ and C# knowledge
  • Any text editor/IDE




Getting Started
  • The Unity 3DS linker uses 16-bit wide characters, but most Makefiles (that I've seen) use 32-bit characters by default. This causes an error when attempting to build the game
    • Before you compile your plugin code (this includes libctru as a whole if you use its objects!), you must add the following flag in your Makefile: -fshort-wchar
    • Example:
    • Makefile:
      CFLAGS    :=    -g -Wall -O2 -mword-relocations -fshort-wchar \
                  -ffunction-sections \
                  $(ARCH)
    • (As I mentioned, you will have to compile libctru with these flags as well if you will be using it)

  • Now, even with a successful compile of your plugin, the Unity linker will likely complain about missing internal symbols that it doesn't normally provide. So we must add them manually.
  • Examples:
    • void* __service_ptr = NULL; (This satisfies the environment handler)
    • If you're going to make use of strlen, you might need to define a local definition for it:
    • C:
      size_t strnlen(const char *s, size_t maxlen) {
          size_t i;
          for (i = 0; i < maxlen && s[i] != '\0'; i++);
          return i;
      }

  • Doing this, you can now compile your file
  • After making, head to the generated lib folder and drag the yourfilename.a file into your Plugins folder (Assets/Plugins/N3DS)
    • Don't forget! If you're using other compiled libraries like libctru you must compile it with 16-bit characters and also drag it into your project!



Implementing your plugin functionality to your Unity project

  • Once you have your plugin loaded into your project, create a new script or edit an existing one
  • Import System.Runtime.InteropServices
  • Use [DllImport("__Internal")]before statically linking a method from your plugin. Example:
    • C#:
      using System.Runtime.InteropServices;
      using UnityEngine;
      
      public class NativePlugin: MonoBehaviour {
          [DllImport("__Internal")]
          private static extern int MyNativeFunction();
      
          void Start() {
              MyNativeFunction();
              Debug.Log("Devkitpro plugin test");
          }
      }
    • [IMPORTANT] It is highly likely that running code using the plugin inside of the Editor will only result in an error on your debug console. To test your plugin, run it from an emulator or on your 3ds console instead

  • You are now able to build your game with new functionality by using your own native plugins with devkitpro! :yay3ds:


Example Project
This example plugin lets you write a file in your SD card

I will attach a ZIP file below that contains:
  • libctru compiled with 16-bit wide characters
  • An example plugin
    • Source file
    • Compiled .a
  • Makefile
  • And a C# script to get you started
Feel free to ask questions or give any suggestions for this below. This is all fairly new, and I have yet to try more of the features offered by devkitpro, as I'm still a bit new to it.
If you have any issues also feel free to comment here, I'll try to help as much as I can with my limited knowledge :yay:
 

Attachments

Last edited by CooingMaxito,
Na, me f

Limiting to what libctru can link ended in whatyou said. On Emulator it works but retail crashes with "undefined instruction" error, even before calling the plugin functions... The ctr sdk probably misses some stuff the regular hb playback has. Dang...
Yeah it kinda sucks haha, after a lot of troubleshooting I figured it probably just crashes when it attempts to recognize/load the plugin

It will 100% always crash as long as the plugin is present in the build, even if you never call it on a C# script lol
I might take another shot at fixing it soon, no promises though
 
  • Like
Reactions: Manurocker95
Yeah it kinda sucks haha, after a lot of troubleshooting I figured it probably just crashes when it attempts to recognize/load the plugin

It will 100% always crash as long as the plugin is present in the build, even if you never call it on a C# script lol
I might take another shot at fixing it soon, no promises though

Ping/mention me if you achieve it. That would be the only way to actually get the photo selector working as the SDK can't access the raw data of the pictures in the SD but only the path.
 
Ping/mention me if you achieve it. That would be the only way to actually get the photo selector working as the SDK can't access the raw data of the pictures in the SD but only the path.
Will do, hopefully I can come up with something
When I get it working, it can potentially open the door to so many things that aren't normally possible

Thanks for passing by, it's a nice reminder that I need to work on this hahahaha
 
Will do, hopefully I can come up with something
When I get it working, it can potentially open the door to so many things that aren't normally possible

Thanks for passing by, it's a nice reminder that I need to work on this hahahaha
In the meantime I will try to get the middleware working for augmented reality and speech + writing recognition. AR will probably fail bc Unity has 70% of the camera funcs stubbed but the other 2 might work.
 
  • Like
Reactions: I pwned U!
I made a plugin based on NativePlugin and SaveData example packages. I tested it on Citra and hardware (n3ds) and it works for me, but I could use someone else to confirm it.
In the zip there's a UnityPackage (5.6.6f2) with the plugin, an API for it, and an "example" folder with a scene and scripts that show how it can be used.
 

Attachments

Site & Scene News

Popular threads in this forum