ue和android互调
这两种方式都是在UE打包的Android工程之上进行的。
一、首先是UE打包Android,勾选下面这项
如果有多个场景需要添加场景
工程文件在这个路径下
然后可以通过Android Studio打开,选择gradle打开
先运行一下,看看是否可以发布到Android设备上,然后再进行下一步。
二、新建一个MainActivity启动UE
MainActivity注意要继承Activity,test.android包名是UE发布android时候的包名
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, GameActivity.class);
startActivity(intent);
}
});
}
}
然后就是Manifest中启动这个Activity,把自动生成的GameActivity作为启动的Activity取消了。
<activity android:name="com.test.android.MainActivity"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
这个页面上就一个按钮,用来跳转UE用的。
<?xml version="1.0" encoding="utf-8"?>
<android.widget.RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.test.android.MainActivity">
<Button
android:id="@+id/button"
android:layout_width="177dp"
android:layout_height="155dp"
android:text="Button"
tools:layout_editor_absoluteX="172dp"
tools:layout_editor_absoluteY="351dp" />
</android.widget.RelativeLayout>
然后就可以测试一下,启动项目应该是启动自己新的这个Activity,点击按钮就可以跳转到UE的界面。
三、UE中自定义widget点击按钮,打开Android页面,右边两个没有用不用管。
1、这个是我们新建的c++类
头文件
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "Components/Button.h"
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "DemoUserWidget.generated.h"
/**
*
*/
UCLASS()
class DEMOANDROID_API UDemoUserWidget : public UUserWidget
{
GENERATED_BODY()
protected:
virtual void NativeConstruct() override;
public:
UPROPERTY(meta = (BindWidget))
class UButton* ButtonUEJump;
UPROPERTY(meta = (BindWidget))
class UButton* ButtonHaerbin;
UPROPERTY(meta = (BindWidget))
class UButton* ButtonBeijing;
UFUNCTION()
void ButtonUEJumpClick();
UFUNCTION()
void ButtonHaerbinClick();
UFUNCTION()
void ButtonBeijingClick();
};
?cpp文件,ButtonHaerbinClick是我们点击widget按钮时,回调的方法。toAndroidActivity是定义在GameActivity中的一个java方法,(Ljava/lang/String;)V这个要注意的是参数后面要加分号,V表示无返回值的意思。CallVoidMethod就是调用java中无返回值的方法,str是要传递的参数。
void UDemoUserWidget::ButtonHaerbinClick()
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("haerbin")));
#if PLATFORM_ANDROID
if (JNIEnv* Env = FAndroidApplication::GetJavaEnv())
{
bool bIsOptional = false;
static jmethodID toAndroidActivity = FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "toAndroidActivity", "(Ljava/lang/String;)V", bIsOptional);
char tt[30] = {"--------a--"};
jstring str = Env->NewStringUTF((const char*)tt);
FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, toAndroidActivity, str);
UE_LOG(LogTemp, Warning, TEXT("jmethodID is vaild :AndroidThunkJava_GetMessage "));
}
#endif//PALTFORM_ANDROOT
}
2、UE中创建一个Widget要继承我们之前写的c++的代码
按钮的名字要与c++头文件的名称一致,因为我们使用的是绑定的方式。
?
3、在Android的GameActivty中新建的2个方法,以对话框的方式打开Android的界面。?
public void toAndroidActivity(String placeName) {
runOnUiThread(new Runnable() {
@Override
public void run() {
showLimit(GameActivity.this);
}
});
}
public void showLimit(Context context) {
final Dialog baseDialog = new Dialog(context);
View view = LayoutInflater.from(context).inflate(R.layout.view_pop_custom, null);
TextView tv_next = view.findViewById(R.id.tv_next);
baseDialog.show();
baseDialog.setCanceledOnTouchOutside(false);
Window window = baseDialog.getWindow();
WindowManager.LayoutParams attributes = window.getAttributes();
attributes.width = 600;
window.setAttributes(attributes);
tv_next.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.debug("tv_next.setOnClickListener");
baseDialog.dismiss();
toNewUEPlace();
}
});
window.setContentView(view);
}
四、点击弹出的Android界面上的按钮,切换ue中的场景
1、在GameActivity类中定义一个方法public native void toNewUEPlace();
2、在UE中DemoUserWidget.cpp中
#include "Kismet/GameplayStatics.h"
#if PLATFORM_ANDROID
#include "Runtime/Launch/Public/Android/AndroidJNI.h"
#include "Runtime/ApplicationCore/Public/Android/AndroidApplication.h"
#include "Android/AndroidJavaEnv.h"
#endif//PLATFORM_ANDROID
#if PLATFORM_ANDROID
JNI_METHOD void Java_com_epicgames_unreal_GameActivity_toNewUEPlace(JNIEnv* jenv, jobject thiz)
{
UE_LOG(LogTemp, Warning, TEXT("toNewUEPlace"));
UGameplayStatics::OpenLevel(GWorld, FName("/Game/Maps/abc"), true);
}
#endif//PLATFORM_ANDROID
abc是自己创建的map