ue和android互调
这两种方式都是在UE打包的Android工程之上进行的。
一、首先是UE打包Android,勾选下面这项
如果有多个场景需要添加场景
工程文件在这个路径下
然后可以通过Android Studio打开,选择gradle打开
先运行一下,看看是否可以发布到Android设备上,然后再进行下一步。
二、新建一个MainActivity启动UE
MainActivity注意要继承Activity,test.android包名是UE发布android时候的包名
public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {@Overridepublic 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"><Buttonandroid: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_ANDROIDif (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() {@Overridepublic 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() {@Overridepublic 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