SlideShare une entreprise Scribd logo
1  sur  22
Valerio “Lotti” Riva – Interactive Project
valerio.riva@gmail.com
@ValerioRiva
http://it.linkedin.com/in/valerioriva/
Avoid loss of hair while coding
Unity3D plugins for mobile
ROME 24 June 2014 – Valerio Riva
Codemotion Tech Meetup #4 – Roma Summer Edition
Nice to meet you!
• Web / Game developer
• Recent works @ Interactive Project
• World Cup Juggler
• OverVolt: crazy slot cars
ROME 24 June 2014 – Valerio Riva
2
Why develop a Unity3D mobile plugin?
• Access to device native features
• Implement third-party SDK (analytics, advertising,
in-app purchases, game services, etc.)
• Save/Earn money
• Personal growth
ROME 24 June 2014 – Valerio Riva
3
Extending Unity 4.x
• Unity supports C/C++ libraries. “extern”-alized
functions/methods can be called from C#
• All plugins must be placed inside “Assets/Plugins”
folder
• Platform-dependent plugins must be placed inside
specific folders (x86, x86_64, Android, iOS, WP8, Metro,
etc.)
• Available only on Unity3D Pro/Mobile
ROME 24 June 2014 – Valerio Riva
4
Extending Unity (iOS)
• Call externalized Object-C methods
• Must wraps third-party SDK if their methods are not
externalized
• Gameobjects can receive messages from native code
• Receiver methods declared on GO’s components must
have only 1 string parameter as signature
ROME 24 June 2014 – Valerio Riva
5
Extending Unity (Android)
• Use JNI (Java Native Interface), Unity provides Helper
classes
• Call native methods directly from Unity
• Gameobjects can receive messages from native code
• Receiver methods declared on GO’s components must have
only 1 string parameter as signature
• On specific cases, Unity Player activity must be extended
• Android Manifest editing is often required
ROME 24 June 2014 – Valerio Riva
6
Extending Unity (WP8)
• Access native code directly from Unity
• Use of callbacks to return data from native code
• Unity’s Mono (v2.6) doesn’t support .NET >= 4.0
• Artefacts are needed to use .NET >= 4.0 libaries
• “Always” needs a fake and a real plugin – Unity will
overwrite fake one with the real one automatically
• In specific cases, write a plugin is a monkey job
ROME 24 June 2014 – Valerio Riva
7
Extending Unity (remarks)
• Scripting define symbols are your friends
• Native calls are CPU intensive
• Provide fake results for in-editor usage
• Every native UI call must run inside native UI thread
• Every callback must run inside Unity thread (WP8)
• Save time by testing plugin on a native app
• Remember to include Unity library if needed
• classes.jar
• UnityEngine.dll
ROME 24 June 2014 – Valerio Riva
8
Case study: Flurry plugin
• Wrap Flurry SDK to made it accessible from Unity
• Flurry SDK is simple to use, just call static methods
(Advertising, In-App Purchase, …, are more complex plugin)
• We have to code wrappers for each platform
• Place platforms SKDs on the right directories
• FlurryAnalytics-4.0.0.jar -> Plugins/Android/
• libFlurry_5.0.0.a -> Plugins/iOS/
• FlurryWP8SDK.dll -> Plugins/WP8/
• FlurryWP8SDK.dll -> Plugins/ (the WP8 fake one)
ROME 24 June 2014 – Valerio Riva
9
Flurry plugin (iOS)
• Flurry SDK is not “extern”-alized
• Dictionary<string, string> must be translated somewhat to
NSMutableDictionary
• Each KeyValuePair<string,string> are concatenated to form a single
string
ROME 24 June 2014 – Valerio Riva
10
//FlurryiOS.h - created by PRADA Hsiung on 13/3/8.
extern "C" {
void FlurryiOS_startSession(unsigned char* apiKey);
void FlurryiOS_setEventLoggingEnabled(BOOL bEnabled);
void FlurryiOS_logEventWithParameters(unsigned char* eventId,unsigned
char *parameters);
}
Flurry plugin (iOS)
// FlurryiOS.m - created by Faizan Naqvi on 1/10/13.
#import <stdio.h>
#include "Flurry.h" //Flurry SDK headers
void FlurryiOS_startSession(const char* apiKey) {
NSString *str = [NSString stringWithUTF8String:apiKey];
[Flurry startSession:str];
}
void FlurryiOS_setEventLoggingEnabled(BOOL bEnabled){
[Flurry setEventLoggingEnabled:bEnabled];
}
ROME 24 June 2014 – Valerio Riva
11
Flurry plugin (iOS)
void FlurryiOS_logEventWithParameters(const char* eventId,const char *parameters) {
NSString *params = [NSString stringWithUTF8String:parameters];
NSArray *arr = [params componentsSeparatedByString: @"n"];
NSMutableDictionary *pdict = [[[NSMutableDictionary alloc] init] autorelease];
for(int i=0;i < [arr count]; i++) {
NSString *str1 = [arr objectAtIndex:i];
NSRange range = [str1 rangeOfString:@"="];
if (range.location!=NSNotFound) {
NSString *key = [str1 substringToIndex:range.location];
NSString *val = [str1 substringFromIndex:range.location+1];
//NSLog(@"kv %@=%@n",key,val);
[pdict setObject:val forKey:key];
} }
if([pdict count]>0) {
[Flurry logEvent:[NSString stringWithUTF8String:eventId] withParameters:pdict timed:false];
} else FlurryiOS_logEvent(eventId);
}
ROME 24 June 2014 – Valerio Riva
12
Flurry plugin (iOS)
Meanwhile on Unity side…
#region FlurryiOS_Imports
[DllImport("__Internal", CharSet = CharSet.Ansi)]
private static extern void FlurryiOS_startSession([In, MarshalAs(UnmanagedType.LPStr)]string
apiKey);
[DllImport("__Internal")]
private static extern void FlurryiOS_setEventLoggingEnabled(bool bEnabled);
[DllImport("__Internal", CharSet = CharSet.Ansi)]
private static extern void FlurryiOS_logEventWithParameters([In,
MarshalAs(UnmanagedType.LPStr)]string evendId, [In,
MarshalAs(UnmanagedType.LPStr)]string parameters);
#endregion
ROME 24 June 2014 – Valerio Riva
13
Flurry plugin (WP8)
• Flurry SDK is compiled with .NET 4.5, import it and Unity will go
mad!
• We need the “fake & real” library approach, but…
• Using Flurry SDK doesn’t involve use of complex logic or complex
user defined classes…
• … we can use the downloaded FlurryWP8SDK.dll as “real”
• and code only the fake dll!
Yes, this is the particular case
where you can bring in monkeys!
ROME 24 June 2014 – Valerio Riva
14
Flurry plugin (WP8)
using FlurryWP8SDK.Models;
using System;
using System.Collections.Generic;
namespace FlurryWP8SDK.Models {
public enum Gender { Unknown = -1, Female = 0, Male = 1 }
public class Parameter {
public Parameter(string name, string value) {
Name = name;
Value = value;
}
public string Name { get; set; }
public string Value { get; set; }
}
}
namespace FlurryWP8SDK {
public sealed class Api {
private static Api instance = null;
public static Api Current { get { return instance; } }
public void DummyInitiator() {}
public static void EndSession() {}
public static void EndTimedEvent(string eventName) {}
public static void EndTimedEvent(string eventName, List<Parameter> parameters) {}
public static void LogEvent(string eventName) {}
public static void LogEvent(string eventName, List<Parameter> parameters, bool timed) {}
public static void SetAge(int age) {}
public static void SetGender(Gender gender) {}
public static void SetLocation(double latitude, double longitude, float accuracy) {}
public static void SetSessionContinueSeconds(int seconds) {}
public static void StartSession(string apiKey) {}
}
}
ROME 24 June 2014 – Valerio Riva
15
That was easy, now
give me peanuts!
Flurry plugin (Android)
• As said before, Flurry doesn’t involve complex logic…
• … so we save time and wrote plugin directly in Unity using JNI
Helper classes
ROME 24 June 2014 – Valerio Riva
16
public Flurry StartSession(string apiKey) {
#if !UNITY_EDITOR && UNITY_WP8
Api.StartSession(apiKey);
#elif !UNITY_EDITOR && UNITY_ANDROID
using(AndroidJavaClass cls_UnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
using(AndroidJavaObject obj_Activity = cls_UnityPlayer.GetStatic<AndroidJavaObject>("currentActivity"))
using(AndroidJavaClass cls_FlurryAgent = new AndroidJavaClass("com.flurry.android.FlurryAgent")) {
cls_FlurryAgent.CallStatic("onStartSession", obj_Activity, apiKey);
}
#elif !UNITY_EDITOR && UNITY_IPHONE
FlurryiOS_startSession(apiKey);
#endif
return this;
}
Flurry plugin (Android)
ROME 24 June 2014 – Valerio Riva
17
public Flurry LogEvent(string eventId, Dictionary<string,string> parameters, bool timed) {
#if !UNITY_EDITOR && UNITY_WP8
List<Parameter> p = new List<Parameter>();
foreach(KeyValuePair<string,string> i in parameters) {
p.Add(new Parameter(i.Key,i.Value));
}
Api.LogEvent(eventId, p, timed);
#elif !UNITY_EDITOR && UNITY_ANDROID
using(AndroidJavaObject obj_HashMap = new AndroidJavaObject("java.util.HashMap")) {
// Call 'put' via the JNI instead of using helper classes to avoid: "JNI: Init'd AndroidJavaObject with null ptr!"
IntPtr method_Put = AndroidJNIHelper.GetMethodID(obj_HashMap.GetRawClass(), "put“,
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
object[] args = new object[2];
foreach(KeyValuePair<string, string> kvp in parameters) {
using(AndroidJavaObject k = new AndroidJavaObject("java.lang.String", kvp.Key))
using(AndroidJavaObject v = new AndroidJavaObject("java.lang.String", kvp.Value)) {
args[0] = k;
args[1] = v;
AndroidJNI.CallObjectMethod(obj_HashMap.GetRawObject(), method_Put, AndroidJNIHelper.CreateJNIArgArray(args));
}
}
cls_FlurryAgent.CallStatic("logEvent", eventId, obj_HashMap, timed);
}
#elif !UNITY_EDITOR && UNITY_IPHONE
FlurryiOS_logEventWithParametersTimed(eventId, dictionaryToText(parameters));
#endif
return this;
}
and for more complex plugins…?
• Do most of logic on native side to minimize native calls from Unity
• Messages examples (Android)
UnityPlayer.UnitySendMessage("gameObjectName", "methodName", "message");
• Use “Action<…>” delegates to pass callbacks on WP8, Unity supports
Action with max 4 parameters as .NET 3.5 does
• Structure plugin as a wrapper (mainly for third-party SDKs)
• Hide user defined classes (e.g.: instantiate them with methods) so Unity can’t see
them
• Wrap API calls with ones that use just primitive or built-in data type and the convert
them to user defined classes inside plugin!
ROME 24 June 2014 – Valerio Riva
18
Run on UI Thread
• iOS
dispatch_async(dispatch_get_main_queue(), ^{
// Your code to run on the main queue/thread
});
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// Your code to run on the main queue/thread
}];
• Android
UnityPlayer.currentActivity.runOnUiThread(new Runnable() {
public void run() {
//your code to run on the UI thread
}
});
ROME 24 June 2014 – Valerio Riva
19
Run on UI Thread (WP8)
• MainPage.xaml.cs
public partial class MainPage : PhoneApplicationPage
{
public void InvokeOnAppThread ( Action callback ) {
UnityApp.BeginInvoke ( () => { callback (); } );
}
public void InvokeOnUIThread ( Action callback ) {
Dispatcher.BeginInvoke ( () => { callback (); } );
}
private void Unity_Loaded() {
…
MyDispatcher.InvokeOnAppThread = InvokeOnAppThread;
MyDispatcher.InvokeOnUIThread = InvokeOnUIThread;
…
}
}
• MyPlugin.cs
MyDispatcher.InvokeOnAppThread(() => {
//your Unity callbacks execution must be placed here
});
MyDispatcher.InvokeOnUIThread(() => {
//your code to run on UI Thread
});
ROME 24 June 2014 – Valerio Riva
20
Resources and examples
Resources
• http://docs.unity3d.com/Manual/Plugins.html
• http://docs.unity3d.com/Manual/wp8-plugins.html
• http://docs.unity3d.com/Manual/PluginsForAndroid.html
• http://docs.unity3d.com/Manual/PluginsForIOS.html
Examples
• https://github.com/playgameservices/play-games-plugin-for-unity
• https://github.com/googleads/googleads-mobile-
plugins/tree/master/unity
• https://github.com/guillermocalvo/admob-unity-plugin
• https://github.com/mikito/unity-admob-plugin
• https://github.com/bearprada/flurry-unity-plugin
• https://github.com/mikito/unity-flurry-plugin
• https://github.com/faizann/unity3d_flurry
ROME 24 June 2014 – Valerio Riva
21
Thank you!
ROME 24 June 2014 – Valerio Riva
22
Question Time
No animals were harmed in the making of this talk
valerio.riva@gmail.com
@ValerioRiva
http://it.linkedin.com/in/valerioriva/

