homeへのリンクです。

FlashCS4の3Dの重なり順の話

2008年11月29日

F-Siteのセミナーに行って、野中先生の3Dの講義を聞いてきました。

サンプルをそのままコピーしたものが下になります。

ぺらぺらなのもなんなので、もう少し立体ぽくしたいなと思ってSpriteを4枚にしてみたのが下になります。

3DのZ座標の前後関係よりも、Spriteの重なり順の方が優先されるようで、複数のSpriteを3D的に動かそうとすると、前後関係がおかしくなってしまいます。

そこで、Z座標の前後関係を自分で調整すると下のようになります。


コードは以下のような感じです。
重要な部分は野中先生のコードの受け売りです。

// タイムライン: メイン
// 第1フレームアクション
var nX:Number = mySprite.x;
var nY:Number = mySprite.y;
var nDeceleration:Number = 0.1;
mySprite.z = 0;
var spriteParts:Array=[mySprite.front,mySprite.back,mySprite.top,mySprite.bottom];
addEventListener(Event.ENTER_FRAME, xRotate);
function xRotate(eventObject:Event):void {
  var nRotationY:Number = (mouseX - nX)*nDeceleration;
  var nRotationX:Number = (mouseY - nY)*nDeceleration;
  // 3次元座標空間でインスタンスを回転
  mySprite.transform.matrix3D.appendTranslation(-nX, -nY, 0);   // 親タイムラインの基準点に移動
  for(var i:uint=0;i<spriteParts.length;i++){
	  Sprite(spriteParts[i]).transform.matrix3D.appendRotation(nRotationY,Vector3D.Y_AXIS);
	  Sprite(spriteParts[i]).transform.matrix3D.appendRotation(nRotationX,Vector3D.X_AXIS);
  }
  mySprite.transform.matrix3D.appendTranslation(nX, nY, 0);   // 位置を戻す
  spriteParts.sort(sortOnZ);
  for(var j:uint=0;j<spriteParts.length;j++){
	  mySprite.setChildIndex(spriteParts[j],j);
  }
  function sortOnZ(a:Sprite, b:Sprite):Number {
    var aZ:Number = a.z;
    var bZ:Number = b.z;
    if(aZ > bZ) {
        return 1;
    } else if(aZ < bZ) {
        return -1;
    } else  {
        //aZ == bZ
        return 0;
    }
  }
} 

ちょっとしたポイントは、キューブ状に配置したMCを回転させてしまうと、z座標が変わらないので、各パネルのMCをそれぞれ別々に回転させた後、zの値でソートして、重ね順を変える、という点。

自分でやらないでもCS4でちゃんとしてくれる方法とかあるのだろうか?