เขียน Plugin Android สำหรับ Unity3d ด้วย Kotlin เพื่อรับผลจาก onActivityResult โดยไม่ต้อง override activity หลัก
Tags: unity, gamedev
Published: 2018-08-08 05:28:27

---
title: เขียน Plugin Android สำหรับ Unity3d ด้วย Kotlin เพื่อรับผลจาก onActivityResult โดยไม่ต้อง override activity หลัก
published: true
tags: unity,game-development
canonical_url: 
---

สวัสดีครับบ วันนี้มาเป็นเรื่องเกี่ยวกับการเขียน Plugin Android บน Unity3d ที่ตัดสินใจมาเขียนนี่เพราะว่า รู้สึกว่าตอนผมทำเนี่ยมันหาอ่านยากมากเลย เลยมาเขียนเก็บไว้ตรงนี้ เพื่อคนต่อ ๆ ไปนะครับบ เดี๋ยวจะทำให้ดูคร่าว ๆ นะครับไม่งั้นมันจะยาวโคตร

#### Requirement สำหรับวันนี้

- Android studio
- Unity3d 2018.2.0f2

ครับผม สำหรับคนที่มีครบทุกอย่างแล้ว ก็เริ่มกันเลย! โดยสำหรับวันนี้จะมาทำ Line Login กันดูนะครับ

เปิด Android Studio ขึ้นมาทำงานกันโลด ทำการสร้างโปรเจคบน Andriod แล้ว New Module ใหม่ขึ้นมาเป็น Android Library สักหนึ่งที

