Google Cardboard Video on iOS with Unity 5

I am trying to make a spherical 360 video with the Google Cardboard SDK.

I ran some tests with a MovieTexture

desktop build which works great, but there is no implementation of this class in iOS.

I've seen some external plugins in the asset store, but none of them seem to be compatible with Unity 5.

Is there a class provided by the Cardboard SDK to achieve this, or if you don't know of another solution or plugin that can do this?

+3


source to share


2 answers


I finally solved it.

We need to remove CardboardAppController and MMTAppController and merge them into one.

Basically there are 2 AppControllers in Assets / Plugin / ios: "CardboardAppController.mm" (also has a header CardboardAppController.h) and "MMTAppController.mm"

The trick is that ios only "sees" one application controller after generation. Since CardboardAppController comes first, MMTAppController is discarded.

To solve this problem, I did the following:

Create a new AppController: in my case it was named SVAppController.mm and SVAppController.h

Then we have to merge both application controllers into this one and delete them.

So, I copied the contents of CardboardAppController.h to SVAppController.h and the contents of CardboardAppController.mm to SVAppController.mm (Make sure to change the names in the code, replace CardboardAppController with SVAppController ).



Then copy the contents of MMTAppController.mm to SVAppController.mm in the desired location

Finally, remove CardboardAppController and MMTAppController.

You will have 1 app controller left and everything should work fine.

For reference, here is my latest SVAppController:

SVAppController.h

#import "UnityAppController.h"
#import "UnityAppController+Rendering.h"
#import "UnityAppController+ViewHandling.h"

// Unity 4.6.2 added a category to the app controller.
#if UNITY_VERSION < 462
#import "UnityInterface.h"
#else
#import "UnityAppController+UnityInterface.h"
#endif

// Unity 4 used a different method name to create the UnityView.
#if UNITY_VERSION < 500
#define createUnityView initUnityViewImpl
#endif

@interface SVAppController : UnityAppController

- (void)preStartUnity;

- (UnityView *)createUnityView;

- (void)startSettingsDialog:(UIViewController *)dialog;

- (void)stopSettingsDialog;

- (void)pause:(bool)paused;

- (void)shouldAttachRenderDelegate;

@end

      

SVAppController.mm

#import "SVAppController.h"
#import "CardboardView.h"
#import <UIKit/UIKit.h>
extern "C" {

    extern void readProfile();
    extern void syncProfile();

    extern "C" void MMTUnitySetGraphicsDevice(void* device, int deviceType, int eventType);
    extern "C" void MMTUnityRenderEvent(int marker);

    extern UIViewController* createSettingsDialog(id app);
    extern UIViewController* createOnboardingDialog(id app);

    bool isOpenGLAPI() {
#if UNITY_VERSION < 463
        return true;
#else
        SVAppController* app = (SVAppController *)GetAppController();
        UnityRenderingAPI api = [app renderingAPI];
        return api == apiOpenGLES2 || api == apiOpenGLES3;
#endif
    }

    void launchSettingsDialog() {
        SVAppController* app = (SVAppController *)GetAppController();
        [app startSettingsDialog:createSettingsDialog(app)];
    }

    void launchOnboardingDialog() {
        SVAppController* app = (SVAppController *)GetAppController();
        [app startSettingsDialog:createOnboardingDialog(app)];
    }

    void endSettingsDialog() {
        SVAppController* app = (SVAppController *)GetAppController();
        [app stopSettingsDialog];
    }

}  // extern "C"

@implementation SVAppController

- (void)preStartUnity {
    [super preStartUnity];
    syncProfile();
}

- (UnityView *)createUnityView {
    return [[CardboardView alloc] initFromMainScreen];
}

- (void)startSettingsDialog:(UIViewController*)dialog {
    [self pause:YES];
    [self.rootViewController presentViewController:dialog animated:NO completion:nil];
}

- (void)stopSettingsDialog {
    [[self rootViewController] dismissViewControllerAnimated:NO completion:nil];
    [self pause:NO];
}

- (void)pause:(bool)paused {
#if UNITY_VERSION < 462
    UnityPause(paused);
#else
    self.paused = paused;
#endif
}

- (void)shouldAttachRenderDelegate;
{
    UnityRegisterRenderingPlugin(&MMTUnitySetGraphicsDevice, &MMTUnityRenderEvent);
}

@end

IMPL_APP_CONTROLLER_SUBCLASS(SVAppController)

      

+1


source


Movies in Unity are usually rendered as textures on objects. On a mobile device, the problem is that the device wants to display the video in the video player, so the MovieTexture of the Unity class is not supported.

I have success getting around this and successfully creating 360 videos inside a sphere using a Unity plugin from the Unity Asset Store called Easy Movie Texture.

To work on Mac, here's what I did:



  • Download the Easy Movie Texture plugin from the Unity Asset Store.
  • Open the Demo Sphere demo scene from Assets / EasyMovieTexture / Scene
  • Create a new (empty) Prefab for your project and drag the Sphere GameObject from the Demo Sphere scene onto the Prefab.
  • Reopen your card scene and drag the new video sphere assembly into your hierarchy.
  • Open source 360 ​​video in Quicktime
  • File -> Export -> 720p
  • Change the file extension from '.mov' to '.mp4'
  • Drag the new mp4 file into your Assets / Streaming Assets projects. Note: do not import via the menu system as this will force Unity to convert to OGG.
  • In the "Media Player Ctrl" script of your Video GameObject, find the "Str_File_Name" field and specify FULL the filename of your newly exported video file. Remember to include the extension as part of the string, "mymovie.mp4".

Pretty sure that's all. Hope this helps other people to get stuck with this issue.

Final note: the video will only be displayed on the device. In the editor, you will only see a white texture on the sphere. You have to publish it to your device to see your amazing 360 video.

+2


source







All Articles