Category Archives: Unity3d

AndroidJavaException: java.lang.NoSuchMethodError: no static method

I’ve been working on updating my Unity3D Android plugins, and decided to make a new project to test them in.  On and off for the past few days I’ve been trying to nail down the reason for the following error:

AndroidJavaException: java.lang.NoSuchMethodError: no static method “Lcom/purplebuttons/unity/PBAndroidUtils;.PBInitAndroidUtils(Lcom.unity3d.player.UnityPlayerNativeActivity;Z)V”

I get this error when the plugin is initialized, and it looks like Unity can’t find my static method.  I checked my parameters, verified that the method name was correct, checked that the JAR was in my plugins/android folder.  Everything checked out, but I was still getting the error.

I rolled the plugin back to a version from another project I knew worked as intended.  No difference, same error.  Lots of google searching and still nothing obvious.  The most common cause is either the parameters not matching, an incorrect java class path, or a misspelled method name.  I had none of those.

So I duplicated a working project that called the plugin without any errors, and started stripping it back.  Removed lots of scripts, objects, images & sounds. Finally I started pairing down the plugins/android directory, and that’s when it happened – I found the error.

Turns out I needed to include the ‘google-play-services_lib’ in my plugins/android folder.  The plugin jar used various bits & bobs from this lib and without it included in the APK, the plugin would fail to load when called, and return the error above, which didn’t really explain what was going on.

When I created the test project, I didn’t think to copy that forward, and hence my wasted time…

Extending the Unity3D Color struct

I’m working on a convenience class that will allow me to specify the color used by an NGUI item by the SVG/HTML named color list (http://www.december.com/html/spec/colorsvg.html).

I was hoping I could extend the standard Unity3D Color class by adding a static method that could be used to update the color values, however as Color is a struct and not a class, you can’t update the value in an extension method as a copy is passed.

    public static void ColorWithName(this Color color,
     PBColor.ColorNames name)
    {
        color = PBColor.FromName(name);
    }

This will not work as expected.  The var color points to a copy of the calling color struct and not the actual struct, so any changes are discarded 🙁

I ended up with this:

    public static void ColorWithName(this UIWidget widget,
     PBColor.ColorNames name)
    {
        widget.color = PBColor.FromName(name);
    }

Not as convenient as I wanted, but it gets the job done as below:

    widget.ColorWithName(ColorNames.GoldenRod);

where widget is an NGUI.UIWidget object.

Unity 3D c# and lack of Tuple

Unfortunately the compiler used for Unity 3D does not support Tuples.  Tuples are a convenient way to lump a couple of types together into one object without creating a class.

So, if like me you needed a list to contain a string and a float for one entry, you could do so like this:

    public List<Tuple<string,float>> things;

Then you could access the parts of the item, add both parts at the same time, etc.

There are a bunch of class definitions available that will let you use something very similar to Tuple in Unity.  I didn’t want to go to that effort, so I ended up with using an ArrayList.  This will hold multiple objects of different types in a nice ordered array.

    public List<ArrayList> things;

Now each item in the list is an array and I can get at the contents using normal array syntax.

     ArrayList thing = things[0];
     label.text = thing[0as string;
     duration = (float)thing[1];

There’s no error checking here, but you get the basic idea.

Renaming c# classes and Unity…

As far as I know, there is no ‘correct’ way to rename a class that you’ve built inside a Unity C# file with ease and 0 pain…  but there is certainly a wrong way to do it:

Approach it in this order:

Rename the ????.cs file using the Unity Editor.  Click on the file in the project explorer and use what ever method you’d like to rename it to the new class name.  This means that Unity will keep a reference to the newly named file and any instances of that class file attached to objects in the scene will get updated.

Now, open the file in your text editor (Mono, VS, whatever) and use ‘Refactor or Rename’ on the actual class name and let the editor change all references in the project.  Save all the changed files and you should be able to build just fine.

Go back to Unity and the project should build and run without any errors.

If you do what I did – rename the class first in your text editor, then you’ll end up replacing every ‘missing script’ error by hand – not so much fun — you’ve been warned!

C# System.Func

I needed to create a hook into a class I’m working on that will return a GameObject for a given index.  Now, I could have just built that function into my class, but I’d rather make this class re-usable by other projects down the line (and even other classes within the same project).

public System.Func<int,Transform,TransformrowForRowIndex;

The first two parameters are passed to the function from the calling method, while the third is the returned object.  So in this case, I would invoke the function as follows:

row = rowForRowIndex(r,cachedRow);

Where, r is the index of the row I want to generate, and cachedRow is a row object that has been previously created but is free for use.

You can obviously use different parameters & return type than I am, just remember, the last entry is always the return type, so

public System.Func<bool> isValid;

will return a bool and takes no parameters, while

public System.Func<int,float> rootOfInt;

will return a float and take 1 int as a parameter.

You can also use lambdas to create in-line functions using this syntax:

public System.Func<int,float> rootOfInt = (x) => Mathf.Sqrt(x);

While this is similar to System.Action, the big difference is that System.Func can return a value, System.Action is always type Void.