Contenu connexe

Tendances

Exploring Your Apple M1 devices with Open Source Tools
Exploring Your Apple M1 devices with Open Source ToolsExploring Your Apple M1 devices with Open Source Tools
Exploring Your Apple M1 devices with Open Source ToolsKoan-Sin Tan
 
Using the Android Native Development Kit (NDK)
Using the Android Native Development Kit (NDK)Using the Android Native Development Kit (NDK)
Using the Android Native Development Kit (NDK)Xavier Hallade
 
One bite and all your dreams will come true: Analyzing and Attacking Apple Ke...
One bite and all your dreams will come true: Analyzing and Attacking Apple Ke...One bite and all your dreams will come true: Analyzing and Attacking Apple Ke...
One bite and all your dreams will come true: Analyzing and Attacking Apple Ke...Priyanka Aash
 
Android Platform Debugging and Development
Android Platform Debugging and DevelopmentAndroid Platform Debugging and Development
Android Platform Debugging and DevelopmentOpersys inc.
 
Android Platform Debugging and Development
Android Platform Debugging and DevelopmentAndroid Platform Debugging and Development
Android Platform Debugging and DevelopmentOpersys inc.
 
Embedded Android Workshop with Marshmallow
Embedded Android Workshop with MarshmallowEmbedded Android Workshop with Marshmallow
Embedded Android Workshop with MarshmallowOpersys inc.
 
