Works in Editor, Doesn't on iPad

I’ve never seen this before, at least not such major problems. The app works perfectly in the editor, but has all sorts of problems on iPad. Colliders don’t seem to be working, at least in part. Most objects just fall right through the floor, but a few don’t. Some kinematic objects aren’t there, I’m guessing because they’re positioned below the floor. And at least one texture (transparent/diffuse) isn’t drawn with the correct color – the texture’s color is changed when its object is selected, and the highlight color is always black on iPad (should be various other colors).

Beyond these obvious problems, I can’t really test much of anything else as the basic functionality of adding an object to the scene doesn’t work. The objects immediately fall through the floor, and I can no longer see them. It looks like maybe the collider for the floor has moved down below where the floor is, but I can’t really tell. I’m not sure why it would move at all, as it has no rigidbody and is set to static, as are all other non-moving environment objects.

Any suggestions? I can’t find anything that’s set incorrectly in the player or other settings. Everything’s set the way it always is in every other project. I don’t even know where to begin to try tracking down this problem.

These are the only errors I see in the console, and I have no idea what they mean or if they have anything to do with the problems I’m seeing:

May 11 13:35:22 John-Bs-iPad-Air DGame[2451] : → registered mono modules 0x12ecd80
May 11 13:35:22 John-Bs-iPad-Air backboardd[2048] : HID: The ‘Passive’ connection ‘DGame’ access to protected services is denied.
May 11 13:35:23 John-Bs-iPad-Air backboardd[2048] : CoreAnimation: updates deferred for too long
May 11 13:35:23 John-Bs-iPad-Air backboardd[2048] : CoreAnimation: timed out fence 2cbdf

I don’t know why, but it is definitely NOT seeing the floor collider. A raycast down hits the floor in the editor, as it should, but hits nothing on iPad. I don’t get it.

Most iOS devices are still using VFP in FTZ mode and if some of your colliders are very thin, then simulation outcome on iPad might be different than on desktop. What kind of collider are you using for floor collisions? Are you moving objects with Transform.Translate() ?

The floor is an empty object, marked static, with a box collider attached, trigger off. The other objects in the scene also have colliders, but they are attached to gameObjects, and some have rigidbodies, but none are static.

The problem is not with moving objects, but with a raycast. When a new object is created and added to the scene, it’s instantiated high above, and it casts a ray downward to see what’s below, the floor or another object it would rest upon. The raycast hits nothing about 9 out of 10 times. Every once in a while it will hit the floor or whatever object is already sitting there, apparently at random. There’s nowhere an object can appear that it should’t at least hit the floor.

For a quick fix to further test it, I added a check to make sure an object can’t be placed below the floor, but that doesn’t help with other objects, since I have no way of knowing the height of any particular object at any particular location. Hence the raycast to see what’s there.

Sounds like a bug. Could you please submit a bugreport?

It’s been a while since I’ve been able to get back to this problem, and now the app won’t run at all on iPad. It crashes with a bad access error with the splash screen showing. I tracked the crash down to this function:

function GetPieceHeight (thePos: Vector3, theType: PieceType): float {
    var tPos: Vector3;
    var theHeight: float;
    var hit: RaycastHit;  
  
    theHeight = 999.0;
  
    if (theType == PieceType.dNone) {
        tPos = thePos;
        if (Physics.Raycast(tPos, -Vector3.up, hit)) {
            if (hit.distance < theHeight)
                theHeight = hit.distance;
        }      
    }
...
    theHeight = (tPos.y - theHeight) + 0.000005;
    return theHeight;
}

The interesting thing is that this is the function that does the raycast that never hits anything on iPad. So I’m thinking the bad access crash I’m seeing now is related to the not hitting colliders problem I was seeing before.

There are other if/then conditions in this function, and it crashes regardless of what theType equals. But this is the condition that’s true when this function is called on Start, and it crashes with the splash screen showing. I see nothing that should cause any problems, all variables have the values they should. But if I don’t call this function, there’s no crash. If I call the function, there’s a bad access error. And there’s no way the raycast should not at least hit the floor.

It turns out I was trying to display the name of the hit collider (right after the code shown above) to help me debug the not hitting a collider problem, and that was causing the crash (because there was no hit). The problem is that the argument theType is not being passed correctly (on iPad only), and the if/then was not being executed at all.

If I display the value of theType in the Unity editor, it’s always correct when no object is selected (theType = dNone), but when running on iPad, theType is some crazy 9 digit integer value. I don’t see how that’s even possible. The function is called with this line:

theY = GetPieceHeight(thePos, PieceType.dNone);

How can it call the function with a constant value of dNone, but the function gets a value like 492468311? How is it possible for an enumerated variable to change value?

Doing some more digging, and I’m even more confused. The GetHeight function gets passed the correct value the first time only, when its called on launch. After that, it gets a random, large integer.

The function call appears to be correct and passing the correct value:

debugText.Text = parseInt(PieceType.dNone).ToString(); // this displays 0, as it should
theY = GetPieceHeight(thePos, PieceType.dNone);

The function however appears to be receiving a different number:

function GetPieceHeight (thePos: Vector3, theType: PieceType): float {
   debugText.Text = parseInt(theType).ToString(); // this displays something like 429497020
}

This only passes the wrong value when running on iPad!