接下来说下UI界面与3D界面的交互。前面的介绍已经讲过,要想在UIWidgets中刷新3D的场景,需要修改一下帧率的设置 。在挂载到panel上的脚本添加刷新同步的脚本,并把目标帧率设置成60帧。
public class ViewerApp : UIWidgetsPanel
{
protected override void OnEnable()
{
base.OnEnable();
Window.onFrameRateSpeedUp = () => { };
Window.onFrameRateCoolDown = CustomFrameRateCoolDown;
}
static void CustomFrameRateCoolDown()
{
Application.targetFrameRate = 60;
}
当点击场景详情进入AR交互时,会把fltter的背景设置透明。但这时候就有个问题,因为是用push的方式进入的AR交互界面也会有flutter的UI,如果把背景设置成透明的话,会把上一层的页面也显示出来。这种情况一般有两种处理手段,一种是把3D的场景中摄像机看到的东西保存成rendererTexture,并且把这个renderTextue设置成当前界面的一个背景,每帧都在实时刷新;另一种方式就比较取巧:把背景设置成透明,详情界面与3D操作界面在同一个界面平铺在一起,当进入详情界面时只显示详情信息,而3D的界面会叠在详情的上或者右的位置,当点击进入3D交互时,整个界面向下移动一个界面的高度,或者向左移动一个界面的宽度。
这个动画的实现需要用到flutter里的动画控制器,并且配置stack组件来实现
public class ProjectDetailScreenState : State<ProjectDetaiScreen>, TickerProvider
{
public Ticker createTicker(TickerCallback onTick)
{
return new Ticker(onTick);
}
AnimationController animationContrller;
Animation<Offset> animation;
public override void initState()
{
animationContrller = new AnimationController(
duration:TimeSpan.FromMilliseconds(300),
vsync: this
);
animationContrller.addStatusListener((status)=>
{
//if (status == AnimationStatus.completed)
//{
// animationContrller.reverse();
//}
// else if()
});
animation =new OffsetTween(begin:Offset.zero,end:new Offset(-1,0)).chain(new CurveTween(curve: Curves.linear)).animate(animationContrller);
}
//.....
}
上面的代码段是创建一个动画控制器,同时再添加一个位置偏移的Tween,当进入3D界面时触发时会执行这个位置的偏移;当从3D界面返回时会调用reverse的方法反转偏移。
public override Widget build(BuildContext context)
{
return new Stack(
alignment:Alignment.center,
fit:StackFit.expand,
children:new List<Widget>()
{
new 3DInteration(animationContrller),
new Container(child:
new SlideTransition(
position:animation,
child:Detail())
)
}
);
}