Android Platform Debugging and Development
Android Platform Debugging and DevelopmentAndroid Platform Debugging and Development
Android Platform Debugging and DevelopmentOpersys inc.
 
Standalone Android Apps in Python
Standalone Android Apps in PythonStandalone Android Apps in Python
Standalone Android Apps in PythonBaptiste Lagarde
 
J2me Crash Course
J2me Crash CourseJ2me Crash Course
J2me Crash Courseguest860a03
 
Android Platform Debugging and Development
Android Platform Debugging and DevelopmentAndroid Platform Debugging and Development
Android Platform Debugging and DevelopmentOpersys inc.
 
Embedded Android Workshop
Embedded Android WorkshopEmbedded Android Workshop
Embedded Android WorkshopOpersys inc.
 
Developing Android Platform Tools
Developing Android Platform ToolsDeveloping Android Platform Tools
Developing Android Platform ToolsOpersys inc.
 
Exploring Thermal Related Stuff in iDevices using Open-Source Tool
Exploring Thermal Related Stuff in iDevices using Open-Source ToolExploring Thermal Related Stuff in iDevices using Open-Source Tool
Exploring Thermal Related Stuff in iDevices using Open-Source ToolKoan-Sin Tan
 
Android Platform Debugging and Development
Android Platform Debugging and DevelopmentAndroid Platform Debugging and Development
Android Platform Debugging and DevelopmentKarim Yaghmour
 
