[solved] Xcode: help creating a cocoa GUI on top of unity

Well the subject is a bit misleading as i have successfully done that already more or less following this:
http://technology.blurst.com/a-cocoa-based-frontend-for-unity-iphone-applications/

I can start with cocoa stuff, then, when needed, switch to unity AND put a UIView over that.

The Problem i am NOW stuck with is, that the UIView with the GUI hinders the Unity Window from recieving the Touch events.

If i set containerView.userInteractionEnabled = NO; then Unity recieves the touches. But then the GUI doesn´t.
Somehow i need to make the Unity View Firstreciever, but i don´t know how.

The other way would be to make the GUI UIview small, because, when it´s not in the way, Unity recieves the touches as well.
But that makes things also more complicated in my case and in other cases, were GUI elements are all over the place is anyways not possible.

Any Xcode heros around here?

You likely did something wrong as AdMob overlays in an own window on top work receiving their events while the unity window around that windows gets its events.

:smile: of course i did something wrong, the question is what.

As Long As the overlay is Square One can adjust the overlaying uiview. Maybe they did it like that.

Ok, i figured it out. Problem was the way blursts “tutorial” sets up the views. For those of you interested:

Blursts description first doesn´t use the unity startupway, instead they change it to their own, loading UIViews

After they do that the basic siblings look like this:

  • UIWindow
    • SceneTitle (UIView)

    • SceneOne (UIView)

    • SceneTwo (UIView)

    • SceneAndSoOn (UIView)

This Structur already leads to problems with autorotation. Turned out that only the first added UIView will rotate as expected. All the other ones not.

So i changed this to

  • UIWindow
    • ContainerView (UIView)

        • SceneTitle (UIView)

        • SceneOne (UIView)

        • SceneTwo (UIView)

        • SceneAndSoOn (UIView)

Now rotation of all Views is ok, even if you add them at a later time.

When they call their launchUnity method, it will start Unity (and i guess change the topmost UIWindow, but am not sure). Anyways, the structur looks like this:

  • UIWindow
    • ContainerView (UIView)

        • SceneTitle (UIView)

        • SceneOne (UIView)

        • SceneTwo (UIView)

        • SceneAndSoOn (UIView)

    • unityView (EAGLView)

The Eventsystem on the iphone works like this:
The visible topmost UIView or other Class will recieve the touch Events. If it doesn´t handle the Event, the Event gets automatically passed to its superView until it gets somewhere handled or reaches the top of the responder chain.

With the currentsetup, imagine SceneTitle is visually on the top and a touch occurs and that touch is not handled by something inside this UIView, then the event bubbles up:

  • UIWindow (> as nextResponder recieves unhandled Event ContainerView)
    • ContainerView (UIView) (> as nextResponder recieves unhandled Event from SceneTitle)

        • SceneTitle (UIView) (> gets TouchEvent)

        • SceneOne (UIView)

        • SceneTwo (UIView)

        • SceneAndSoOn (UIView)

    • unityView (EAGLView)

As you can see, the Event cannot reach unitys view, as it is not inside the responderchain. Luckily it turns out, that you can actually add subViews to the EAGLView. Thats solves the Problem:

  • UIWindow
    → ContainerView (UIView)
        • SceneTitle (UIView)

        • SceneOne (UIView)

        • SceneTwo (UIView)

        • SceneAndSoOn (UIView)
          → unityView (EAGLView)

        • ScenGUI (UIView)

This structur is fine. SceneGui is now a “layer” on top of unity, can handle events or pass them to unity.
The other scenes are still outside. Imagine you have scenes like intro, outro, help and so on, they don´t need to be inside the responder chain.

So far i tested this in a supersimple testProject, will now try to change the real one accordingly.
Don´t know if this has some evel sideeffect so far

Well, for the moment, the evil pitfall is, that the added cocoa stuff inside the unity view is again not being rotated to landscape, (although the unity3d content actually handles landscapeLeft and rotatation to landscaperight just fine).

Furthermore, after getting to the 3D part, the other cocoa xscenes don´t autorotate any more. Before loading the unity scene they do.

Stuck again :evil:

Hi Marjan

I’m pretty sure you responded to my post on the answers site about this here.

To give you an overview of what is working for me right now.

  • Container view sits on top of Unity Rendering window
  • It won’t respond to rotations automatically, so I have a callback method in XCode that performs manual rotations.
  • I have a script in Unity that just monitors for rotations, if it detects a new orientation, I call the function in XCode and update the rotations manually on the container object, which rotates all of it’s children.

So the check code in Unity is like this:

if ((iPhoneInput.orientation == iPhoneOrientation.LandscapeLeft)  (iPhoneSettings.screenOrientation != iPhoneScreenOrientation.LandscapeLeft)) 
{ 
	iPhoneSettings.screenOrientation = iPhoneScreenOrientation.LandscapeLeft; 
	// Call XCode Function
}

Obviously it expands out to any of the different orientations you need to support. Just run those checks in an update, or to save some processing possibly a coroutine that only polls once a second.

Then inside the XCode Callback function, I perform manual rotations as follows.

// Rotates to landscape right (thats the home button on the right as per Apple documents, not Landscape right which has the home button on the left like the Unity Documents)
CGAffineTransform tr = CGAffineTransformRotate(tr, degreesToRadians(90));
containerView.transform = tr;
containerView.center = window.center;

If you aren’t using iPhone Advanced this will be much harder to do as you can’t call native functions directly, however you could do the PlayerPrefs monitoring method.

Thanks, Murcho.

I found another more simple way:

if you commt out the following line in AppController.mm:

//iphone::KeyboardOnScreen::Init();

…then the autorotation actually works!!!

Nice one, will give it a go.