Unity 3D: Debugging with the Unity logfile when testing an APK file on an actual device

Normally, if you test your Unity game on your Android phone you are able to see the Unity debug logfile in the Android logcat with Eclipse.

Debug.Log("info");
Debug.LogWarning("warning");
Debug.LogError("error");

However, in case this is not working you can output the game’s logfile to a flat file. Do as follows:

  • Connect to the device using ADB.
  • Use the logcat command:
    adb logcat -d > mylogfile.txt

That will create a text file (mylogfile.txt) which should include any statements you logged (like „information“ from Debug.Log).

Unity 3D: Access GUIText object from script

  • Add a GUIText object to the scene:
    Component -> Rendering -> GUIText
    Give it a dummy value (for testing) like „xxxxx“ or something.
    You should see that object floating on top of the scene.
  • Create the script you want to use for the GUIText and put it to the scripts folder in your Unity project. Let’s say it’s called „ChangeVar.js“.
    The content of it can look something like this:

    public var resolutionText : GUIText;
    var i : int;function Start() {
    resolutionText.text = "Hey ya!";
    } 
  • In Unity select the GUIText. When it’s selected go to: Component -> Scripts -> „Change Var“ Now the script is attached to the GUIText as you can see it now in the Inspector part. It’s still not working at this point, though.
  • Drag the GUIText object from the Hierarchy and drop it in the Inspector area to „Resolution Text“.
  • From now on you can access that object from the script. If you launch it now with the player the value of the GUIText object will change from „xxxxx“ to „Hey ya!“.

Hope these instructions were helpful!

Android debugging: Force app to be installed on SD card

If you are working on a big application which uses a lot of memory you might get the error „No space left on device“ when trying to debug. With a Android Debug Bridge (ADB) command you can force the application to be installed on the SD card directly.

You have following options to chose when it comes to where the app shall be installed by default:

The setInstallLocation command changes the default install location
0 [auto]: Let system decide the best location
1 [internal]: Install on internal device storage
2 [external]: Install on external media

Do as described:

  1. Connect your phone to your computer via USB. Make sure it is in debug mode.
  2. Open Windows CMD Command (cmd.exe)
  3. Type following command if you want the default location to be your SD card:
    adb shell pm setInstallLocation 2
That’s about it. From now on when testing your app it will automatically be installed on the SD card instead of the internal memory.

Corona SDK: Get JSON data from the Internet

If you want to receive a parsed JSON string from the Internet in your Corona project do as in the following example:

Include JSON library

require "json"

Create the functions

Then create the functions which get the JSON string from the Internet.

local jsonFile = function( filename, base )

-- set default base dir if none specified
if not base then base = system.ResourceDirectory; end

-- create a file path for corona i/o
local path = system.pathForFile( filename, base )

-- will hold contents of file
local contents

-- io.open opens a file at path. returns nil if no file found
local file = io.open( path, "r" )
if file then
-- read all contents of file into a string
contents = file:read( "*a" )
io.close( file ) -- close the file after using it
end

return contents
end

local function networkListener( event )
if ( event.isError ) then
print( "Network error!")
else
print ( "RESPONSE: " .. event.response )
local t = json.decode( event.response )

-- Go through the array in a loop
for key in pairs(t) do
-- Here you can do whatever you like with the values
print(t[key]["returnvalue1"])
print(t[key]["returnvalue2"])
print(t[key]["returnvalue3"])
end

end
end

HTTP POST call

With the following lines of code you can call the above created functions to get data from the Internet.

postData = "parameter1=value1&parameter2=value2&parameter3=value3"

local params = {}
params.body = postData

local json_file_by_post = jsonFile( network.request( "http://www.yourserver.com/your_json_file.php", "POST", networkListener, params ) )

HTTP GET call

local json_file_by_get = jsonFile( network.request( "http://www.yourserver.com/your_json_file.php?parameter1=value1&parameter2=value2&parameter3=value3", "GET", networkListener ) )

Corona SDK: Center text horizontally

How to center text horizontally with Corona SDK:

local aboutText = display.newText("", 0, 0, native.systemFontBold, 13)
aboutText:setReferencePoint(display.CenterReferencePoint)
aboutText.x = display.contentWidth * 0.5
aboutText.y = display.contentHeight * 0.5 - 30<
aboutText:setTextColor(255, 255, 255)
aboutText.text = "Horizontal centered!"

How to convert an Activity class to use with FragmentPagerAdapter

This article shows how you have to alter your Activity classes to make them usable as Fragments for a horizontal slider.

You can find a tutorial how to create a smooth horizontal slider here:
Simple tutorial for a “smooth horizontal view slider” with Android

If you already have Activity classes and you want to combine them into one horizontal slider (FragmentPagerAdapter) you have to make some alterations in order to make it work. Here is how:

Let’s say you have following Activity classes in your project and want to combine them with a FragmentPagerAdapter:

  • MainArticle
  • AuthorInformation
  • CommentSection

First of all you change extends Activity to extends Fragment in those classes.

Before:

public class MainArticle extends Activity {...}

After:

public class MainArticle extends Fragment {...}

As with any Activity class there is the mandatory onCreate(…) method. Change this method to public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {…}.

