【Android】Live2D Cubism SDK for JavaをJetpack ComposeとKotlinで動かす
2024/07/19
2024/11/05
📰 アフィリエイト広告を利用しています
はじめに
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 でNDKとCMakeを追加
今回はEmpty Activityで新規作成しました。
Frameworkの設定
CoreからFrameworkを呼び出すときにcom.live2d.sdk.cubism.frameworkからimportしているので、呼び出せるようにします。
ダウンロードしてきたzipを解凍し、CubismSdkForJava-5-r.1\Framework\framework\src\main\java\com の com フォルダをkotlin+java にコピーします。
画像のようにcomにlive2d.sdk.cubism.framework が追加されます。
Coreの設定
次にCoreの設定を行います。
まずCoreのaarファイルを入れるフォルダを作成します。
表示をAndroidからProjectに切り替えます。
appの下にlibs を作成します。
\CubismSdkForJava-5-r.1\Core\android\Live2DCubismCore.aar の .aar ファイルを libs にコピーします。
build.gradle.ktsに依存関係を追加します
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ファイルを参考に以下のようにして完了
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
}
}
},
)
}