Posts Tagged ‘Android’

Reports from the field – Alien Apartment demo on more devices

On the 12th of April, I gave a very short presentation of my Alien Apartment demo (apk) to a local Android Developer meetup group.

One of the attendees was so kind as to grab the apk that very night and show me how it runs on some other devices. He demoed it running on the Samsung Galaxy Tab, and the Motorola Xoom. The excellent news is that the UI repositions as I’d expected. This was possibly the thing that worried me most, and I was gratified to see it went according to plan. The even better news is that the Galaxy Tab ran the demo so very incredibly smoothly. The animations were smooth as butter, and the controls were very responsive. The framerate felt almost as nice as the web player version. Furthermore, the larger screen size made the whole control scheme feel very nice and open. On my phone it can feel a little cramped, but not so on the larger screen. Performance on the Xoom seemed subjectively to be about 2/3 that of the Galaxy Tab, which is surprising given its raw statistics.

I’d like to thank Mike for letting me see the demo running on another device in-person, and if anyone else (whether you attended the meetup or not) has anything to report on how the demo runs on a device, please let me know.

Tags: , ,

1 Comment


An introduction to Unity3D for Android

We’re going to take a short break from the Seven Languages updates to talk about Unity 3D, as I’m working on a short demo project and would like to chronicle some of the early highlights as well as bumps in the road.

Unity 3D is an incredible tool geared solidly towards making 3D game content. For years Unity lived in obscurity, targeting its output strictly to the largely unheard of Unity Web player, a competitor to Flash that never really took off. Unity has always been interesting, but its reach was never truly compelling until recently. What’s changed? Unity now has the ability to compile projects to native applications that target iOS and Android in much the same way as Adobe’s CS5 can create native applications for iOS and Android that run swfs using the AIR packager.

Most of what I’ve done with Unity involves mashing together various different tutorials and making them behave in new and interesting ways. This is surprisingly easy to do. What’s slightly harder is making sure it all works when you’re ready to publish to an APK file. I’ll break this down a bit and highlight some of the things that can go wrong.

Certain standard library code won’t compile on Android. This is typically going to be code in JavaScript files, as JS allows and encourages dynamic object referencing while Android an iOS does not allow it in any form no matter the language you choose. For this reason alone I’d suggest to never use JS if developing for iOS or Android. Code that doesn’t generate any immediate errors as you’re writing it may be non-compilable. One such error was easy to find and fix:

Assets/Standard Assets/Scripts/DragRigidbody.js(31,22): BCE0019: ‘isKinematic’ is not a member of ‘UnityEngine.Component’. (Filename: Assets/Standard Assets/Scripts/DragRigidbody.js Line: 31)

I found the solution to the issue here

Other errors were more insidious. One in particular was evident in the Detonator demo buried in the example project on this page.

BCE0019: ‘size’ is not a member of ‘UnityEngine.Component’.
BCE0019: ‘detail’ is not a member of ‘UnityEngine.Component’.

If you look at the relevant code in light of the restriction against dynamic coding the problem is obvious.

var offsetSize = currentDetonator.GetComponent("Detonator").size / 3;
var hitPoint = hit.point + ((Vector3.Scale(hit.normal, Vector3(offsetSize,offsetSize,offsetSize))));
var exp : GameObject = Instantiate (currentDetonator, hitPoint, Quaternion.identity);
exp.GetComponent("Detonator").detail = detailLevel;
 
// currentDetonator.GetComponent returns GameObject.  
// GameObject does not have a .size or a .detailLevel.
// variable.

So you’d think this could be solved by just casting the return value of GetComponent into Detonator and we’ll be fine. Unfortunately there’s an entirely different problem when you do that…

BCE0018: The name “Detonator does not denote a valid type”

But why is this? Why would it suddenly be invalid on Android but not when compiling for the web player? That has to do with the order in which scripts are compiled. This link details some of the pitfalls that can be related to script compilation order. This particular issue was a result of the fact that the JS file was compiled *before* the Detonator and had no reference to the Detonator scripts. I could solve this by re-arranging the locations of the script files, or by re-writing the JS to be C#. I opted for the latter. This solved my problems.

Another issue I ran into, that was harder to diagnose, is that in one of my scenes I’d created a terrain, as I wanted to play with the terrain painting tools. Unfortunately, every time I tried to load the scene that had the terrain my apk would crash. This is because Terrains are unsupported on Android. This means that you won’t be using any of the pretty terrain painting tools if you’re targeting mobile.

Don’t let any of these things stop you from exploring Unity, however. These have been fairly minor setbacks, and the results of a successful compile are nothing short of incredible. Unity’s particular deal with the Devil is that it gains incredible ease of content creation for performance, but depending on how you look at it Unity might just have gotten one over on Lucifer. Performance may not be up to the level of C++ but it is definitely respectable, and the tools for creating and managing projects are truly amazing.

I’ll be sure to keep you posted as this progresses.

Tags: , , ,

