几个重要的点:
1、自定义移动时间
2、移动过程中产生动画
3、到达终点位置
从网上找了一些大神发的代码,发现一秒到达终点,并没有动画的效果。阅读代码发现并没有做位移动画的处理,修改了一下供大家使用:
目前还存在的问题:运动方式效果没有生效
export default class Sprite3DMoveContorller {
static frompostion: Laya.Vector3;
static topostion: Laya.Vector3;
static moveDistance: Laya.Vector3;
static moveObjcet: Laya.Sprite3D;
static moveTime: number = 0;
static moveValue: number = 0.01;
static callback: Function;
static obj: any;
/**
* Sprite3D移动方法
* @param gameObject 需要移动的3D对象
* @param toPos 移动目标点
* @param playTime 移动总耗时
* @param easeFun 缓动函数 (Laya.Ease) 默认为线性移动
* @param obj 回调域
* @param callback 回调函数
*/
public static onPositionMoveTo(gameObject: Laya.Sprite3D, toPos: Laya.Vector3, playValue: number, easeFun: Function, obj: any = null, callback: Function = null) {
this.moveDistance = new Laya.Vector3(toPos.x - gameObject.transform.position.x, toPos.y - gameObject.transform.position.y, toPos.z - gameObject.transform.position.z);
this.frompostion = gameObject.transform.position;
this.topostion = toPos;
this.moveObjcet = gameObject;
this.moveValue = playValue;
this.callback = callback;
this.obj = obj;
this.startMove();
}
private static startMove() {
Laya.timer.frameLoop(1, this, this.moveUpdate);
}
private static endMove(handler: Laya.Handler) {
Laya.timer.clear(this, this.moveUpdate);
//this.moveObjcet.transform.position = this.topostion;
console.log(handler);
if (handler != null) {
handler.run();
}
}
private static moveUpdate() {
this.moveTime += 1;
let a = Laya.Vector3.distance(this.moveObjcet.transform.position, this.topostion);
if (a < 0.1) {
this.endMove(Laya.Handler.create(this.obj, this.callback));
} else {
this.moveObjcet.transform.position = new Laya.Vector3(
this.frompostion.x + (this.moveDistance.x / this.moveValue * this.moveTime),
this.frompostion.y + (this.moveDistance.y / this.moveValue * this.moveTime),
this.frompostion.z + (this.moveDistance.z / this.moveValue * this.moveTime)
);
}
}
}
调用方式:
//先引入
import Sprite3DMoveContorller from "./../common/Sprite3DMoveContorller"
//在需要的地方调用
Sprite3DMoveContorller.onPositionMoveTo(target, position, 1000, Laya.Ease);
target:需要移动的目标 ,一般是 Laya.sprite3D 对象
position:终点坐标,一个三维向量
1000:大概是毫秒吧,这里也有问题,还没有处理好。
二更:
今天在使用的时候,发现多移动几个点后,就会出现问题,被移动的物体会被无限移走,越来越远。
仔细查看代码,发现有一处写法是:
去固定判断这个值为是否小于0.1,打印了出问题的值,a会先变小,后变大,永远不会小于0.1,这是因为计算机在进行计算时,会有一定的精度丢失。所以我们要记录一下这个值,当新计算得出的 a 比之前记录的值大时,就算作结束了。
下面为修改后的新代码:
export default class Sprite3DMoveContorller {
static frompostion: Laya.Vector3;
static topostion: Laya.Vector3;
static moveDistance: Laya.Vector3;
static moveObjcet: Laya.Sprite3D;
static moveTime: number = 0;
static moveValue: number = 0.01;
static callback: Function;
static obj: any;
static _lastDistance: number;
/**
* Sprite3D移动方法
* @param gameObject 需要移动的3D对象
* @param toPos 移动目标点
* @param playTime 移动总耗时
* @param easeFun 缓动函数 (Laya.Ease) 默认为线性移动
* @param obj 回调域
* @param callback 回调函数
*/
public static onPositionMoveTo(gameObject: Laya.Sprite3D, toPos: Laya.Vector3, playValue: number, easeFun: Function, obj: any = null, callback: Function = null) {
this.moveDistance = new Laya.Vector3(toPos.x - gameObject.transform.position.x, toPos.y - gameObject.transform.position.y, toPos.z - gameObject.transform.position.z);
this.frompostion = gameObject.transform.position;
this.topostion = toPos;
this.moveObjcet = gameObject;
this.moveValue = playValue;
this.callback = callback;
this.obj = obj;
this.endMove(Laya.Handler.create(this.obj, this.callback));
this.startMove();
this._lastDistance = 0;
this.moveTime = 0;
}
private static startMove() {
Laya.timer.frameLoop(1, this, this.moveUpdate);
}
private static endMove(handler: Laya.Handler) {
Laya.timer.clear(this, this.moveUpdate);
//this.moveObjcet.transform.position = this.topostion;
if (handler != null) {
handler.run();
}
}
private static moveUpdate() {
this.moveTime += 1;
let a = Laya.Vector3.distance(this.moveObjcet.transform.position, this.topostion);
console.log(a, this._lastDistance, this.moveTime)
if (a > this._lastDistance && this.moveTime > 1) {
this.endMove(Laya.Handler.create(this.obj, this.callback));
} else {
this.moveObjcet.transform.position = new Laya.Vector3(
this.frompostion.x + (this.moveDistance.x / this.moveValue * this.moveTime),
this.frompostion.y + (this.moveDistance.y / this.moveValue * this.moveTime),
this.frompostion.z + (this.moveDistance.z / this.moveValue * this.moveTime)
);
}
this._lastDistance = a;
}
}