![](https://cdn-images-1.medium.com/max/1012/1*sCTHodnDaMBiur2lXj1RRA.png)<figcaption>สร้าง Moudle ใหม่เป็น Android Library</figcaption>

จากสร้าง Activity ใหม่ชื่อว่า LineSDKActivity ขึ้นมาครับ จากนั้นเราจะมาเริ่มเขียนตัว Plugin กันนะครับ ก่อนอื่น เราต้องไป Download ตัว LineSDK สำหรับ Android จากหน้าเว็บกันก่อนเลยครับ​ (จัดการสร้าง Project อะไรให้เสร็จสรรพเลยนะครับ ลองอ่านจากหน้าเว็บมันดูนั่นแหละ) สามารถหาได้จาก[ที่นี่](https://developers.line.me/en/) หลังจากเสร็จแล้วก็เอาตัว .aar ลากลง lib โลดเลยครับ

![](https://cdn-images-1.medium.com/max/184/1*DcYFSbtKvMNOsnfMlBZa7Q.png)<figcaption>เอา Line SDK for Android ใส่ในโปรเจค</figcaption>

จากนั้นก็เขียนโค้ดสำหรับ Login เลยครับผม สามารถแทบจะลอกจากหน้าเว็บของ Developer Line ได้เลยครับ

```
class LineSDKActivity : AppCompatActivity() {

    companion object {
        lateinit var lineLoginCallback: LineLoginCallback

        fun startLineSDKActivity(activity: Activity, lineLoginCallback: LineLoginCallback) {
            LineSDKActivity.lineLoginCallback = lineLoginCallback;
            val intent = Intent(activity._applicationContext_, LineSDKActivity::class._java_)
            activity.startActivity(intent);
        }
    }

    data class PlayerProfile(
            val displayName: String,
            val statusMessage: String?,
            val userId: String,
            val pictureUri: Uri?
    )

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        login()
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode != Constants.REQUEST\_CODE) {
            Log.e("ERROR", "Unsupported Request");
            lineLoginCallback.onLoginFailed("Unsupported Request")
            finish()
        }

        if (data == null) {
            lineLoginCallback.onLoginFailed("Can't connect with Line")
            finish()
        }

        val result: LineLoginResult = LineLoginApi.getLoginResultFromIntent(data)

        when (result._responseCode_) {
            LineApiResponseCode.SUCCESS -> {
                lineLoginCallback.onLoginSuccess(
                        result._lineProfile_!!._displayName_  
)
            }
            else -> {
                lineLoginCallback.onLoginFailed("Login Unsuccessful")
            }
        }

        finish()

    }

    fun login() {
        startActivityForResult(getLineLoginIntent(), Constants.REQUEST\_CODE)
    }

    private fun getLineLoginIntent() : Intent {
        return LineLoginApi.getLoginIntent(this._applicationContext_, Constants.CHANNEL\_ID)
    }
}
```

หลังจากได้ประมาณนี้ปุ๊บ จะเห็นว่าผมมีใช้ตัว LineLoginCallback เพื่อให้สามารถเอาไปเชื่อมกับตัว C# ใน Unity3d ได้ ก็ทำการสร้างไฟล์ใหม่แล้วประกาศ interface โลด

```
interface LineLoginCallback {
    fun onLoginSuccess(displayName: String)
    fun onLoginFailed(errorMessage: String)
}
```

หลังจากเสร็จ อย่าลืมว่าต้องใส่ appcompat กับ customtabs ให้กับ build.gradle ของตัว ​module นี้ด้วยนะครับ แบบนี้

```
dependencies {
    implementation fileTree(dir: 'libs', include: ['\*.jar'])
    implementation 'androidx.appcompat:appcompat:1.0.0-beta01'
    implementation 'androidx.browser:browser:1.0.0-beta01'
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin\_version"
    implementation(name: 'line-sdk-4.0.8', ext: 'aar')
}
```

แล้วก็ทำการ build โลดเลยครับ ถ้า build สำเร็จเราก็จะได้เป็นไฟล์ .aar มาอยู่ใน output ของ module นะครับ

คราวนี้เรามาดูที่ตัว Unity ของเรากันบ้าง ที่นี่เราต้องทำการสร้างโฟลเดอร์ Plugins/Android ขึ้นมาครับ เพื่อเป็นที่เก็บตัว Plugin ของเราตามกฏของ Unity นะครับ

![](https://cdn-images-1.medium.com/max/115/1*C1D1DaKz4r8Vrtpc9aqGXw.png)

จากนั้นเอา .aar ของเรายัดเข้าไปเลยครับ รวมถึงไฟล์ line-sdk-4.0.8.aar ที่โหลดมาจากเว็บของ Line ด้วยนะครับ จากนั้น เราจะทำการเปิด gradle ไฟล์ขึ้นมา เพื่อจัดการตัว Dependencies ในโปรเจคนะครับ ไปที่ build setting ของ Android ในส่วนของ Publishing Settings ทำการติ้กถูกตรง Custom Gradle Template โลดเลยครับ ตามรูปข้างล่าง

![](https://cdn-images-1.medium.com/max/298/1*UT0meoBtzzCeawTlwJYT-A.png)

เราจะได้ไฟล์ mainTemplate.gradle ขึ้นมานะครับแล้วทำการ แก้ไขโลดเลยครับ

```
implementation(name:'line-sdk-4.0.8', ext:'aar')
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.51'
implementation 'androidx.appcompat:appcompat:1.0.0-alpha1'
implementation 'androidx.browser:browser:1.0.0-alpha1'
```

ทำการ add สี่ตัวนี้เข้าไปที่ส่วนของ Dependencies ได้เลยครับ จากนั้น ผมจะเขียนคร่าว ๆ ของส่วนการใช้ให้ดูนะครับ จะประมาณนี้ก็คือ ก่อนอื่นสร้างไฟล์ขึ้นมาก่อน สำหรับผมใช้ชื่อ LineSDK.cs นะครับ

```
// LineSDK.cs

public class LineSDK {
  public class LineLoginCallback : AndroidJavaProxy {
    public LineLoginCallback : base("xxx.xx.xxx.LineSDKActivity") {}

    public void onLoginSuccess(string displayName) {
      Debug.Log("Line login success");
    }

    public void onLoginFailed(string errorMessage) {
      Debug.Log("Line login failed");
    }
  }

  ...
}
```

อันนี้เป็นส่วนหลักเลยนะครับ อันนี้สังเกตนะครับ LineLoginCallback สืบทอดมาจาก AndroidJavaProxy โดยใน constructor เนี่ยเอามาจากชื่อ Class ของใน Java ที่เราประกาศ interface ไว้นะครับ

ส่วนตอน function login เนี่ยก็จะประมาณนี้ครับ

![](https://cdn-images-1.medium.com/max/1009/1*sbZAm7W0MIkK6SXmi7_2dA.png)

สุดท้ายยยนะครับ อย่าลืมใส่ AndroidManifest.xml ใน Unity3d ด้วยนะครับ​ โดยมันจะมี Template อยู่นะครับ แต่เดี๋ยวผมเอาแต่ส่วนสำคัญที่จำเป็นต้องเพิ่มมาให้ดูละกันครับ

```
...

<activity
  android:name="app.zosimos.linesdk.LineSDKActivity"
  android:theme="@style/Theme.AppCompat.NoActionBar"
/>

...
```

อันนี้คือการที่เราเพิ่ม Activity ที่เราเขียนใน Java เพิ่มเข้าไปใน Unity นะครับ ถ้าเกิดเราไม่ใส่อันนี้เข้าไปเนี่ยมันจะหาไม่เจอครับบ

ก็จะประมาณนี้แหละครับ ต้องขอโทษที พอดีบล๊อกนี้รีบเขียนไปหน่อย แต่ยังไงก็ถ้ามีอะไรก็ทักมาถามกันได้ครับ อาจจะพอให้เป็นแนวทางได้ ขอบคุณครับ

คุยกันได้ [ที่นี่](https://www.facebook.com/%E0%B8%97%E0%B8%B8%E0%B8%81%E0%B8%AD%E0%B8%A2%E0%B9%88%E0%B8%B2%E0%B8%87%E0%B9%80%E0%B8%9B%E0%B9%87%E0%B8%99%E0%B9%80%E0%B8%A3%E0%B8%B7%E0%B9%88%E0%B8%AD%E0%B8%87%E0%B8%87%E0%B9%88%E0%B8%B2%E0%B8%A2%E0%B8%96%E0%B9%89%E0%B8%B2%E0%B8%84%E0%B8%B8%E0%B8%93%E0%B8%95%E0%B8%B1%E0%B9%89%E0%B8%87%E0%B9%83%E0%B8%88%E0%B8%AD%E0%B9%88%E0%B8%B2%E0%B8%99-194825381157188/) ปล. page นี้ผมเคยเปิดทิ้ง ๆ ไว้ เอาไว้เป็นที่คุยละกันครับ 555