Embedded Android Workshop with Marshmallow
Embedded Android Workshop with MarshmallowEmbedded Android Workshop with Marshmallow
Embedded Android Workshop with MarshmallowKarim Yaghmour
 
Going native with less coupling: Dependency Injection in C++
Going native with less coupling: Dependency Injection in C++Going native with less coupling: Dependency Injection in C++
Going native with less coupling: Dependency Injection in C++Daniele Pallastrelli
 

Tendances (20)

Exploring Your Apple M1 devices with Open Source Tools
Exploring Your Apple M1 devices with Open Source ToolsExploring Your Apple M1 devices with Open Source Tools
Exploring Your Apple M1 devices with Open Source Tools
 
Using the Android Native Development Kit (NDK)
Using the Android Native Development Kit (NDK)Using the Android Native Development Kit (NDK)
Using the Android Native Development Kit (NDK)
 
Kivy for you
Kivy for youKivy for you
Kivy for you
 
NDK Introduction
NDK IntroductionNDK Introduction
NDK Introduction
 
One bite and all your dreams will come true: Analyzing and Attacking Apple Ke...
One bite and all your dreams will come true: Analyzing and Attacking Apple Ke...One bite and all your dreams will come true: Analyzing and Attacking Apple Ke...
One bite and all your dreams will come true: Analyzing and Attacking Apple Ke...
 
Android Platform Debugging and Development
Android Platform Debugging and DevelopmentAndroid Platform Debugging and Development
Android Platform Debugging and Development
 
Android Platform Debugging and Development
Android Platform Debugging and DevelopmentAndroid Platform Debugging and Development
Android Platform Debugging and Development
 
Embedded Android Workshop with Marshmallow
Embedded Android Workshop with MarshmallowEmbedded Android Workshop with Marshmallow
Embedded Android Workshop with Marshmallow
 
Kivy report
Kivy reportKivy report
Kivy report
 
Android Platform Debugging and Development
Android Platform Debugging and DevelopmentAndroid Platform Debugging and Development
Android Platform Debugging and Development
 
Standalone Android Apps in Python
Standalone Android Apps in PythonStandalone Android Apps in Python
Standalone Android Apps in Python
 
J2me Crash Course
J2me Crash CourseJ2me Crash Course
J2me Crash Course
 
Android Platform Debugging and Development
Android Platform Debugging and DevelopmentAndroid Platform Debugging and Development
Android Platform Debugging and Development
 
Embedded Android Workshop
Embedded Android WorkshopEmbedded Android Workshop
Embedded Android Workshop
 
Developing Android Platform Tools
Developing Android Platform ToolsDeveloping Android Platform Tools
Developing Android Platform Tools
 
Android NDK
Android NDKAndroid NDK
Android NDK
 
Exploring Thermal Related Stuff in iDevices using Open-Source Tool
Exploring Thermal Related Stuff in iDevices using Open-Source ToolExploring Thermal Related Stuff in iDevices using Open-Source Tool
Exploring Thermal Related Stuff in iDevices using Open-Source Tool
 
Android Platform Debugging and Development
Android Platform Debugging and DevelopmentAndroid Platform Debugging and Development
Android Platform Debugging and Development
 
Embedded Android Workshop with Marshmallow
Embedded Android Workshop with MarshmallowEmbedded Android Workshop with Marshmallow
Embedded Android Workshop with Marshmallow
 
Going native with less coupling: Dependency Injection in C++
Going native with less coupling: Dependency Injection in C++Going native with less coupling: Dependency Injection in C++
Going native with less coupling: Dependency Injection in C++
 

Similaire à Avoid loss of hair while coding Unity3D plugin for mobile

Python Flask app deployed to OPenShift using Wercker CI
Python Flask app deployed to OPenShift using Wercker CIPython Flask app deployed to OPenShift using Wercker CI
Python Flask app deployed to OPenShift using Wercker CIBruno Rocha
 
Cross platform mobile apps using .NET
Cross platform mobile apps using .NETCross platform mobile apps using .NET
Cross platform mobile apps using .NETJonas Follesø
 
NSC #2 - D2 03 - Nicolas Collignon - Google Apps Engine Security
NSC #2 - D2 03 - Nicolas Collignon - Google Apps Engine SecurityNSC #2 - D2 03 - Nicolas Collignon - Google Apps Engine Security
NSC #2 - D2 03 - Nicolas Collignon - Google Apps Engine SecurityNoSuchCon
 
Web automation with #d8rules (European Drupal Days 2015)
Web automation with #d8rules (European Drupal Days 2015)Web automation with #d8rules (European Drupal Days 2015)
Web automation with #d8rules (European Drupal Days 2015)Eugenio Minardi
 
Serial Killer - Silently Pwning your Java Endpoints // OWASP BeNeLux Day 2016
Serial Killer - Silently Pwning your Java Endpoints // OWASP BeNeLux Day 2016Serial Killer - Silently Pwning your Java Endpoints // OWASP BeNeLux Day 2016
Serial Killer - Silently Pwning your Java Endpoints // OWASP BeNeLux Day 2016Christian Schneider
 
