egret-docs-master/Engine3D/Egret3DCamera/animation/README.md

154 lines
4.5 KiB
Markdown
Raw Permalink Normal View History

2024-06-19 13:32:32 +08:00
在3D Max中可以通过时间轴制作摄像机动画你可以通过Egret3D所提供得插件将制作好的摄像机动画导出为`eca`格式文件,并通过在程序中对该文件的解析,生成摄像机动画。
为了方便查看效果我们首先在3D MAX中制作一个简单的摄像机动画。3D MAX中场景如下
![](575cd31ccd58b.png)
摄像机运动轨迹如下:
![](575cd3235cbe6.gif)
我们以摄像机视角,查看整个场景运行效果如图:
![](575cd32284507.gif)
通过Egret3D插件导出其动画文件名称为`Camera001.eca`,由于当前场景中摄像机名称为`Camera001`,所有导出文件保留其元素命名。
你需要借助`URLLoader`类来加载`Camera001.eca`文件,当文件加载完成后,得到的数据`evt.target.data`其数据类型为`egret3d.CameraAnimationController`。
在Egret3D中控制摄像机的动画类由`CameraAnimationController`实现,每一帧中的数据由`CameraAnimationFrame`实现。
当你的数据加载并解析完成后,你就可以使用这个`CameraAnimationController`。当在使用之前,你需要通过其中的`bindCamera`方法绑定要控制的摄像机。
具体编码步骤如下:
1、加载`eca`文件
```
var load:egret3d.URLLoader = new egret3d.URLLoader();
load.addEventListener(egret3d.LoaderEvent3D.LOADER_COMPLETE,this.com,this);
load.load("resource/Camera001.eca");
```
```
private ani:egret3d.CameraAnimationController;
private com(evt:egret3d.LoaderEvent3D)
{
this.ani = evt.target.data;
}
```
2、绑定摄像机
```
this.ani.bindCamera(this._view.camera3D);
```
3、注册刷新
```
this.canvas.addEventListener(egret3d.Event3D.ENTER_FRAME,this.update,this);
```
```
private update(evt:egret3d.Event3D)
{
this.ani.update(10,16);
}
```
每一次调用`CameraAnimationController`的`update`方法,才会更新一次摄像机动画。每一次更新,`update`方法需要两个参数。第一个参数为当前时间,第二个参数为每帧时间间隔。
4、播放动画
```
this.ani.play(true);
```
`play`方法中,参数如果为`true`,则摄像机动画循环播放。
5、暂停动画
```
this.ani.stop();
```
6、监听动画播放完毕事件
```
this.ani.addEventListener(egret3d. CameraAnimationController.EVENT_CAMERA_COMPLETE,this.AniComplete,this);
```
摄像机动画的事件直接封装到了`CameraAnimationController`中,并没有单独放置于独立的事件类中。
上述示例完整代码如下:
```
class CameraAni extends LoadingUI
{
private _view:egret3d.View3D;
protected canvas:egret3d.Egret3DCanvas;
public constructor()
{
super();
this.CloseLoadingView();
this.canvas = new egret3d.Egret3DCanvas();
this.canvas.x = 0;
this.canvas.y = 0;
this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight;
this.canvas.start();
this._view = new egret3d.View3D(0,0,window.innerWidth,window.innerHeight);
this.canvas.addView3D(this._view);
this._view.backColor = 0x00ff00;
this.createCub();
this._view.camera3D.lookAt(new egret3d.Vector3D(300, 500, -1000), new egret3d.Vector3D(0, 0, 0));
var load:egret3d.URLLoader = new egret3d.URLLoader();
load.addEventListener(egret3d.LoaderEvent3D.LOADER_COMPLETE,this.com,this);
load.load("resource/Camera001.eca");
}
private cube:egret3d.Mesh;
private mat:egret3d.TextureMaterial;
private createCub()
{
var mat:egret3d.TextureMaterial = new egret3d.TextureMaterial();
var go:egret3d.CubeGeometry = new egret3d.CubeGeometry(10,10,10);
var cube:egret3d.Mesh = new egret3d.Mesh(go, mat);
this._view.addChild3D(cube);
}
private ani:egret3d.CameraAnimationController;
private com(evt:egret3d.LoaderEvent3D)
{
this.ani = evt.target.data;
this.ani.bindCamera(this._view.camera3D);
this.ani.play(true);
this.canvas.addEventListener(egret3d.Event3D.ENTER_FRAME,this.update,this);
}
private update(evt:egret3d.Event3D)
{
this.ani.update(10,16);
}
}
```
编译并运行,效果如图:
![](575cd31ce7598.gif)
## 摄像机帧数据
由于摄像机动画相对比较简单,不涉及变形等信息,只包含了时间和摄像机在三维空间中的运动轨迹于姿态。你可以通过`CameraAnimationController`类中的`cameraAnimationFrames`属性获取当前摄像机动画的全部帧数据。每个帧数据的内容可参考`CameraAnimationFrame`类的API内容。