java - 使用 Unity3D 和 Vuforia 的 Android 4.1.2 上相机为黑色

标签 java android unity-game-engine augmented-reality vuforia

我工作的公司正在构建一个集成 vuforia(版本 5.x)和 Unity3D(版本 5.3.5f1 Personal)的 Android 应用程序。

在最新的 Android 设备中,相机可以正常打开,但我们在 Samsung Galaxy S2(4.1.2) 等旧设备中遇到问题。当设备通过 vuforia 打开相机时,屏幕是黑色的,如果我们尝试拍照,图像也明显是黑色的。

我的 Activity 只是实例化统一播放器,它就像下面的代码:

public class MainActivity extends AppCompatActivity {

protected UnityPlayer mUnityPlayer;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    getWindow().setFormat(PixelFormat.RGBX_8888); // <--- This makes xperia play happy
    mUnityPlayer = new UnityPlayer(this);
    setContentView(mUnityPlayer);
    mUnityPlayer.requestFocus();
}

public void onImageSaved(final String path) {
    final Intent intent = new Intent(MainActivity.this, CameraPreviewActivity.class);
    final Bundle bundle = new Bundle();
    bundle.putString("IMAGE_PATH", path);
    intent.putExtras(bundle);
    startActivity(intent);
}

public void onImageSavedError(final String message) {
    UnityPlayer.currentActivity.runOnUiThread(new Runnable() {

        @Override
        public void run() {
            Log.e("Teste", message);
        }
    });
}

// Quit Unity
@Override protected void onDestroy ()
{
    mUnityPlayer.quit();
    super.onDestroy();
}

// Pause Unity
@Override protected void onPause()
{
    super.onPause();
    mUnityPlayer.pause();
}

// Resume Unity
@Override protected void onResume()
{
    super.onResume();
    mUnityPlayer.resume();
}

// This ensures the layout will be correct.
@Override public void onConfigurationChanged(Configuration newConfig)
{
    super.onConfigurationChanged(newConfig);
    mUnityPlayer.configurationChanged(newConfig);
}

// Notify Unity of the focus change.
@Override public void onWindowFocusChanged(boolean hasFocus)
{
    super.onWindowFocusChanged(hasFocus);
    mUnityPlayer.windowFocusChanged(hasFocus);
}

// For some reason the multiple keyevent type is not supported by the ndk.
// Force event injection by overriding dispatchKeyEvent().
@Override public boolean dispatchKeyEvent(KeyEvent event)
{
    if (event.getAction() == KeyEvent.ACTION_MULTIPLE)
        return mUnityPlayer.injectEvent(event);
    return super.dispatchKeyEvent(event);
}

// Pass any events not handled by (unfocused) views straight to UnityPlayer
@Override public boolean onKeyUp(int keyCode, KeyEvent event)     { return mUnityPlayer.injectEvent(event); }
@Override public boolean onKeyDown(int keyCode, KeyEvent event)   { return mUnityPlayer.injectEvent(event); }
@Override public boolean onTouchEvent(MotionEvent event)          { return mUnityPlayer.injectEvent(event); }
/*API12*/ public boolean onGenericMotionEvent(MotionEvent event)  { return mUnityPlayer.injectEvent(event); }

@Override
public void onBackPressed() {
    finish();
}

}

vuforia负责打开相机并开始跟踪图像目标,而unity3D将渲染带有动画的3D图像并负责拍照。

在unity项目中,我们开发了一个拍照按钮和一个将图像保存在android目录中的功能。其脚本是用C#完成的,其实现如下:

IEnumerator TakeSnapshot()
{
    yield return new WaitForEndOfFrame();
    Texture2D snap = new Texture2D(Screen.width,Screen.height);
    Camera camera = Camera.current;

    if (rotation != null)
    {
        camera.transform.rotation = rotation.Value;
    }

    if (position != null)
    {
        camera.transform.position = position.Value;
    }

    camera.Render();
    RenderTexture.active = camera.targetTexture;
    snap.ReadPixels(new Rect(0,0,Screen.width,Screen.height),0,0);
    snap.Apply();
    RenderTexture.active = null;

    byte[] bytes = snap.EncodeToJPG();
    DestroyObject(snap);

    string path = Application.persistentDataPath + "/MyAppPath/";
    if(!System.IO.Directory.Exists(path)){
        System.IO.Directory.CreateDirectory(path);
    }

    string filename = fileName(Convert.ToInt32(snap.width), Convert.ToInt32(snap.height));
    path = path + filename;
    System.IO.File.WriteAllBytes(path, bytes);

    using (var actClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
    {
        var jo = actClass.GetStatic<AndroidJavaObject>("currentActivity");

        if (jo == null) {
            Debug.Log ("jo is null");
        } else {
            jo.Call("onImageSaved", path);
        }
    }
}

这篇文章的主要目标是尝试理解为什么相机仅在旧设备中是黑色的,因为它在新设备中运行良好。另外我想强调的是,openGL 可能不是问题,因为我已经使用 sinogen 5.1 在 Samsung Galaxy S2 等旧设备中测试了该应用程序。 Unity项目当前导出的openGL版本是openGL2。 提前致谢。

最佳答案

试试这个代码:

public string deviceName;
WebCamTexture wct;
void Start ()
{
    WebCamDevice[] devices = WebCamTexture.devices;
    deviceName = devices[0].name;
    wct = new WebCamTexture(deviceName, 400, 300, 12);
    GetComponent<Renderer> ().material.mainTexture = wct;
    wct.Play();
}

关于java - 使用 Unity3D 和 Vuforia 的 Android 4.1.2 上相机为黑色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38857788/

相关文章:

android - 可扩展列表,在 android 中的 grouplayput 上编辑文本

ios - libc++abi.dylib : terminating with uncaught exception of type Il2CppExceptionWrapper on restore IAP

android - 如何在 Unity 上制作适合屏幕的游戏

java - 在 Java Android 中加密并在 C# Unity 中解密

java - 如何添加-Xlint :unchecked option or any javac option in Eclipse?

android - AppCompatActivity 中的 setListAdapter

java - 有什么方法可以将已经运行的浏览器附加到 java 中的 selenium webdriver?

android - 录制 Android 音频输出

java - 是否应该与 DAO 一起使用同步

java - Eclipse juno 在 Suse 64 位中给出错误