Appium Overview - by Daniel Puterman
Appium Overview - by Daniel PutermanAppium Overview - by Daniel Puterman
Appium Overview - by Daniel PutermanApplitools
 
EuroPython 2014 - How we switched our 800+ projects from Apache to uWSGI
EuroPython 2014 - How we switched our 800+ projects from Apache to uWSGIEuroPython 2014 - How we switched our 800+ projects from Apache to uWSGI
EuroPython 2014 - How we switched our 800+ projects from Apache to uWSGIMax Tepkeev
 
RichFaces - Testing on Mobile Devices
RichFaces - Testing on Mobile DevicesRichFaces - Testing on Mobile Devices
RichFaces - Testing on Mobile DevicesPavol Pitoňák
 
Porting your favourite cmdline tool to Android
Porting your favourite cmdline tool to AndroidPorting your favourite cmdline tool to Android
Porting your favourite cmdline tool to AndroidVlatko Kosturjak
 
Rapid Prototyping Chatter with a PHP/Hack Canvas App on Heroku
Rapid Prototyping Chatter with a PHP/Hack Canvas App on HerokuRapid Prototyping Chatter with a PHP/Hack Canvas App on Heroku
Rapid Prototyping Chatter with a PHP/Hack Canvas App on HerokuSalesforce Developers
 
Setting Apple's UI Automation Free with Appium
Setting Apple's UI Automation Free with AppiumSetting Apple's UI Automation Free with Appium
Setting Apple's UI Automation Free with Appiummobiletestsummit
 
Custom Buildpacks and Data Services
Custom Buildpacks and Data ServicesCustom Buildpacks and Data Services
Custom Buildpacks and Data ServicesTom Kranz
 
Create a-strong-two-factors-authentication-device-for-less-than-chf-100
Create a-strong-two-factors-authentication-device-for-less-than-chf-100Create a-strong-two-factors-authentication-device-for-less-than-chf-100
Create a-strong-two-factors-authentication-device-for-less-than-chf-100Cyber Security Alliance
 
Native Javascript apps with Phonegap - De Keijzer
Native Javascript apps with Phonegap - De KeijzerNative Javascript apps with Phonegap - De Keijzer
Native Javascript apps with Phonegap - De KeijzerCodemotion
 
Native Javascript apps with PhoneGap 11-04-2014 Codemotion Rome
Native Javascript apps with PhoneGap 11-04-2014 Codemotion RomeNative Javascript apps with PhoneGap 11-04-2014 Codemotion Rome
Native Javascript apps with PhoneGap 11-04-2014 Codemotion RomeMartin de Keijzer
 
Flutter Forward EXTENDED - Flutter로 앱 개발 입문하기
Flutter Forward EXTENDED -  Flutter로 앱 개발 입문하기Flutter Forward EXTENDED -  Flutter로 앱 개발 입문하기
Flutter Forward EXTENDED - Flutter로 앱 개발 입문하기SuJang Yang
 
Next Generation Memory Forensics
Next Generation Memory ForensicsNext Generation Memory Forensics
Next Generation Memory ForensicsAndrew Case
 

Similaire à Avoid loss of hair while coding Unity3D plugin for mobile (20)

Python Flask app deployed to OPenShift using Wercker CI
Python Flask app deployed to OPenShift using Wercker CIPython Flask app deployed to OPenShift using Wercker CI
Python Flask app deployed to OPenShift using Wercker CI
 
Cross platform mobile apps using .NET
Cross platform mobile apps using .NETCross platform mobile apps using .NET
Cross platform mobile apps using .NET
 
NSC #2 - D2 03 - Nicolas Collignon - Google Apps Engine Security
NSC #2 - D2 03 - Nicolas Collignon - Google Apps Engine SecurityNSC #2 - D2 03 - Nicolas Collignon - Google Apps Engine Security
NSC #2 - D2 03 - Nicolas Collignon - Google Apps Engine Security
 
Web automation with #d8rules (European Drupal Days 2015)
Web automation with #d8rules (European Drupal Days 2015)Web automation with #d8rules (European Drupal Days 2015)
Web automation with #d8rules (European Drupal Days 2015)
 
How to Build & Use OpenCL on OpenCV & Android NDK
How to Build & Use OpenCL on OpenCV & Android NDKHow to Build & Use OpenCL on OpenCV & Android NDK
How to Build & Use OpenCL on OpenCV & Android NDK
 
Serial Killer - Silently Pwning your Java Endpoints // OWASP BeNeLux Day 2016
Serial Killer - Silently Pwning your Java Endpoints // OWASP BeNeLux Day 2016Serial Killer - Silently Pwning your Java Endpoints // OWASP BeNeLux Day 2016
Serial Killer - Silently Pwning your Java Endpoints // OWASP BeNeLux Day 2016
 
Appium Overview - by Daniel Puterman
Appium Overview - by Daniel PutermanAppium Overview - by Daniel Puterman
Appium Overview - by Daniel Puterman
 
EuroPython 2014 - How we switched our 800+ projects from Apache to uWSGI
EuroPython 2014 - How we switched our 800+ projects from Apache to uWSGIEuroPython 2014 - How we switched our 800+ projects from Apache to uWSGI
EuroPython 2014 - How we switched our 800+ projects from Apache to uWSGI
 
