Unity3D-Discard
<p>[TOC]</p>
<h2>1. Abstract</h2>
<p>Though MSLD native SDK(iOS/Android)provide full function for Unity game developer, it is not very convenient. In consideration of many game studio develop games using Unity, We provide the MSLD Unity SDK base on native SDK. The developer can conside the game logic of their games ohter than the SDK integration logic. It's easier for Integration.</p>
<h3>1.1 Feature of Unity SDK</h3>
<p>Unity SDK provides functions below based on native SDK:</p>
<ul>
<li>
<p><strong>Encapsulate Business API</strong>
Consider the flexibility of SDK, the native using the common parameter(key/Value) as the input. Developers must read the document to know what the key represent and what the value shold be seted. It's very inefficient. The Unity SDK provides the business API based on native SDK. By the API declaration, developers can clearly know what API should call and what parameter representd and what value should set. The document is needless.</p>
</li>
<li>
<p><strong>Encapsulate the communication progress between Native and Unity</strong>
Using Native SDK in Unity, you should implement the communication progress between Native code and Unity code. In actual fact the communication progress is not belong to the game logic but the Unity Engineer. The developers should not care about it. So the API Unity SDK provides encapsulate the details of communication progress. And developers needn't care about it and maintain it. </p>
</li>
<li><strong>Automatic config about platform</strong>
For platform access, it is often necessary to configure related to the platform. For example, adding Framework for iOS,adding compilation parameters etc. All of this is about platform not the game logic. The game developer should not care about it. The Unity SDK help to configure the platform base on Unity techlogy. It makes integration easier.</li>
</ul>
<p>All above, we highly recommend developers use the MSLD Unity SDK other than native SDK.</p>
<h3>1.2 Attention</h3>
<p><strong> Special attention: If the game developers are about to access is the type of online games (leisure games can be ignored), in order to login and pay security, the server access related interface is required. Specific access documents can be viewed <a href="https://www.showdoc.cc/mssdk?page_id=2647897962757260">MSSDK server access documents</a></strong></p>
<h2>2. Integrate Unity SDK</h2>
<h3>2.1 Get Unity SDK Package</h3>
<p>Please contact developers of MSLD.(jack.deng)</p>
<h4>Construction of Unity SDK</h4>
<p><img src="https://github.com/veryitman/MSSDKResource/blob/mark-feature/Unity3D/guide-main/guide_01.png?raw=trueg" alt="construction of Unity SDK" /></p>
<p><strong>Doc directory</strong>
This directory contains documents. The sub directory API contains the API document. Double click the index.html, it will show the contents.</p>
<p><strong>MSLDSDK.unitypackage</strong></p>
<p>This directory contains package of Unity MSLD SDK with iOS/Android native SDK and some config(config.json). </p>
<p><strong>MSLDSDKSample.unitypackage</strong></p>
<p>It shows how to call MSLD SDK Unity API to implement the business. Import this packgae can give your some guides.</p>
<h3>2.2 import MSLDSDK.unitypackage to Unity project</h3>
<p>Double click "MSLDSDK.unitypackage", you'll see the import interface. Click "import" to import all files.
<img src="https://github.com/veryitman/MSSDKResource/blob/mark-feature/Unity3D/guide-main/guide_02.png?raw=true" alt="import UnitySDK" /></p>
<h3>2.3 SDK Integrate</h3>
<h4>2.3.1 Apply SDK Config</h4>
<ul>
<li>Visit the <a href="http://biz.cloud.idreamsky.com">Business Service console</a>, Create APP. Fill the associated content.</li>
<li>Download the "msConfig.json" to the local path.
<img src="https://github.com/veryitman/MSSDKResource/blob/mark-feature/Unity3D/guide-main/guide_03.png?raw=true" alt="Download config" /></li>
</ul>
<h4>2.3.2 Conifg SDK</h4>
<h5>iOS Platform</h5>
<p>put the config file "msConfig.json" into the Unity project directory's sub directory "Assets/Plugins/iDreamsky/MSLD/iOS".</p>
<h5>Android platform</h5>
<p><strong>parameter config</strong></p>
<blockquote>
<p>put the downloaded "msConfig.json" file into directory "assets\msld\config" of <strong>Gradle project</strong></p>
</blockquote>
<p>**Integrate of platform</p>
<blockquote>
<p>First: export the Gradle Project from Unity Project whitch integrated MSLDSDK.unitypackage.
Second: Open the Gradle Project with AndroidStdio for configing
Third: Out Put Game.apk</p>
</blockquote>
<p><strong>Gradle Project config</strong></p>
<h6>config build.gradle</h6>
<pre><code class="language-xml"> implementation 'com.android.support:appcompat-v7:28.0.0'</code></pre>
<h6>config Androidmanifest.xml</h6>
<pre><code class="language-xml"> <application
android:name="com.ms.plugin.unity.MSUnityApplication"
>
<activity
android:name="com.ms.plugin.unity.MSLDUnityActivity"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application></code></pre>
<h4>2.3.3 Integrate public logic</h4>
<h4>2.3.3.1 Init SDK</h4>
<p>when Start the games, call "MSLDSDK.Init(APICallBack callback)" for init the SDK. the callback param is the result of init.</p>
<p>```C#
using iDreamsky.MSLD;
......</p>
<pre><code>void Start()
{
MSLDSDK.InitSDK(InitSDKCallBack);
......
}
......
void InitSDKCallBack(MSLDErrorCode code, string msg)
{
if (code == MSLDErrorCode.Success)
{
MSLDInfoWindow.Info("Init success!");
}
else
{
MSLDInfoWindow.Info("Init Failure! code = " + code + " msg = " + msg);
}
}</code></pre>
<pre><code>
##### 2.3.3.2 set the global callback observator
When some import things happened, SDK will tell it to Game. Game logic shold do somthing if needed.
After init SDK, we can set global as below:
```C#
using iDreamsky.MSLD;
......
void Start()
{
......
MSLDSDK.SetEventCallBack(OnSDKEventCallBack);
}
......
// Global callback
void OnSDKEventCallBack(MSLDSDK.Event eventID, object eventObj)
{
MSLDInfoWindow.Info("Global Event Callback eventId:" + eventID);
switch (eventID)
{
case MSLDSDK.Event.SwitchAccount:
// when SDK switch account, it will get this event
break;
case MSLDSDK.Event.LogOut:
// when SDK logout account, it will get this event
break;
case MSLDSDK.Event.RedeliveryOrder:
{
// when SDK get redelivery order,it will get this event
......
}
break;
}
}</code></pre>
<h2>3. Integrate features</h2>
<p>The game developer can integrate features according needed. For now, the MSLD SDK has features like account system, pay system.
<strong>Before you integrate the features, Please make sure finish section 2.3.3 whitch about public logic.</strong></p>
<h3>3.1 Integrate Account System</h3>
<p>All function about Account System provided are in class MSLDAccountManager. you should import the namespac before using it.</p>
<p>```C#
using iDeramsky.MSLD.Account;</p>
<pre><code>
#### 3.1.1 login Panel
call "MSLDAccountManager.ShowLoginPannel(APICallBack<MSLDAccount> callback)" can show the login panel.
```C#
using iDreamsky.MSLD;
using iDreamsky.MSLD.Account;
......
MSLDAccountManager.ShowLoginPannel((MSLDErrorCode code, string msg, MSLDAccount account) => {
if (code == MSLDErrorCode.Success)
{
MSLDInfoWindow.Info("Normal Login success! account:" + account.desc());
}
else if (code == MSLDErrorCode.UIUserClose)
{
MSLDInfoWindow.Info("Cancel Normal Login by user! code = " + code + " msg = " + msg);
}
else
{
MSLDInfoWindow.Info("Normal Login Failed! code:" + code + " msg:" + msg);
}
});</code></pre>
<h4>3.1.2 Guest Login</h4>
<p>call "MSLDAccountManager.GuestLogin(APICallBack<MSLDAccount> callback)" can start guest login flow.</p>
<p>```C#
MSLDAccountManager.GuestLogin((MSLDErrorCode code, string msg, MSLDAccount account) => {
if (code == MSLDErrorCode.Success)
{
MSLDInfoWindow.Info("Guest Login success! account:" + account.desc());
}
else if (code == MSLDErrorCode.UIUserClose)
{
MSLDInfoWindow.Info("Cancel Guest Login by user! code = " + code + " msg = " + msg);
}
else
{
MSLDInfoWindow.Info("Guest login Failed! code = " + code + " msg = " + msg);
}
});</p>
<pre><code>
#### 3.1.3 Auto Login
call "MSLDAccountManager.AutoLogin(APICallBack callback)" can start the auto login flow.
Auto Login will using the information of last login for current login action. If their's no last login information, auto login will failed. At this situation, you should give the user another way to login(such as show login panel).
```C#
using iDreamsky.MSLD;
using iDreamsky.MSLD.Account;
......
MSLDAccountManager.AutoLogin(OnAutoLoginCallBack);
......
/*
* auto login callback
*/
void OnAutoLoginCallBack(MSLDErrorCode code, string msg, MSLDAccount account)
{
if (code == MSLDErrorCode.Success)
{
MSLDInfoWindow.Info("Auto Login Success! account:" + account.desc());
}
else if (code == MSLDErrorCode.UIUserClose)
{
MSLDInfoWindow.Info("Cancel Auto Login by user! code = " + code + " msg = " + msg);
}
else
{
MSLDInfoWindow.Info("Auto Login Failed! code = " + code + " msg = " + msg);
}
}</code></pre>
<h4>3.1.4 user center</h4>
<p>call "MSLDAccountManager.ShowUserCenterPannel(APICallBack callback)" will show the usercenter panel.</p>
<p>```C#</p>
<p>using iDreamsky.MSLD;
using iDreamsky.MSLD.Account;
......</p>
<p>MSLDAccountManager.ShowUserCenterPannel(OnShowUserCenterPannelCallBack);
......</p>
<p>/*</p>
<ul>
<li>user center panel callback<br />
*/
void OnShowUserCenterPannelCallBack(MSLDErrorCode code, string msg, object data)
{
if (code == MSLDErrorCode.Success)
{
MSLDInfoWindow.Info("show user center panel success!");
}
else if (code == MSLDErrorCode.UIUserClose)
{
MSLDInfoWindow.Info("cancel by user! code = " + code + " msg = " + msg);
}
else
{
MSLDInfoWindow.Info("show user center panel action faied! code = " + code + " msg = " + msg);
}
}
<pre><code></code></pre></li>
</ul>
<h4>3.1.5 Real Name</h4>
<p>call "MSLDAccountManager.AuthenticationPanel(APICallBack callback)" will show real name panel.</p>
<p>```C#</p>
<p>using iDreamsky.MSLD;
using iDreamsky.MSLD.Account;
......</p>
<p>MSLDAccountManager.AuthenticationPanel(OnAuthenticationPanelCallBack);
......</p>
<p>/*</p>
<ul>
<li>real name panel callback
*/
void OnAuthenticationPanelCallBack(MSLDErrorCode code, string msg, object data)
{
if (code == MSLDErrorCode.Success)
{
MSLDInfoWindow.Info("real name success!");
}
else if (code == MSLDErrorCode.UIUserClose)
{
MSLDInfoWindow.Info("user cancel real name! code = " + code + " msg = " + msg);
}
else
{
MSLDInfoWindow.Info("real name failed! code = " + code + " msg = " + msg);
}
}
<pre><code></code></pre></li>
</ul>
<h4>3.1.6 get user informaton</h4>
<p>call "MSLDAccountManager.GetLoginedUserInfo()" will get the informaton of user.
when no user logined, it returns null, ohterwise return user info of current logined.</p>
<p>```C#
MSLDAccount account = MSLDAccountManager.GetLoginedUserInfo();
if (account != null)
{
MSLDInfoWindow.Info("user info: " + account.desc());
}
else
{
MSLDInfoWindow.Info("no user inofo ");
}</p>
<pre><code>### 3.2 Integrate Pay System
call "public static void PurchaseProduct(MSLDProduct product, MSLDCPInfo cpInfo, MSLDPayMethod payMethod, APICallBack<MSLDPayResult> callback)" will start the purchase flow.
**product**
parameter product contains product info. such as product Id, product type, product name, price, currency. All those info are input by this object.
you need to config the product in site [Business Service console](http://biz.cloud.idreamsky.com). After that you can get the product ID.

For plantform iOS, you should also vist the [apple develop site](https://developer.apple.com/) for config the product. The product ID should be configed as the same. The other infomation in object product, you can get those by calling "QueryProduct(string productID, APICallBack<MSLDProduct> callback)" . It get the information from apple service.
For platform Android, the infomation of product are config by game developers. A common implement is config by local file.
**cpInfo**
parameter cpInfo are information of content provider(CP). such as player id, order id of CP, mark, order title, extern info. All those info are input by this object for purchase.
**payMethod**
parameter payMethod are pay method.
For iOS, only apple pay supported.
For Android, pay panel, WeChat, Alipay are supported. You can choose by yourself.
**pay result**
For iOS, the pay normal result is in the callback info. but when pay flow be intrupped and be recoved next time, global call will receive event " MSLDSDK.Event.RedeliveryOrder", and can get the pay result.
For Android, all pay result are returned in global callback when received "MSLDSDK.Event.RedeliveryOrder" event.
Please make sure global callback are setted and deal with event "MSLDSDK.Event.RedeliveryOrder"
#### 3.2.1 purchase product
```C#
......
using iDreamsky.MSLD.Payment;
using iDreamsky.MSLD;
......
public MSLDProduct product;
public MSLDCPInfo cpInfo;
......
product = new MSLDProduct("0", "test01", "test proudct 1", "1.23", "yuan");
cpInfo = new MSLDCPInfo("pid1234", "mchNO123456", "cpDataxxxxx", "remarkXXXXX", "subjectXXXXX", "attachXXX");
......
//call this function to start the purchase flow. product are product info, see the class "MSLDProduct". cpInfo are cp information such as order id of cp, player id etc.
MSLDPaymentManager.PurchaseProduct(this.product, this.cpInfo, payMethod, (MSLDErrorCode code, string msg, MSLDPayResult order) => {
if (MSLDErrorCode.Success == code)
{
MSLDInfoWindow.Info("purchase success msg = " + msg + "order: " + order.desc());
MSLDInfoWindow.Info("add the product to user...");
}
else
{
MSLDInfoWindow.Info("purchase failed! code = " + code + " msg = " + msg);
}
});</code></pre>
<h4>3.2.2 implement the Redelivery Order(must)</h4>
<p>please deal the event at the global event call when receive the event "MSLDSDK.Event.RedeliveryOrder"</p>
<p>```C#
using iDreamsky.MSLD.Payment;
using iDreamsky.MSLD;</p>
<p>// global event callback
void OnSDKEventCallBack(MSLDSDK.Event eventID, object eventObj)
{
MSLDInfoWindow.Info("event ID:" + eventID);
switch (eventID)
{
case MSLDSDK.Event.SwitchAccount:
......
break;
case MSLDSDK.Event.LogOut:
......
break;
case MSLDSDK.Event.RedeliveryOrder:
{
MSLDInfoWindow.Info("[RedeliveryOrder]pay result:" + eventObj.ToString());</p>
<pre><code> MSLDPayResult mSLDPayResult = (MSLDPayResult)eventObj;
// when receive the result, you should verify it and then send the product to user
......
MSLDInfoWindow.Info("[RedeliveryOrder]add product of user...");
// after add product of user, it is best report the consume result
MSLDInfoWindow.Info("[RedeliveryOrder]report Consumed");
MSLDPaymentManager.ReportOrderConsumed(mSLDPayResult.orderNo, (MSLDErrorCode codeROC, string msgROC) => {
MSLDInfoWindow.Info("[RedeliveryOrder]Finsh report consumed! code:" + codeROC + " msg:" + msgROC);
});
}
break;
}
}</code></pre>
<pre><code>
#### 3.2.3 Restore Transactions(iOS)
this feature only for iOS platform.
call "RestoreTransactions(APICallBack<string[]> callback)" will restore the transations. This function will return product id list of purchased. All behavie are the same as iOS orignal feature.
```C#
using iDreamsky.MSLD.Payment;
using iDreamsky.MSLD;
MSLDPaymentManager.RestoreTransactions((MSLDErrorCode code, string msg, string[] restoreIDs) => {
if (code == MSLDErrorCode.Success)
{
MSLDInfoWindow.Info("restore success!" + restoreIDs + "count:" + restoreIDs.Length);
foreach (string restore in restoreIDs)
{
MSLDInfoWindow.Info("--- productID:" + restore);
}
}
else
{
MSLDInfoWindow.Info("restore failed!");
}
});</code></pre>
<h4>3.2.4 query product infomation(iOS)</h4>
<p>This feature only for iOS platform.
You can get product infomation by product id. </p>
<p>```C#
using iDreamsky.MSLD.Payment;
using iDreamsky.MSLD;</p>
<p>......
string queryProductId = "test_01";
MSLDPaymentManager.QueryProduct(queryProductId, (MSLDErrorCode code, string msg, MSLDProduct product) => {
if (code == MSLDErrorCode.Success)
{
MSLDInfoWindow.Info("query product success! " + product.desc());
}
else
{
MSLDInfoWindow.Info("query product failed! code = " + code + " msg = " + msg);
}
});</p>
<pre><code>
### 3.3 Share
#### 3.3.1 Share Platform config
MSLD SDK support QQ and Wechat share. Developers need create application in these platform and config the infomation of application. Please read the platform document for details.
visit [wechat open platform](https://open.weixin.qq.com/) to create application and obtain wechat AppId.
visit[tencent open platform](https://open.tencent.com/) to create application and obtain QQ AppId.
#### 3.3.2 platform project setting
##### 3.3.2.1 Config Share for Android
###### 3.3.2.1.1 config MSLD with weichat/QQ appId.
- set the weichat/QQ appId in "msConfig.json" File.
###### 3.3.2.1.2 config WXEntryActivity
- create "wxapi" directory in application directory. then create "WXEntryActivity" class file in wxapi directory. "WXEntryActivity" class should inherit WeixinShareAbstract.
- WXEntryActivity config example(applicaton package id: com.idreamsky.hawk):
- 
- WXEntryActivity class example:
```java
package com.idreamsky.hawk.wxapi;
import com.ms.plugin.wechat.WeixinShareAbstract;
/**
* wecha callback Activity
*/
public class WXEntryActivity extends WeixinShareAbstract {
}</code></pre>
<h6>3.3.2.1.3 Config Androidmanifest.xml</h6>
<ul>
<li>add authority </li>
</ul>
<pre><code class="language-xml"> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/></code></pre>
<ul>
<li>add activity component</li>
</ul>
<p>Note: replace <strong>packageName</strong> with real package name.</p>
<pre><code class="language-xml"> <activity
android:name="packageName.wxapi.WXEntryActivity"
android:label="@string/app_name"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:exported="true"
android:taskAffinity="packageName"
android:launchMode="singleTask">
</activity></code></pre>
<h5>3.3.2.2 Config Share for iOS</h5>
<h6>3.3.2.2.1 Config wechat/QQ parameter of Share</h6>
<p>Fill wechat/QQ AppId into "msConfig.json" file. Any problem please contact with MSLD developer(jack.deng).
<img src="https://github.com/veryitman/MSSDKResource/blob/mark-feature/Unity3D/guide-main/guide_06.png?raw=true" alt="Config SNS Key" /></p>
<h6>3.3.2.2.2 Config scheme</h6>
<p><img src="https://github.com/veryitman/MSSDKResource/blob/mark-feature/Unity3D/guide-main/guide_07.png?raw=true" alt="" /></p>
<h6>3.3.2.2.3 Config LSApplicationQueriesSchemes</h6>
<p>Please add content below into "Info.plist" file of iOS project.</p>
<p>```C#
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "<a href="http://www.apple.com/DTDs/PropertyList-1.0.dtd">http://www.apple.com/DTDs/PropertyList-1.0.dtd</a>"></p>
<plist version="1.0">
<array>
<string>weixin</string>
<string>mqq</string>
<string>mqqapi</string>
<string>mqqwpa</string>
<string>mqqbrowser</string>
<string>mttbrowser</string>
<string>mqqOpensdkSSoLogin</string>
<string>mqqopensdkapiV2</string>
<string>mqqopensdkapiV3</string>
<string>mqqopensdkapiV4</string>
<string>wtloginmqq2</string>
<string>mqzone</string>
<string>mqzoneopensdk</string>
<string>mqzoneopensdkapi</string>
<string>mqzoneopensdkapi19</string>
<string>mqzoneopensdkapiV2</string>
<string>mqqapiwallet</string>
<string>mqqopensdkfriend</string>
<string>mqqopensdkdataline</string>
<string>mqqgamebindinggroup</string>
<string>mqqopensdkgrouptribeshare</string>
<string>tencentapi.qq.reqContent</string>
<string>tencentapi.qzone.reqContent</string>
</array>
</plist>
<pre><code>
###### 3.3.2.2.4 deal with weichat/QQ URL callback
There's some openURL callback in iOS projct's application delegate. Call MSLD SDK native API at the right function to deal with the result of wechat/QQ shared.
```Objective-C
#import <MSLDSDK/MSLDSDK.h>
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
[[MSLDSDK sharedInstance] msld_application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
return YES;
}
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_9_0
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options
{
[[MSLDSDK sharedInstance] msld_application:app openURL:url options:options];
return YES;
}
#endif</code></pre>
<h4>3.3.3 Call API for Share</h4>
<p>call "public static void Share(MSLDShareContent content, MSLDShareScence scence, APICallBack callBack)" for share contents.
For now, MSLD support share Images, Webpages and miniprogram. Scence QQ,Qzone,Wechat Friend,Wechat session are supported scences.</p>
<p><strong>content</strong> parameter. Please don't use MSLDShareContent object dierctly. Using subclass of MSLDShareContent object. MSLDShareContentImage(Image),MSLDShareContentWebpage(WebPage),MSLDShareContentMiniProgram(miniProgram)'s objects are supported. You can choose proper object according your business. Fill the paratmeter with proper class of object.</p>
<p><strong>scence</strong> parameter means share scence. If the content are miniprogram, you can ignore this parameter.
<strong>callBack</strong> Share result.</p>
<p>```C#
using iDreamsky.MSLD.Share;
using iDreamsky.MSLD;</p>
<p>......</p>
<p>public void OnClickShare()
{
MSLDShareContent shareContent = null;
MSLDShareContentType scType = contentTypeList[shareContentDropdown.value];
switch (scType) {
case MSLDShareContentType.Image:
shareContent = FindObjectOfType<share_panel_content_image>().shareContentImage;
break;
case MSLDShareContentType.Web:
shareContent = FindObjectOfType<share_panel_content_webpage>().shareContentWebpage;
break;
case MSLDShareContentType.MiniProgram:
shareContent = FindObjectOfType<share_panel_content_miniprogram>().shareContentMiniProgram;
break;
}</p>
<pre><code>MSLDShareScence scence = scenceTypeList[shareScenceDropdown.value];
MSLDInfoWindow.Info("Share content[" + shareContent.Desc() + "]" + " scence[" + scence + "]");
MSLDShareManager.Share(shareContent, scence, shareCallBack);</code></pre>
<p>}</p>
<p>void shareCallBack(MSLDErrorCode code, string msg) {
if (code == iDreamsky.MSLD.MSLDErrorCode.Success)
{
Debug.Log("Share success!");
}
else
{
Debug.Log("Share failure.");
}
}</p>
<pre><code></code></pre>