Before:

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.outer_layout);
...
}

After:

private LinearLayout ll;
private FragmentActivity fa;

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

fa = super.getActivity();
ll = (LinearLayout) inflater.inflate(R.layout.outer_layout, container, false);
...

return ll;
}

The difference now is that we have to use the FragmentActivity object „fa“ and get the Activity from its parent class. Otherwise we won’t be able to access the Layout XML’s elements. You now also have to return a View object which should be your most outer element in the Layout XML file. In this example’s case it would be the LinearLayout called R.layout.outer_layout.

If you used an Intent object to pass variables to that view you will have to change the line of code from:

intent = getIntent();

to

fa = super.getActivity();
intent = fa.getIntent();

All the elements you are accessing from the XML Layout file can still be accessed. However, you have to alter the lines of code from

TextView myTextView = (TextView) findViewById(R.id.myTextView);

to

TextView myTextView = (TextView) ll.findViewById(R.id.myTextView);

Also if you have any Toast messages in that Activity you have to change the line of code to the following:

Toast.makeText(fa, message, Toast.LENGTH_LONG).show();

If you have any links which forward the user to another Activity you have to change the source parameter to „fa“. This will look like this:

Intent explicitIntent = new Intent(fa, AuthorInformation.class);
startActivity(explicitIntent);

Once you’ve done all that you can add those newly converted Fragment classes to the FragmentPagerAdapter class. If you have any questions feel free to use the comment section below.

Simple tutorial for a „smooth horizontal view slider“ with Android

Screenshot of a horizontal sliderSurely you have seen some Android apps which have this cool feature to scroll through different Views smoothly with a horizontal swipe. If you have some Views and you want them to be „slide-able“ you can do this quite easily actually.

Because this feature is not in Android 2.x you will need to use the compatibility pack from Android. It is a library with classes from Android 3. It is called „android-support-v13.jar“. You can download this JAR file from developer.android.com or just download the sample project from this site which also contains this JAR file.

Create a new project and add android-support-v13.jar to its build path. First we need a FragmentPagerAdapter. Create a class according to the code below:

MyPagerAdapter.java

public class MyPagerAdapter extends FragmentPagerAdapter {

private final List<Fragment> fragments;

/**
* @param fm
* @param fragments
*/
public MyPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}

/*
* (non-Javadoc)
*
* @see android.support.v4.app.FragmentPagerAdapter#getItem(int)
*/
@Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}

/*
* (non-Javadoc)
*
* @see android.support.v4.view.PagerAdapter#getCount()
*/
@Override
public int getCount() {
return this.fragments.size();
}
}

Next you have to create a class which handles the different Fragments (i.e. the separate „Views“). This class is going to be your Activity class.

ViewPagerFragmentActivity.java

public class ViewPagerFragmentActivity extends FragmentActivity {

private PagerAdapter mPagerAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.viewpager_layout);

// initialize the pager
this.initialisePaging();
}

/**
* Initialize the fragments to be paged
*/
private void initialisePaging() {

List<Fragment> fragments = new Vector<Fragment>();
fragments.add(Fragment.instantiate(this, Fragment0.class.getName()));
fragments.add(Fragment.instantiate(this, Fragment1.class.getName()));
fragments.add(Fragment.instantiate(this, Fragment2.class.getName()));
this.mPagerAdapter = new MyPagerAdapter(super.getSupportFragmentManager(), fragments);

ViewPager pager = (ViewPager) super.findViewById(R.id.viewpager);
pager.setAdapter(this.mPagerAdapter);
}
}

viewpager_layout.xml

<?xml version="1.0" encoding="utf-8"?>

<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/awesomepager">

</android.support.v4.view.ViewPager>

Eclipse will mark some errors. This is because the Fragment classes have not created yet. But this is what we are going to do right now. Create as many classes as you wish to have in your slider. In my example we use the classes Fragment0, Fragment1 and Fragment2. If you want to use any other classes make sure to include them in the code in the ViewPagerFragmentActivity.java class.

Fragment0.java, Fragment1.java, Fragment2.java

public class Fragment0 extends Fragment {
/**
* (non-Javadoc)
*
* @see android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater,
* android.view.ViewGroup, android.os.Bundle)
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return (LinearLayout) inflater.inflate(R.layout.fragment0_layout, container, false);
}
}

As for the XML Layouts you can design them however you like.

Lastly add the classes ViewPagerFragmentActivity, Fragment0, Fragment1 and Fragment2 to the manifest file.

That’s all. The app should work already allowing you to slide through the Fragment classes smoothly with a horizontal swipe.

If you’re lazy you can as well just download the whole demo project here:
HorizontalSmoothSliderExample

If you already have a FragmentPagerAdapter and want to use your already existing Activity classes als Fragments you can use my other tutorial here:
How to convert an Activity class to use with FragmentPagerAdapter

The start of my Android Tutorial Blog

I finally decided to start a blog where I save all my little Android tutorials I stumbled upon or searched hours online until I found a solution.

It’s going to be all simple and easy to understand tutorials that even I, myself can understand then again in a few months. And if I can understand it, then anyone will be able to understand it!

Hope this blog will be filled with a lot of useful information for you in the future!

« Vorherige Seite