RichFaces - Testing on Mobile Devices
RichFaces - Testing on Mobile DevicesRichFaces - Testing on Mobile Devices
RichFaces - Testing on Mobile Devices
 
Porting your favourite cmdline tool to Android
Porting your favourite cmdline tool to AndroidPorting your favourite cmdline tool to Android
Porting your favourite cmdline tool to Android
 
Rapid Prototyping Chatter with a PHP/Hack Canvas App on Heroku
Rapid Prototyping Chatter with a PHP/Hack Canvas App on HerokuRapid Prototyping Chatter with a PHP/Hack Canvas App on Heroku
Rapid Prototyping Chatter with a PHP/Hack Canvas App on Heroku
 
Setting Apple's UI Automation Free with Appium
Setting Apple's UI Automation Free with AppiumSetting Apple's UI Automation Free with Appium
Setting Apple's UI Automation Free with Appium
 
Custom Buildpacks and Data Services
Custom Buildpacks and Data ServicesCustom Buildpacks and Data Services
Custom Buildpacks and Data Services
 
Create a-strong-two-factors-authentication-device-for-less-than-chf-100
Create a-strong-two-factors-authentication-device-for-less-than-chf-100Create a-strong-two-factors-authentication-device-for-less-than-chf-100
Create a-strong-two-factors-authentication-device-for-less-than-chf-100
 
Native Javascript apps with Phonegap - De Keijzer
Native Javascript apps with Phonegap - De KeijzerNative Javascript apps with Phonegap - De Keijzer
Native Javascript apps with Phonegap - De Keijzer
 
Native Javascript apps with PhoneGap 11-04-2014 Codemotion Rome
Native Javascript apps with PhoneGap 11-04-2014 Codemotion RomeNative Javascript apps with PhoneGap 11-04-2014 Codemotion Rome
Native Javascript apps with PhoneGap 11-04-2014 Codemotion Rome
 
Appenginejs (old presentation)
Appenginejs (old presentation)Appenginejs (old presentation)
Appenginejs (old presentation)
 
Flutter Forward EXTENDED - Flutter로 앱 개발 입문하기
Flutter Forward EXTENDED -  Flutter로 앱 개발 입문하기Flutter Forward EXTENDED -  Flutter로 앱 개발 입문하기
Flutter Forward EXTENDED - Flutter로 앱 개발 입문하기
 
Next Generation Memory Forensics
Next Generation Memory ForensicsNext Generation Memory Forensics
Next Generation Memory Forensics
 
Hexagonal architecture
Hexagonal architectureHexagonal architecture
Hexagonal architecture
 

Dernier

The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 

Dernier (20)

The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 

