hy clear Blog

【Android】Live2D Cubism SDK for JavaをJetpack ComposeとKotlinで動かす

2024/07/19

2024/07/19

📰 アフィリエイト広告を利用しています

はじめに

Live2Dをアプリに組み込みたかったがデモを動かすのに少してこずったで忘れたときようのメモ
サンプルではgradleのsyncでエラーが出て、よくわからん!ってなったので
サンプルを動かすのではなく、新しいProjectを作成して動作させます。

Android Studio

Android Studio Iguana | 2023.2.1 Patch 1
Build #AI-232.10300.40.2321.11567975, built on March 13, 2024

Live2D

Live2D Cubism SDK for Java
(CubismSdkForJava-5-r.1)

参考

公式サンプル
https://docs.live2d.com/cubism-sdk-tutorials/android-sample-run/

ライブラリのダウンロード

公式からCubism SDK for Javaをダウンロードする。

プロジェクトの設定

Tools -> SDK Manager -> SDK Tools でNDKCMakeを追加

今回はEmpty Activityで新規作成しました。

Frameworkの設定

CoreからFrameworkを呼び出すときにcom.live2d.sdk.cubism.framework からimportしているので、呼び出せるようにします。
ダウンロードしてきたzipを解凍し、CubismSdkForJava-5-r.1\Framework\framework\src\main\java\comcom フォルダをkotlin+java にコピーします。

画像のようにcomlive2d.sdk.cubism.framework が追加されます。

Coreの設定

次にCoreの設定を行います。
まずCoreのaarファイルを入れるフォルダを作成します。
表示をAndroidからProjectに切り替えます。

appの下にlibs を作成します。

\CubismSdkForJava-5-r.1\Core\android\Live2DCubismCore.aar .aar ファイルを libs にコピーします。
build.gradle.ktsに依存関係を追加します

build.gradle.kts(Module : app)
dependencies {
    // ...

    // Live2D core
    implementation(files("libs/Live2DCubismCore.aar"))

}

Assetsのインポート

公式のサンプルモデルをimportします。
まずアセットフォルダーを作ります。

assetsフォルダーに\CubismSdkForJava-5-r.1\Sample\src\main\assets 内のファイルをすべてコピーします。

サンプルプログラムの設定

new -> packageでパッケージを作成します。名前はなんでもいいです。今回はutilsにしました。

CubismSdkForJava-5-r.1\Sample\src\full\java\com\live2d\demo\full\ 内のMainAcitiviyt.javaを除くファイルをコピーします。

CubismSdkForJava-5-r.1\CubismSdkForJava-5-r.1\Sample\src\main\java\com\live2d\demo\の二つのファイルをコピーします。
最終的に以下の画像のようになります。

追加したファイルのimport先が違うので修正します。
com.live2d.demoではなく作ったprojectに合わせて設定してください。
今回はcom.example.demo_live2d.utilsなので以下のように変更していきます。

# import com.live2d.demo.LAppDefine;
import com.example.demo_live2d.utils.LAppDefine;

MainActivityの設定

MainActivityをdemoファイルを参考に以下のようにして完了

MainActivity.kt
package com.example.demo_live2d

import android.annotation.SuppressLint
import android.opengl.GLSurfaceView
import android.os.Bundle
import android.view.MotionEvent
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.viewinterop.AndroidView
import com.example.demo_live2d.ui.theme.Demo_live2dTheme
import com.example.demo_live2d.utils.GLRenderer
import com.example.demo_live2d.utils.LAppDelegate

class MainActivity : ComponentActivity() {

    private lateinit var _glSurfaceView: GLSurfaceView

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

        _glSurfaceView = GLSurfaceView(applicationContext)
        _glSurfaceView.setEGLContextClientVersion(2)

        val glRendererMinimum = GLRenderer()
        _glSurfaceView.setRenderer(glRendererMinimum)

        _glSurfaceView.renderMode = GLSurfaceView.RENDERMODE_CONTINUOUSLY

        setContent {
            Demo_live2dTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    Live2dView(glSurfaceView = _glSurfaceView)
                }
            }
        }
    }

    override fun onStart() {
        super.onStart()
        LAppDelegate.getInstance().onStart(this)
    }

    override fun onResume() {
        super.onResume()
        _glSurfaceView.onResume()
    }

    override fun onPause() {
        super.onPause()
        _glSurfaceView.onPause()
    }

    override fun onStop() {
        super.onStop()
        LAppDelegate.getInstance().onStop()
    }

    override fun onDestroy() {
        super.onDestroy()
        LAppDelegate.getInstance().onDestroy()
    }
}

@SuppressLint("ClickableViewAccessibility")
@Composable
fun Live2dView(glSurfaceView: GLSurfaceView){
    AndroidView(
        factory = { _ ->
            glSurfaceView.apply {
                setOnTouchListener { _, event ->
                    val pointX = event.x
                    val pointY = event.y
                    when (event.action) {
                        MotionEvent.ACTION_DOWN -> LAppDelegate.getInstance()
                            .onTouchBegan(pointX, pointY)

                        MotionEvent.ACTION_UP -> LAppDelegate.getInstance()
                            .onTouchEnd(pointX, pointY)

                        MotionEvent.ACTION_MOVE -> LAppDelegate.getInstance()
                            .onTouchMoved(pointX, pointY)
                    }
                    return@setOnTouchListener true
                }
            }
        },
    )
}

【Android】Live2D サンプルのカスタマイズ集