12 Comments


Dude, where’s my R?

What has that Horseman fellow been up to these days? He sure was quiet there for the past few months. What manner of mischief has he been plotting?

The Horseman has been plotting a number of different things over the past few months, brushing up skills and diving into various new and different environments. The topic of the day is about a mystery I encountered in one of the aforementioned environments. “Dude, where’s my R?”

I can hear you asking “Wait, what is an R?” Excellent question! An “R” is an Object that you’ll find in the Land of Coffee and Robots, which is more commonly known as Android development and perhaps less commonly known as Androtopia. The Horseman is more a squire than a Knight in these realms, so he’s had plenty of opportunity to royally botch his courtly etiquette. That’s quite easy to do too, as the language spoken in the Land of Coffee and Robots is Java, and it is definitely a language of strict rigor. Here is an example of where a total noob might find his or herself off the beaten track by asking the wrong citizen of Androtopia directions.

In the world of Android development, “R” is an object that contains a set of resources. These resources come, from among other places, a batch of .xml configuration files that you as the developer create and maintain. They store information about such things as screen layouts, and objects that are available to a particular screen of an application. Handy stuff! But what happens when you can’t find it and you know you wrote it?

The Androtopian atlas I’ve consulted is the Wrox Professional Android 2 Application Development book, so chosen due to the publication date and the relatively recent version of the OS covered. The tome instructs you in the mundane art of downloading Eclipse, and the arcane art of setting it up to develop Android applications. We’re going to skip ahead a bit to Chapter 5 by which time we’ve created many .xml files and should have a reasonably good feel for this whole R business.

Here’s the resource file I created, called “listitemlayout.xml”:

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent"
	>
<TextView
	android:id="@+id/itemTextView"
	android:layout_width = "fill_parent"
	android:layout_height = "wrap_content"
	android:padding = "10px"
	android:textSize = "16px"
	android:textColor = "#FFF"
	/>
 
</LinearLayout>

And here is a Java class written to represent an “Activity” in the application that uses this resource (among others).

package com.scriptocalypse;
 
import android.R;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Contacts.People;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.AdapterView.OnItemClickListener;
 
public class ContactPicker extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        //R.layout.
        setContentView(R.layout.main);
 
        Intent intent = getIntent();
        String dataPathString = intent.getData().toString();
 
        final Uri data = Uri.parse(dataPathString + "people/");
        final Cursor c = managedQuery(data, null, null, null, null);
 
        String[] from = new String[] {People.NAME};
        int[] to = new int[] {R.id.itemTextView};
 
        SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.listitemlayout, c, from, to);
 
        ListView lView = (ListView) findViewById(R.id.contactListView);
        lView.setAdapter(adapter);
 
        lView.setOnItemClickListener(new OnItemClickListener() {
        	@Override
        	public void onItemClick(AdapterView<?> parent, View view, int pos, long id){
        		c.moveToPosition(pos);
        		int rowId = c.getInt(c.getColumnIndexOrThrow("_id"));
        		Uri outUri = Uri.parse(data.toString() + rowId);
        		Intent outDataIntent = new Intent();
        		outDataIntent.setData(outUri);
        		setResult(Activity.RESULT_OK, outDataIntent);
        		finish();
        	}
        });
 
 
    }
}

There’s something desperately wrong with the above code. Can you pick it out? It might be tricky if you don’t know Java, or if you’re new to Androtopia. Even if you do know Java, this might trip you up as the code is all syntactically correct. Eclipse at least is helpful enough to point out that there are errors on all the lines in which we try to access R. So…

package com.scriptocalypse;
 
import android.R;  // <-- looks like we're importing android.R here...  Is that the problem?
import android.app.Activity;

So, imagine you’re walking down the road and you encounter what appears to be a fellow you’re looking for named “Roger”, and you ask him various questions about ids, contactListViews, and such. He simply doesn’t understand what you’re talking about. You begin to want to strangle him for his seemingly willful ignorance. Only much later do you realize that this is not the “Roger” you’re looking for. In fact, you don’t even need the import statement to access the “Roger” you’re looking for! After removing the import statement, the code compiles and works correctly.

“Well that was incredibly daffy of you Mr. Horseman, why did you import android.R if you didn’t need it?”

Ah, that’s the thing you see. I did not. There are many things I can say about the Eclipse IDE. In the interest of keeping the remaining entry expletive-free, I’ll simply say “Eclipse did it ‘automagically’ without my knowledge or consent, after somehow assuming that I wanted it.” Not knowing the lay of the land, and not being as familiar with the idioms of Androtopia and the strange customs of the Gremlins that live inside Eclipse, the import statements didn’t feel like an obvious place to look for a problem. It’s especially true since the statement to an untrained eye looks correct.

So let this be a lesson to intrepid explorers of new realms to be careful who one asks for directions, and to make doubly sure that there isn’t a Gremlin hiding in your code editor.

Tags: , , , , ,

No Comments