Avoid loss of hair while coding Unity3D plugin for mobile

  • 1. Valerio “Lotti” Riva – Interactive Project valerio.riva@gmail.com @ValerioRiva http://it.linkedin.com/in/valerioriva/ Avoid loss of hair while coding Unity3D plugins for mobile ROME 24 June 2014 – Valerio Riva Codemotion Tech Meetup #4 – Roma Summer Edition
  • 2. Nice to meet you! • Web / Game developer • Recent works @ Interactive Project • World Cup Juggler • OverVolt: crazy slot cars ROME 24 June 2014 – Valerio Riva 2
  • 3. Why develop a Unity3D mobile plugin? • Access to device native features • Implement third-party SDK (analytics, advertising, in-app purchases, game services, etc.) • Save/Earn money • Personal growth ROME 24 June 2014 – Valerio Riva 3
  • 4. Extending Unity 4.x • Unity supports C/C++ libraries. “extern”-alized functions/methods can be called from C# • All plugins must be placed inside “Assets/Plugins” folder • Platform-dependent plugins must be placed inside specific folders (x86, x86_64, Android, iOS, WP8, Metro, etc.) • Available only on Unity3D Pro/Mobile ROME 24 June 2014 – Valerio Riva 4
  • 5. Extending Unity (iOS) • Call externalized Object-C methods • Must wraps third-party SDK if their methods are not externalized • Gameobjects can receive messages from native code • Receiver methods declared on GO’s components must have only 1 string parameter as signature ROME 24 June 2014 – Valerio Riva 5
  • 6. Extending Unity (Android) • Use JNI (Java Native Interface), Unity provides Helper classes • Call native methods directly from Unity • Gameobjects can receive messages from native code • Receiver methods declared on GO’s components must have only 1 string parameter as signature • On specific cases, Unity Player activity must be extended • Android Manifest editing is often required ROME 24 June 2014 – Valerio Riva 6
  • 7. Extending Unity (WP8) • Access native code directly from Unity • Use of callbacks to return data from native code • Unity’s Mono (v2.6) doesn’t support .NET >= 4.0 • Artefacts are needed to use .NET >= 4.0 libaries • “Always” needs a fake and a real plugin – Unity will overwrite fake one with the real one automatically • In specific cases, write a plugin is a monkey job ROME 24 June 2014 – Valerio Riva 7
  • 8. Extending Unity (remarks) • Scripting define symbols are your friends • Native calls are CPU intensive • Provide fake results for in-editor usage • Every native UI call must run inside native UI thread • Every callback must run inside Unity thread (WP8) • Save time by testing plugin on a native app • Remember to include Unity library if needed • classes.jar • UnityEngine.dll ROME 24 June 2014 – Valerio Riva 8
  • 9. Case study: Flurry plugin • Wrap Flurry SDK to made it accessible from Unity • Flurry SDK is simple to use, just call static methods (Advertising, In-App Purchase, …, are more complex plugin) • We have to code wrappers for each platform • Place platforms SKDs on the right directories • FlurryAnalytics-4.0.0.jar -> Plugins/Android/ • libFlurry_5.0.0.a -> Plugins/iOS/ • FlurryWP8SDK.dll -> Plugins/WP8/ • FlurryWP8SDK.dll -> Plugins/ (the WP8 fake one) ROME 24 June 2014 – Valerio Riva 9
  • 10. Flurry plugin (iOS) • Flurry SDK is not “extern”-alized • Dictionary<string, string> must be translated somewhat to NSMutableDictionary • Each KeyValuePair<string,string> are concatenated to form a single string ROME 24 June 2014 – Valerio Riva 10 //FlurryiOS.h - created by PRADA Hsiung on 13/3/8. extern "C" { void FlurryiOS_startSession(unsigned char* apiKey); void FlurryiOS_setEventLoggingEnabled(BOOL bEnabled); void FlurryiOS_logEventWithParameters(unsigned char* eventId,unsigned char *parameters); }
  • 11. Flurry plugin (iOS) // FlurryiOS.m - created by Faizan Naqvi on 1/10/13. #import <stdio.h> #include "Flurry.h" //Flurry SDK headers void FlurryiOS_startSession(const char* apiKey) { NSString *str = [NSString stringWithUTF8String:apiKey]; [Flurry startSession:str]; } void FlurryiOS_setEventLoggingEnabled(BOOL bEnabled){ [Flurry setEventLoggingEnabled:bEnabled]; } ROME 24 June 2014 – Valerio Riva 11
  • 12. Flurry plugin (iOS) void FlurryiOS_logEventWithParameters(const char* eventId,const char *parameters) { NSString *params = [NSString stringWithUTF8String:parameters]; NSArray *arr = [params componentsSeparatedByString: @"n"]; NSMutableDictionary *pdict = [[[NSMutableDictionary alloc] init] autorelease]; for(int i=0;i < [arr count]; i++) { NSString *str1 = [arr objectAtIndex:i]; NSRange range = [str1 rangeOfString:@"="]; if (range.location!=NSNotFound) { NSString *key = [str1 substringToIndex:range.location]; NSString *val = [str1 substringFromIndex:range.location+1]; //NSLog(@"kv %@=%@n",key,val); [pdict setObject:val forKey:key]; } } if([pdict count]>0) { [Flurry logEvent:[NSString stringWithUTF8String:eventId] withParameters:pdict timed:false]; } else FlurryiOS_logEvent(eventId); } ROME 24 June 2014 – Valerio Riva 12
  • 13. Flurry plugin (iOS) Meanwhile on Unity side… #region FlurryiOS_Imports [DllImport("__Internal", CharSet = CharSet.Ansi)] private static extern void FlurryiOS_startSession([In, MarshalAs(UnmanagedType.LPStr)]string apiKey); [DllImport("__Internal")] private static extern void FlurryiOS_setEventLoggingEnabled(bool bEnabled); [DllImport("__Internal", CharSet = CharSet.Ansi)] private static extern void FlurryiOS_logEventWithParameters([In, MarshalAs(UnmanagedType.LPStr)]string evendId, [In, MarshalAs(UnmanagedType.LPStr)]string parameters); #endregion ROME 24 June 2014 – Valerio Riva 13
  • 14. Flurry plugin (WP8) • Flurry SDK is compiled with .NET 4.5, import it and Unity will go mad! • We need the “fake & real” library approach, but… • Using Flurry SDK doesn’t involve use of complex logic or complex user defined classes… • … we can use the downloaded FlurryWP8SDK.dll as “real” • and code only the fake dll! Yes, this is the particular case where you can bring in monkeys! ROME 24 June 2014 – Valerio Riva 14
  • 15. Flurry plugin (WP8) using FlurryWP8SDK.Models; using System; using System.Collections.Generic; namespace FlurryWP8SDK.Models { public enum Gender { Unknown = -1, Female = 0, Male = 1 } public class Parameter { public Parameter(string name, string value) { Name = name; Value = value; } public string Name { get; set; } public string Value { get; set; } } } namespace FlurryWP8SDK { public sealed class Api { private static Api instance = null; public static Api Current { get { return instance; } } public void DummyInitiator() {} public static void EndSession() {} public static void EndTimedEvent(string eventName) {} public static void EndTimedEvent(string eventName, List<Parameter> parameters) {} public static void LogEvent(string eventName) {} public static void LogEvent(string eventName, List<Parameter> parameters, bool timed) {} public static void SetAge(int age) {} public static void SetGender(Gender gender) {} public static void SetLocation(double latitude, double longitude, float accuracy) {} public static void SetSessionContinueSeconds(int seconds) {} public static void StartSession(string apiKey) {} } } ROME 24 June 2014 – Valerio Riva 15 That was easy, now give me peanuts!
  • 16. Flurry plugin (Android) • As said before, Flurry doesn’t involve complex logic… • … so we save time and wrote plugin directly in Unity using JNI Helper classes ROME 24 June 2014 – Valerio Riva 16 public Flurry StartSession(string apiKey) { #if !UNITY_EDITOR && UNITY_WP8 Api.StartSession(apiKey); #elif !UNITY_EDITOR && UNITY_ANDROID using(AndroidJavaClass cls_UnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) using(AndroidJavaObject obj_Activity = cls_UnityPlayer.GetStatic<AndroidJavaObject>("currentActivity")) using(AndroidJavaClass cls_FlurryAgent = new AndroidJavaClass("com.flurry.android.FlurryAgent")) { cls_FlurryAgent.CallStatic("onStartSession", obj_Activity, apiKey); } #elif !UNITY_EDITOR && UNITY_IPHONE FlurryiOS_startSession(apiKey); #endif return this; }
  • 17. Flurry plugin (Android) ROME 24 June 2014 – Valerio Riva 17 public Flurry LogEvent(string eventId, Dictionary<string,string> parameters, bool timed) { #if !UNITY_EDITOR && UNITY_WP8 List<Parameter> p = new List<Parameter>(); foreach(KeyValuePair<string,string> i in parameters) { p.Add(new Parameter(i.Key,i.Value)); } Api.LogEvent(eventId, p, timed); #elif !UNITY_EDITOR && UNITY_ANDROID using(AndroidJavaObject obj_HashMap = new AndroidJavaObject("java.util.HashMap")) { // Call 'put' via the JNI instead of using helper classes to avoid: "JNI: Init'd AndroidJavaObject with null ptr!" IntPtr method_Put = AndroidJNIHelper.GetMethodID(obj_HashMap.GetRawClass(), "put“, "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); object[] args = new object[2]; foreach(KeyValuePair<string, string> kvp in parameters) { using(AndroidJavaObject k = new AndroidJavaObject("java.lang.String", kvp.Key)) using(AndroidJavaObject v = new AndroidJavaObject("java.lang.String", kvp.Value)) { args[0] = k; args[1] = v; AndroidJNI.CallObjectMethod(obj_HashMap.GetRawObject(), method_Put, AndroidJNIHelper.CreateJNIArgArray(args)); } } cls_FlurryAgent.CallStatic("logEvent", eventId, obj_HashMap, timed); } #elif !UNITY_EDITOR && UNITY_IPHONE FlurryiOS_logEventWithParametersTimed(eventId, dictionaryToText(parameters)); #endif return this; }
  • 18. and for more complex plugins…? • Do most of logic on native side to minimize native calls from Unity • Messages examples (Android) UnityPlayer.UnitySendMessage("gameObjectName", "methodName", "message"); • Use “Action<…>” delegates to pass callbacks on WP8, Unity supports Action with max 4 parameters as .NET 3.5 does • Structure plugin as a wrapper (mainly for third-party SDKs) • Hide user defined classes (e.g.: instantiate them with methods) so Unity can’t see them • Wrap API calls with ones that use just primitive or built-in data type and the convert them to user defined classes inside plugin! ROME 24 June 2014 – Valerio Riva 18
  • 19. Run on UI Thread • iOS dispatch_async(dispatch_get_main_queue(), ^{ // Your code to run on the main queue/thread }); [[NSOperationQueue mainQueue] addOperationWithBlock:^{ // Your code to run on the main queue/thread }]; • Android UnityPlayer.currentActivity.runOnUiThread(new Runnable() { public void run() { //your code to run on the UI thread } }); ROME 24 June 2014 – Valerio Riva 19
  • 20. Run on UI Thread (WP8) • MainPage.xaml.cs public partial class MainPage : PhoneApplicationPage { public void InvokeOnAppThread ( Action callback ) { UnityApp.BeginInvoke ( () => { callback (); } ); } public void InvokeOnUIThread ( Action callback ) { Dispatcher.BeginInvoke ( () => { callback (); } ); } private void Unity_Loaded() { … MyDispatcher.InvokeOnAppThread = InvokeOnAppThread; MyDispatcher.InvokeOnUIThread = InvokeOnUIThread; … } } • MyPlugin.cs MyDispatcher.InvokeOnAppThread(() => { //your Unity callbacks execution must be placed here }); MyDispatcher.InvokeOnUIThread(() => { //your code to run on UI Thread }); ROME 24 June 2014 – Valerio Riva 20
  • 21. Resources and examples Resources • http://docs.unity3d.com/Manual/Plugins.html • http://docs.unity3d.com/Manual/wp8-plugins.html • http://docs.unity3d.com/Manual/PluginsForAndroid.html • http://docs.unity3d.com/Manual/PluginsForIOS.html Examples • https://github.com/playgameservices/play-games-plugin-for-unity • https://github.com/googleads/googleads-mobile- plugins/tree/master/unity • https://github.com/guillermocalvo/admob-unity-plugin • https://github.com/mikito/unity-admob-plugin • https://github.com/bearprada/flurry-unity-plugin • https://github.com/mikito/unity-flurry-plugin • https://github.com/faizann/unity3d_flurry ROME 24 June 2014 – Valerio Riva 21
  • 22. Thank you! ROME 24 June 2014 – Valerio Riva 22 Question Time No animals were harmed in the making of this talk valerio.riva@gmail.com @ValerioRiva http://it.linkedin.com/in/valerioriva/