玩法 / ProjectileMovement
ProjectileMovement Class
投掷物移动功能类
ProjectileMovement 是一种功能组件,用于处理游戏中的飞行物体,比如子弹、火箭、投掷物等。
想象一下,你在游戏中控制着一个角色,你想让他发射一颗子弹。这时,你可以使用 ProjectileMovement 组件来处理子弹的移动。
这个组件的作用就像是给子弹贴上一个引擎,让它能够自动进行飞行。你只需要设置子弹的速度和方向,组件就会根据这些参数自动计算子弹的轨迹,并将其移动到正确的位置。这样,你就不需要手动编写复杂的移动逻辑,而是交给 ProjectileMovement 来处理。
除了基本的移动功能,ProjectileMovement 还提供了一些其他的特性。例如,你可以设置子弹的最大飞行距离或生命周期,超过这个距离或时间后,子弹会自动销毁。还可以设置子弹的碰撞检测,当子弹与其他物体碰撞时,可以触发相应的效果或伤害。
绑定的逻辑对象请自行关闭物理模拟,运动过程中会忽略相机、禁行区、功能类不考虑移动同步。
Implements
Table of contents
Properties
onProjectileHit: MulticastDelegate <(hitGameObject : GameObject , hitResult : HitResult ) => void > |
---|
投掷物击中物体时触发绑定函数 |
onProjectileHomingFail: MulticastDelegate <() => void > |
投掷物追踪失败触发绑定函数(追踪失败特指追踪目标消失,当且仅当这个情况触发一次) |
onProjectileLifeEnd: MulticastDelegate <() => void > |
投掷物结束运动周期时触发绑定函数 |
owner: Character |
投掷物对象的持有人,便于用户指定发射的角色对象。 |
Accessors
acceleration(): number |
---|
投掷物运动的加速度(cm/s),正值会使投掷物加速,负值减速。default: 0,range: [-10000,10000]。 |
gravityScale(): number |
投掷物受世界重力影响的倍率,正值会使投掷物下坠,负值上升,0可以使投掷物以直线运动。default: 1,range: [-10, 10]。 |
homingAcceleration(): number |
朝向目标对象的加速度(cm/s)。default: 10000。range: [0, 10000]。 |
homingTarget(): GameObject |
投掷物追踪的目标对象,当目标对象不为空时,对象会向目标加速。default: null。 |
initialSpeed(): number |
投掷物的初始运动速度(cm/s),default: 5000,range: [1,100000],发射之后设置不会生效 |
isRotationFollowsVelocity(): boolean |
投掷物的正方向(以及挂载对象)是否始终跟随运动方向。true:跟随。false:不跟随。default: true。 |
lifeSpan(): number |
投掷物存在的最长时间(s),0意味着没有限制。default: 10。range: [0, 1000]。 |
maxSpeed(): number |
投掷物的最大运动速度(cm/s),0意味着没有限制。default: 0,range: [0,100000]。 |
speedRetention(): number |
碰撞后投掷物保持原来速度的比例。0表示碰撞后速度直接清零。default: 0.6。range: [0, 1]。 |
status(): ProjectileMovementStatus |
投掷物当前状态 |
Methods
destroy([destroy](mw.ProjectileMovement.md#destroy)WithObject? ): void |
---|
销毁投掷物,即销毁对象下的移动组件和碰撞组件。可以选择是否和关联的对象一起销毁。 |
getRelatedGameObject(): GameObject |
获取关联的逻辑对象 |
getTrajectory(startDirection : Vector , density : number , duration : number ): Vector [] |
获取预测出的运动轨迹 |
getVelocity(): Vector |
获取当前速度 |
launch(direction : Vector ): void |
发射 |
pause(): void |
暂停运动,将由 Launched 状态切换到 Ready 状态 |
resume(): void |
继续运动,将由 Ready 状态切换到 Launched 状态 |
setRelatedGameObject(value : GameObject ): void |
设置新的关联的逻辑对象 |
setVelocity(v : Vector ): void |
设置当前速度 |
通过配置对象构造功能类
Parameters
relatedGameObject GameObject | 新的关联的逻辑对象,将为之生成组件 |
---|---|
config? ProjectileMovementConfig | 批量读取配置 default: null |
Properties
onProjectileHit
• onProjectileHit: MulticastDelegate
<(hitGameObject
: GameObject
, hitResult
: HitResult
) => void
>
投掷物击中物体时触发绑定函数
onProjectileHomingFail
• onProjectileHomingFail: MulticastDelegate
<() => void
>
投掷物追踪失败触发绑定函数(追踪失败特指追踪目标消失,当且仅当这个情况触发一次)
onProjectileLifeEnd
• onProjectileLifeEnd: MulticastDelegate
<() => void
>
投掷物结束运动周期时触发绑定函数
owner
• owner: Character
投掷物对象的持有人,便于用户指定发射的角色对象。
Accessors
acceleration
• | • | ||||
---|---|---|---|---|---|
投掷物运动的加速度(cm/s),正值会使投掷物加速,负值减速。default: 0,range: [-10000,10000]。 Returns
| 投掷物运动的加速度(cm/s),正值会使投掷物加速,负值减速。default: 0,range: [-10000,10000]。 Parameters
Implementation of |
gravityScale
• | • | ||||
---|---|---|---|---|---|
投掷物受世界重力影响的倍率,正值会使投掷物下坠,负值上升,0可以使投掷物以直线运动。default: 1,range: [-10, 10]。 Returns
| 投掷物受世界重力影响的倍率,正值会使投掷物下坠,负值上升,0可以使投掷物以直线运动。default: 1,range: [-10, 10]。 Parameters
Implementation of |
homingAcceleration
• | • | ||||
---|---|---|---|---|---|
朝向目标对象的加速度(cm/s)。default: 10000。range: [0, 10000]。 Returns
| 朝向目标对象的加速度(cm/s)。default: 10000。range: [0, 10000]。 Parameters
Implementation of |
homingTarget
• | • | ||||
---|---|---|---|---|---|
投掷物追踪的目标对象,当目标对象不为空时,对象会向目标加速。default: null。 Returns
| 投掷物追踪的目标对象,当目标对象不为空时,对象会向目标加速。default: null。 Parameters
Implementation of |
initialSpeed
• | • | ||||
---|---|---|---|---|---|
投掷物的初始运动速度(cm/s),default: 5000,range: [1,100000],发射之后设置不会生效 Returns
| 投掷物的初始运动速度(cm/s),default: 5000,range: [1,100000],发射之后设置不会生效 Parameters
Implementation of |
isRotationFollowsVelocity
• | • | ||||
---|---|---|---|---|---|
投掷物的正方向(以及挂载对象)是否始终跟随运动方向。true:跟随。false:不跟随。default: true。 Returns
| 投掷物的正方向(以及挂载对象)是否始终跟随运动方向。true:跟随。false:不跟随。default: true。 Parameters
Implementation of |
lifeSpan
• | • | ||||
---|---|---|---|---|---|
投掷物存在的最长时间(s),0意味着没有限制。default: 10。range: [0, 1000]。 Returns
| 投掷物存在的最长时间(s),0意味着没有限制。default: 10。range: [0, 1000]。 Parameters
Implementation of |
maxSpeed
• | • | ||||
---|---|---|---|---|---|
投掷物的最大运动速度(cm/s),0意味着没有限制。default: 0,range: [0,100000]。 Returns
| 投掷物的最大运动速度(cm/s),0意味着没有限制。default: 0,range: [0,100000]。 Parameters
Implementation of |
speedRetention
• | • | ||||
---|---|---|---|---|---|
碰撞后投掷物保持原来速度的比例。0表示碰撞后速度直接清零。default: 0.6。range: [0, 1]。 Returns
| 碰撞后投掷物保持原来速度的比例。0表示碰撞后速度直接清零。default: 0.6。range: [0, 1]。 Parameters
Implementation of |
status
• |
---|
投掷物当前状态 Returns |
ProjectileMovementStatus |
---|
Methods
destroy
• destroy(destroyWithObject?
): void
销毁投掷物,即销毁对象下的移动组件和碰撞组件。可以选择是否和关联的对象一起销毁。
Parameters
destroyWithObject? boolean | 是否与对象一起删除 default: true |
---|
ts
@Component
export default class Example_ProjectileMovement_Destroy extends Script {
protected async onStart(): Promise<void> {
// 下列逻辑在服务端执行
if(SystemUtil.isServer()) {
// 创建一个模型数组balls和标识curBall。
let balls = new Array<Model>();
let curBall = 0;
// 在前方异步生成5个球,放入数组balls中。
for (let i = 0;
i < 5;
i++) {
let ball = await GameObject.asyncSpawn("84121") as Model;
ball.worldTransform.position = new Vector(200, i * 100, 25);
ball.name = "ball" + i;
ball.setCollision(CollisionStatus.QueryCollisionOnly);
balls.push(ball);
}
// 创建投掷物。
let projectile = new ProjectileMovement(balls[curBall]);
// 设置初始发射速度为1000。
projectile.initialSpeed = 1000;
// 给击中委托绑定一个函数,当击中对象是目标时,播放一个击中特效,0.5s后删除目标。
projectile.onProjectileHit.add((hitGameObject, HitResult) => {
EffectService.playAtPosition("99599", HitResult.impactPoint, {scale: new Vector(5, 5, 5)});
});
// 添加客户端发送的”LAUNCH“事件监听器,将球右前方发射。
Event.addClientListener("LAUNCH", async (player: Player) => {
projectile.launch(new Vector(1, 1, 1));
});
// 添加客户端发送的”DESTROY“事件监听器,从数组里面删除球对象,并切换投掷物关联的对象。
Event.addClientListener("DESTROY", async (player: Player) => {
console.error("DESTROY");
let deleteBall = projectile.getRelatedGameObject() as Model;
let deleteIndex = balls.indexOf(deleteBall);
balls.splice(deleteIndex, 1);
if(balls.length > 0) {
curBall = (deleteIndex) % balls.length;
projectile.setRelatedGameObject(balls[curBall]);
deleteBall.destroy();
} else {
projectile.destroy(true);
}
});
}
// 下列逻辑在客户端执行
if(SystemUtil.isClient()) {
// 添加一个按键方法:按下按键”1“,向服务端派送一个”LAUNCH“事件,发射球。
InputUtil.onKeyDown(Keys.One, () => {
Event.dispatchToServer("LAUNCH");
});
// 添加一个按键方法:按下按键”2“,向服务端派送一个”DESTROY“事件,切换至下一个球并删除上一个。
InputUtil.onKeyDown(Keys.Two, () => {
Event.dispatchToServer("DESTROY");
});
}
}
}
@Component
export default class Example_ProjectileMovement_Destroy extends Script {
protected async onStart(): Promise<void> {
// 下列逻辑在服务端执行
if(SystemUtil.isServer()) {
// 创建一个模型数组balls和标识curBall。
let balls = new Array<Model>();
let curBall = 0;
// 在前方异步生成5个球,放入数组balls中。
for (let i = 0;
i < 5;
i++) {
let ball = await GameObject.asyncSpawn("84121") as Model;
ball.worldTransform.position = new Vector(200, i * 100, 25);
ball.name = "ball" + i;
ball.setCollision(CollisionStatus.QueryCollisionOnly);
balls.push(ball);
}
// 创建投掷物。
let projectile = new ProjectileMovement(balls[curBall]);
// 设置初始发射速度为1000。
projectile.initialSpeed = 1000;
// 给击中委托绑定一个函数,当击中对象是目标时,播放一个击中特效,0.5s后删除目标。
projectile.onProjectileHit.add((hitGameObject, HitResult) => {
EffectService.playAtPosition("99599", HitResult.impactPoint, {scale: new Vector(5, 5, 5)});
});
// 添加客户端发送的”LAUNCH“事件监听器,将球右前方发射。
Event.addClientListener("LAUNCH", async (player: Player) => {
projectile.launch(new Vector(1, 1, 1));
});
// 添加客户端发送的”DESTROY“事件监听器,从数组里面删除球对象,并切换投掷物关联的对象。
Event.addClientListener("DESTROY", async (player: Player) => {
console.error("DESTROY");
let deleteBall = projectile.getRelatedGameObject() as Model;
let deleteIndex = balls.indexOf(deleteBall);
balls.splice(deleteIndex, 1);
if(balls.length > 0) {
curBall = (deleteIndex) % balls.length;
projectile.setRelatedGameObject(balls[curBall]);
deleteBall.destroy();
} else {
projectile.destroy(true);
}
});
}
// 下列逻辑在客户端执行
if(SystemUtil.isClient()) {
// 添加一个按键方法:按下按键”1“,向服务端派送一个”LAUNCH“事件,发射球。
InputUtil.onKeyDown(Keys.One, () => {
Event.dispatchToServer("LAUNCH");
});
// 添加一个按键方法:按下按键”2“,向服务端派送一个”DESTROY“事件,切换至下一个球并删除上一个。
InputUtil.onKeyDown(Keys.Two, () => {
Event.dispatchToServer("DESTROY");
});
}
}
}
getRelatedGameObject
• getRelatedGameObject(): GameObject
获取关联的逻辑对象
Returns
GameObject | 关联的逻辑对象 |
---|
ts
@Component
export default class Example_ProjectileMovement extends Script {
protected async onStart(): Promise<void> {
// 下列逻辑在服务端执行
if(SystemUtil.isServer()) {
// 创建一个模型数组balls和标识curBall。
let balls = new Array<Model>();
let curBall = 0;
// 在前方异步生成5个球,放入数组balls中。
for (let i = 0;
i < 5;
i++) {
let ball = await GameObject.asyncSpawn("84121") as Model;
ball.worldTransform.position = new Vector(200, i * 100, 25);
ball.name = "ball" + i;
ball.setCollision(CollisionStatus.QueryCollisionOnly);
balls.push(ball);
}
// 创建投掷物。
let projectile = new ProjectileMovement(balls[curBall]);
// 设置初始发射速度为1000。
projectile.initialSpeed = 1000;
// 给击中委托绑定一个函数,当击中对象是目标时,播放一个击中特效,0.5s后删除目标。
projectile.onProjectileHit.add((hitGameObject, HitResult) => {
EffectService.playAtPosition("99599", HitResult.impactPoint, {scale: new Vector(5, 5, 5)});
});
// 添加客户端发送的”LAUNCH“事件监听器,将球右前方发射。
Event.addClientListener("LAUNCH", async (player: Player) => {
projectile.launch(new Vector(1, 1, 1));
});
// 添加客户端发送的”DESTROY“事件监听器,从数组里面删除球对象,并切换投掷物关联的对象。
Event.addClientListener("DESTROY", async (player: Player) => {
console.error("DESTROY");
let deleteBall = projectile.getRelatedGameObject() as Model;
let deleteIndex = balls.indexOf(deleteBall);
balls.splice(deleteIndex, 1);
if(balls.length > 0) {
curBall = (deleteIndex) % balls.length;
projectile.setRelatedGameObject(balls[curBall]);
deleteBall.destroy();
} else {
projectile.destroy(true);
}
});
}
// 下列逻辑在客户端执行
if(SystemUtil.isClient()) {
// 添加一个按键方法:按下按键”1“,向服务端派送一个”LAUNCH“事件,发射球。
InputUtil.onKeyDown(Keys.One, () => {
Event.dispatchToServer("LAUNCH");
});
// 添加一个按键方法:按下按键”2“,向服务端派送一个”DESTROY“事件,切换至下一个球并删除上一个。
InputUtil.onKeyDown(Keys.Two, () => {
Event.dispatchToServer("DESTROY");
});
}
}
}
@Component
export default class Example_ProjectileMovement extends Script {
protected async onStart(): Promise<void> {
// 下列逻辑在服务端执行
if(SystemUtil.isServer()) {
// 创建一个模型数组balls和标识curBall。
let balls = new Array<Model>();
let curBall = 0;
// 在前方异步生成5个球,放入数组balls中。
for (let i = 0;
i < 5;
i++) {
let ball = await GameObject.asyncSpawn("84121") as Model;
ball.worldTransform.position = new Vector(200, i * 100, 25);
ball.name = "ball" + i;
ball.setCollision(CollisionStatus.QueryCollisionOnly);
balls.push(ball);
}
// 创建投掷物。
let projectile = new ProjectileMovement(balls[curBall]);
// 设置初始发射速度为1000。
projectile.initialSpeed = 1000;
// 给击中委托绑定一个函数,当击中对象是目标时,播放一个击中特效,0.5s后删除目标。
projectile.onProjectileHit.add((hitGameObject, HitResult) => {
EffectService.playAtPosition("99599", HitResult.impactPoint, {scale: new Vector(5, 5, 5)});
});
// 添加客户端发送的”LAUNCH“事件监听器,将球右前方发射。
Event.addClientListener("LAUNCH", async (player: Player) => {
projectile.launch(new Vector(1, 1, 1));
});
// 添加客户端发送的”DESTROY“事件监听器,从数组里面删除球对象,并切换投掷物关联的对象。
Event.addClientListener("DESTROY", async (player: Player) => {
console.error("DESTROY");
let deleteBall = projectile.getRelatedGameObject() as Model;
let deleteIndex = balls.indexOf(deleteBall);
balls.splice(deleteIndex, 1);
if(balls.length > 0) {
curBall = (deleteIndex) % balls.length;
projectile.setRelatedGameObject(balls[curBall]);
deleteBall.destroy();
} else {
projectile.destroy(true);
}
});
}
// 下列逻辑在客户端执行
if(SystemUtil.isClient()) {
// 添加一个按键方法:按下按键”1“,向服务端派送一个”LAUNCH“事件,发射球。
InputUtil.onKeyDown(Keys.One, () => {
Event.dispatchToServer("LAUNCH");
});
// 添加一个按键方法:按下按键”2“,向服务端派送一个”DESTROY“事件,切换至下一个球并删除上一个。
InputUtil.onKeyDown(Keys.Two, () => {
Event.dispatchToServer("DESTROY");
});
}
}
}
getTrajectory
• getTrajectory(startDirection
, density
, duration
): Vector
[]
获取预测出的运动轨迹
Parameters
startDirection Vector | 发射方向 |
---|---|
density number | 预测点密度,等同于模拟的帧率 range: 不做限制,值越大轨迹越精细,性能消耗越大 type: 浮点数 |
duration number | 预测时长,等同于模拟时长 range: 不做限制,值越大轨迹轨迹越长,性能消耗越大 type: 浮点数 |
Returns
Vector [] | 轨迹点坐标数组 |
---|
Precautions
Launched 状态调用时不生效
getVelocity
• getVelocity(): Vector
获取当前速度
Returns
Vector | 当前速度 |
---|
ts
@Component
export default class Example_ProjectileMovement extends Script {
protected async onStart(): Promise<void> {
// 下列逻辑在服务端执行
if(SystemUtil.isServer()) {
// 在r(2000, 0, 0)生成一个火箭模型。
let rocket = await GameObject.asyncSpawn("162807") as Model;
rocket.worldTransform.position = new Vector(2000, 0, 0);
// 将火箭的碰撞状态修改为无碰撞
rocket.setCollision(CollisionStatus.Off);
// 创建投掷物。
let projectile = new ProjectileMovement(rocket);
// 设置初始发射速度为1。
projectile.initialSpeed = 1;
// 设置最大速度为1000。
projectile.maxSpeed = 1000;
// 设置发射加速度为200
projectile.acceleration = 200;
// 设置重力缩放为0。
projectile.gravityScale = 0;
// 设置投掷物旋转不跟随速度方向。
projectile.isRotationFollowsVelocity = false;
// 设置投掷物运动时间10秒。
projectile.lifeSpan = 10;
// 添加客户端发送的”LAUNCH“事件监听器,将火箭朝上方发射。
Event.addClientListener("LAUNCH", async (player: Player) => {
projectile.launch(new Vector(0, 0, 1));
// 广播客户端给火箭挂载尾焰特效
Event.dispatchToAllClient("TAIL", rocket.gameObjectId);
// 每0.1秒都会给客户端广播火箭当前速度
let scaleInterval = TimeUtil.setInterval(() => {
if(projectile.getVelocity().length > 999) {
projectile.setVelocity(Vector.zero);
TimeUtil.clearInterval(scaleInterval);
rocket.worldTransform.position = new Vector(2000, 0, 0);
}
Event.dispatchToAllClient("SCALING", rocket.gameObjectId, projectile.getVelocity());
}, 0.1);
});
}
// 下列逻辑在客户端执行
if(SystemUtil.isClient()) {
// 添加一个按键方法:按下按键”1“,向服务端派送一个”LAUNCH“事件,发射火箭
InputUtil.onKeyDown(Keys.One, () => {
Event.dispatchToServer("LAUNCH");
});
// 添加服务端发送的”TAIL“事件监听器,给火箭挂载尾焰。
Event.addServerListener("TAIL", async (rocketId: string) => {
let rocket = await GameObject.asyncFindGameObjectById(rocketId);
if(typeof(rocket.getChildByName("tail")) != "undefined") {
return;
}
let tail = await GameObject.asyncSpawn("144098") as Effect;
tail.name = "tail";
tail.parent = rocket;
tail.localTransform.position = Vector.zero;
});
// 添加服务端发送的”SCALING“事件监听器,根据速度对尾焰进行缩放
Event.addServerListener("SCALING", async (rocketId: string, velocity: Vector) => {
let rocket = await GameObject.asyncFindGameObjectById(rocketId);
let tail = rocket.getChildByName("tail");
if(tail) {
tail.worldTransform.scale = Vector.one.multiply(velocity.length / 250);
}
});
}
}
}
@Component
export default class Example_ProjectileMovement extends Script {
protected async onStart(): Promise<void> {
// 下列逻辑在服务端执行
if(SystemUtil.isServer()) {
// 在r(2000, 0, 0)生成一个火箭模型。
let rocket = await GameObject.asyncSpawn("162807") as Model;
rocket.worldTransform.position = new Vector(2000, 0, 0);
// 将火箭的碰撞状态修改为无碰撞
rocket.setCollision(CollisionStatus.Off);
// 创建投掷物。
let projectile = new ProjectileMovement(rocket);
// 设置初始发射速度为1。
projectile.initialSpeed = 1;
// 设置最大速度为1000。
projectile.maxSpeed = 1000;
// 设置发射加速度为200
projectile.acceleration = 200;
// 设置重力缩放为0。
projectile.gravityScale = 0;
// 设置投掷物旋转不跟随速度方向。
projectile.isRotationFollowsVelocity = false;
// 设置投掷物运动时间10秒。
projectile.lifeSpan = 10;
// 添加客户端发送的”LAUNCH“事件监听器,将火箭朝上方发射。
Event.addClientListener("LAUNCH", async (player: Player) => {
projectile.launch(new Vector(0, 0, 1));
// 广播客户端给火箭挂载尾焰特效
Event.dispatchToAllClient("TAIL", rocket.gameObjectId);
// 每0.1秒都会给客户端广播火箭当前速度
let scaleInterval = TimeUtil.setInterval(() => {
if(projectile.getVelocity().length > 999) {
projectile.setVelocity(Vector.zero);
TimeUtil.clearInterval(scaleInterval);
rocket.worldTransform.position = new Vector(2000, 0, 0);
}
Event.dispatchToAllClient("SCALING", rocket.gameObjectId, projectile.getVelocity());
}, 0.1);
});
}
// 下列逻辑在客户端执行
if(SystemUtil.isClient()) {
// 添加一个按键方法:按下按键”1“,向服务端派送一个”LAUNCH“事件,发射火箭
InputUtil.onKeyDown(Keys.One, () => {
Event.dispatchToServer("LAUNCH");
});
// 添加服务端发送的”TAIL“事件监听器,给火箭挂载尾焰。
Event.addServerListener("TAIL", async (rocketId: string) => {
let rocket = await GameObject.asyncFindGameObjectById(rocketId);
if(typeof(rocket.getChildByName("tail")) != "undefined") {
return;
}
let tail = await GameObject.asyncSpawn("144098") as Effect;
tail.name = "tail";
tail.parent = rocket;
tail.localTransform.position = Vector.zero;
});
// 添加服务端发送的”SCALING“事件监听器,根据速度对尾焰进行缩放
Event.addServerListener("SCALING", async (rocketId: string, velocity: Vector) => {
let rocket = await GameObject.asyncFindGameObjectById(rocketId);
let tail = rocket.getChildByName("tail");
if(tail) {
tail.worldTransform.scale = Vector.one.multiply(velocity.length / 250);
}
});
}
}
}
launch
• launch(direction
): void
发射
Parameters
direction Vector | 发射方向,direction 如果是 (0,0,0), 会被重置为默认值 default: (1,0,0) |
---|
Precautions
能在 Ready 状态下调用
ts
@Component
export default class Example_ProjectileMovement_Launch extends Script {
protected async onStart(): Promise<void> {
// 下列逻辑在服务端执行
if(SystemUtil.isServer()) {
// 在世界坐标(200,0,25)异步生成一个球
let ball = await GameObject.asyncSpawn("84121") as Model;
ball.worldTransform.position = new Vector(200, 0, 25);
ball.name = "ball";
ball.setCollision(CollisionStatus.QueryCollisionOnly);
// 在世界坐标(1000,0,0)异步生成一面墙
let wall = await GameObject.asyncSpawn("197386") as Model;
wall.worldTransform.position = new Vector(1000, 0, 0);
wall.worldTransform.scale = new Vector(1, 5, 5);
wall.name = "wall";
// 创建投掷物。
let projectile = new ProjectileMovement(ball);
// 设置初始发射速度为1500。
projectile.initialSpeed = 1500;
// 设置重力缩放为1。
projectile.gravityScale = 1;
// 设置投掷物旋转跟随速度方向。
projectile.isRotationFollowsVelocity = true;
// 设置投掷物碰撞维持速度比例为0.4。
projectile.speedRetention = 0.4;
// 给击中委托绑定一个函数,打印击中信息:角色X 发射 对象Y 击中 对象Z,并播放一个击中特效。
projectile.onProjectileHit.add((hitGameObject, HitResult) => {
console.log( "Projectile " + projectile.getRelatedGameObject().name + " thrown by Character " + projectile.owner.displayName + " hits the " + hitGameObject.name);
EffectService.playAtPosition("99599", HitResult.impactPoint);
});
// 给投掷物生命结束委托绑定一个函数,播放一个销毁特效。
projectile.onProjectileLifeEnd.add(() => {
EffectService.playAtPosition("133276", ball.worldTransform.position);
});
// 添加客户端发送的”LAUNCH“事件监听器,将球朝上方发射。
Event.addClientListener("LAUNCH", async (player: Player) => {
// 设置owner为玩家角色。
projectile.owner = player.character;
projectile.launch(new Vector(1, 0, 1));
});
// 添加客户端发送的”PAUSE“事件监听器,将暂停投掷物运动并打印状态。
Event.addClientListener("PAUSE", async (player: Player) => {
projectile.pause();
console.log("Projectile status " + projectile.status);
});
// 添加客户端发送的”RESUME“事件监听器,将恢复投掷物运动并打印状态。
Event.addClientListener("RESUME", async (player: Player) => {
projectile.resume();
console.log("Projectile status " + projectile.status);
});
}
// 下列逻辑在客户端执行
if(SystemUtil.isClient()) {
// 添加一个按键方法:按下按键”1“,向服务端派送一个”LAUNCH“事件,发射球
InputUtil.onKeyDown(Keys.One, () => {
Event.dispatchToServer("LAUNCH");
});
// 添加一个按键方法:按下按键”2“,向服务端派送一个”PAUSE“事件,发射球
InputUtil.onKeyDown(Keys.Two, () => {
Event.dispatchToServer("PAUSE");
});
// 添加一个按键方法:按下按键”3“,向服务端派送一个”RESUME“事件,发射球
InputUtil.onKeyDown(Keys.Three, () => {
Event.dispatchToServer("RESUME");
});
}
}
}
@Component
export default class Example_ProjectileMovement_Launch extends Script {
protected async onStart(): Promise<void> {
// 下列逻辑在服务端执行
if(SystemUtil.isServer()) {
// 在世界坐标(200,0,25)异步生成一个球
let ball = await GameObject.asyncSpawn("84121") as Model;
ball.worldTransform.position = new Vector(200, 0, 25);
ball.name = "ball";
ball.setCollision(CollisionStatus.QueryCollisionOnly);
// 在世界坐标(1000,0,0)异步生成一面墙
let wall = await GameObject.asyncSpawn("197386") as Model;
wall.worldTransform.position = new Vector(1000, 0, 0);
wall.worldTransform.scale = new Vector(1, 5, 5);
wall.name = "wall";
// 创建投掷物。
let projectile = new ProjectileMovement(ball);
// 设置初始发射速度为1500。
projectile.initialSpeed = 1500;
// 设置重力缩放为1。
projectile.gravityScale = 1;
// 设置投掷物旋转跟随速度方向。
projectile.isRotationFollowsVelocity = true;
// 设置投掷物碰撞维持速度比例为0.4。
projectile.speedRetention = 0.4;
// 给击中委托绑定一个函数,打印击中信息:角色X 发射 对象Y 击中 对象Z,并播放一个击中特效。
projectile.onProjectileHit.add((hitGameObject, HitResult) => {
console.log( "Projectile " + projectile.getRelatedGameObject().name + " thrown by Character " + projectile.owner.displayName + " hits the " + hitGameObject.name);
EffectService.playAtPosition("99599", HitResult.impactPoint);
});
// 给投掷物生命结束委托绑定一个函数,播放一个销毁特效。
projectile.onProjectileLifeEnd.add(() => {
EffectService.playAtPosition("133276", ball.worldTransform.position);
});
// 添加客户端发送的”LAUNCH“事件监听器,将球朝上方发射。
Event.addClientListener("LAUNCH", async (player: Player) => {
// 设置owner为玩家角色。
projectile.owner = player.character;
projectile.launch(new Vector(1, 0, 1));
});
// 添加客户端发送的”PAUSE“事件监听器,将暂停投掷物运动并打印状态。
Event.addClientListener("PAUSE", async (player: Player) => {
projectile.pause();
console.log("Projectile status " + projectile.status);
});
// 添加客户端发送的”RESUME“事件监听器,将恢复投掷物运动并打印状态。
Event.addClientListener("RESUME", async (player: Player) => {
projectile.resume();
console.log("Projectile status " + projectile.status);
});
}
// 下列逻辑在客户端执行
if(SystemUtil.isClient()) {
// 添加一个按键方法:按下按键”1“,向服务端派送一个”LAUNCH“事件,发射球
InputUtil.onKeyDown(Keys.One, () => {
Event.dispatchToServer("LAUNCH");
});
// 添加一个按键方法:按下按键”2“,向服务端派送一个”PAUSE“事件,发射球
InputUtil.onKeyDown(Keys.Two, () => {
Event.dispatchToServer("PAUSE");
});
// 添加一个按键方法:按下按键”3“,向服务端派送一个”RESUME“事件,发射球
InputUtil.onKeyDown(Keys.Three, () => {
Event.dispatchToServer("RESUME");
});
}
}
}
pause
• pause(): void
暂停运动,将由 Launched 状态切换到 Ready 状态
Precautions
非 Launched 状态调用时不生效
ts
@Component
export default class Example_ProjectileMovement_Launch extends Script {
protected async onStart(): Promise<void> {
// 下列逻辑在服务端执行
if(SystemUtil.isServer()) {
// 在世界坐标(200,0,25)异步生成一个球
let ball = await GameObject.asyncSpawn("84121") as Model;
ball.worldTransform.position = new Vector(200, 0, 25);
ball.name = "ball";
ball.setCollision(CollisionStatus.QueryCollisionOnly);
// 在世界坐标(1000,0,0)异步生成一面墙
let wall = await GameObject.asyncSpawn("197386") as Model;
wall.worldTransform.position = new Vector(1000, 0, 0);
wall.worldTransform.scale = new Vector(1, 5, 5);
wall.name = "wall";
// 创建投掷物。
let projectile = new ProjectileMovement(ball);
// 设置初始发射速度为1500。
projectile.initialSpeed = 1500;
// 设置重力缩放为1。
projectile.gravityScale = 1;
// 设置投掷物旋转跟随速度方向。
projectile.isRotationFollowsVelocity = true;
// 设置投掷物碰撞维持速度比例为0.4。
projectile.speedRetention = 0.4;
// 给击中委托绑定一个函数,打印击中信息:角色X 发射 对象Y 击中 对象Z,并播放一个击中特效。
projectile.onProjectileHit.add((hitGameObject, HitResult) => {
console.log( "Projectile " + projectile.getRelatedGameObject().name + " thrown by Character " + projectile.owner.displayName + " hits the " + hitGameObject.name);
EffectService.playAtPosition("99599", HitResult.impactPoint);
});
// 给投掷物生命结束委托绑定一个函数,播放一个销毁特效。
projectile.onProjectileLifeEnd.add(() => {
EffectService.playAtPosition("133276", ball.worldTransform.position);
});
// 添加客户端发送的”LAUNCH“事件监听器,将球朝上方发射。
Event.addClientListener("LAUNCH", async (player: Player) => {
// 设置owner为玩家角色。
projectile.owner = player.character;
projectile.launch(new Vector(1, 0, 1));
});
// 添加客户端发送的”PAUSE“事件监听器,将暂停投掷物运动并打印状态。
Event.addClientListener("PAUSE", async (player: Player) => {
projectile.pause();
console.log("Projectile status " + projectile.status);
});
// 添加客户端发送的”RESUME“事件监听器,将恢复投掷物运动并打印状态。
Event.addClientListener("RESUME", async (player: Player) => {
projectile.resume();
console.log("Projectile status " + projectile.status);
});
}
// 下列逻辑在客户端执行
if(SystemUtil.isClient()) {
// 添加一个按键方法:按下按键”1“,向服务端派送一个”LAUNCH“事件,发射球
InputUtil.onKeyDown(Keys.One, () => {
Event.dispatchToServer("LAUNCH");
});
// 添加一个按键方法:按下按键”2“,向服务端派送一个”PAUSE“事件,发射球
InputUtil.onKeyDown(Keys.Two, () => {
Event.dispatchToServer("PAUSE");
});
// 添加一个按键方法:按下按键”3“,向服务端派送一个”RESUME“事件,发射球
InputUtil.onKeyDown(Keys.Three, () => {
Event.dispatchToServer("RESUME");
});
}
}
}
@Component
export default class Example_ProjectileMovement_Launch extends Script {
protected async onStart(): Promise<void> {
// 下列逻辑在服务端执行
if(SystemUtil.isServer()) {
// 在世界坐标(200,0,25)异步生成一个球
let ball = await GameObject.asyncSpawn("84121") as Model;
ball.worldTransform.position = new Vector(200, 0, 25);
ball.name = "ball";
ball.setCollision(CollisionStatus.QueryCollisionOnly);
// 在世界坐标(1000,0,0)异步生成一面墙
let wall = await GameObject.asyncSpawn("197386") as Model;
wall.worldTransform.position = new Vector(1000, 0, 0);
wall.worldTransform.scale = new Vector(1, 5, 5);
wall.name = "wall";
// 创建投掷物。
let projectile = new ProjectileMovement(ball);
// 设置初始发射速度为1500。
projectile.initialSpeed = 1500;
// 设置重力缩放为1。
projectile.gravityScale = 1;
// 设置投掷物旋转跟随速度方向。
projectile.isRotationFollowsVelocity = true;
// 设置投掷物碰撞维持速度比例为0.4。
projectile.speedRetention = 0.4;
// 给击中委托绑定一个函数,打印击中信息:角色X 发射 对象Y 击中 对象Z,并播放一个击中特效。
projectile.onProjectileHit.add((hitGameObject, HitResult) => {
console.log( "Projectile " + projectile.getRelatedGameObject().name + " thrown by Character " + projectile.owner.displayName + " hits the " + hitGameObject.name);
EffectService.playAtPosition("99599", HitResult.impactPoint);
});
// 给投掷物生命结束委托绑定一个函数,播放一个销毁特效。
projectile.onProjectileLifeEnd.add(() => {
EffectService.playAtPosition("133276", ball.worldTransform.position);
});
// 添加客户端发送的”LAUNCH“事件监听器,将球朝上方发射。
Event.addClientListener("LAUNCH", async (player: Player) => {
// 设置owner为玩家角色。
projectile.owner = player.character;
projectile.launch(new Vector(1, 0, 1));
});
// 添加客户端发送的”PAUSE“事件监听器,将暂停投掷物运动并打印状态。
Event.addClientListener("PAUSE", async (player: Player) => {
projectile.pause();
console.log("Projectile status " + projectile.status);
});
// 添加客户端发送的”RESUME“事件监听器,将恢复投掷物运动并打印状态。
Event.addClientListener("RESUME", async (player: Player) => {
projectile.resume();
console.log("Projectile status " + projectile.status);
});
}
// 下列逻辑在客户端执行
if(SystemUtil.isClient()) {
// 添加一个按键方法:按下按键”1“,向服务端派送一个”LAUNCH“事件,发射球
InputUtil.onKeyDown(Keys.One, () => {
Event.dispatchToServer("LAUNCH");
});
// 添加一个按键方法:按下按键”2“,向服务端派送一个”PAUSE“事件,发射球
InputUtil.onKeyDown(Keys.Two, () => {
Event.dispatchToServer("PAUSE");
});
// 添加一个按键方法:按下按键”3“,向服务端派送一个”RESUME“事件,发射球
InputUtil.onKeyDown(Keys.Three, () => {
Event.dispatchToServer("RESUME");
});
}
}
}
resume
• resume(): void
继续运动,将由 Ready 状态切换到 Launched 状态
Precautions
对应 pause 方法,还没有发射的对象调用也不会运动
ts
@Component
export default class Example_ProjectileMovement_Launch extends Script {
protected async onStart(): Promise<void> {
// 下列逻辑在服务端执行
if(SystemUtil.isServer()) {
// 在世界坐标(200,0,25)异步生成一个球
let ball = await GameObject.asyncSpawn("84121") as Model;
ball.worldTransform.position = new Vector(200, 0, 25);
ball.name = "ball";
ball.setCollision(CollisionStatus.QueryCollisionOnly);
// 在世界坐标(1000,0,0)异步生成一面墙
let wall = await GameObject.asyncSpawn("197386") as Model;
wall.worldTransform.position = new Vector(1000, 0, 0);
wall.worldTransform.scale = new Vector(1, 5, 5);
wall.name = "wall";
// 创建投掷物。
let projectile = new ProjectileMovement(ball);
// 设置初始发射速度为1500。
projectile.initialSpeed = 1500;
// 设置重力缩放为1。
projectile.gravityScale = 1;
// 设置投掷物旋转跟随速度方向。
projectile.isRotationFollowsVelocity = true;
// 设置投掷物碰撞维持速度比例为0.4。
projectile.speedRetention = 0.4;
// 给击中委托绑定一个函数,打印击中信息:角色X 发射 对象Y 击中 对象Z,并播放一个击中特效。
projectile.onProjectileHit.add((hitGameObject, HitResult) => {
console.log( "Projectile " + projectile.getRelatedGameObject().name + " thrown by Character " + projectile.owner.displayName + " hits the " + hitGameObject.name);
EffectService.playAtPosition("99599", HitResult.impactPoint);
});
// 给投掷物生命结束委托绑定一个函数,播放一个销毁特效。
projectile.onProjectileLifeEnd.add(() => {
EffectService.playAtPosition("133276", ball.worldTransform.position);
});
// 添加客户端发送的”LAUNCH“事件监听器,将球朝上方发射。
Event.addClientListener("LAUNCH", async (player: Player) => {
// 设置owner为玩家角色。
projectile.owner = player.character;
projectile.launch(new Vector(1, 0, 1));
});
// 添加客户端发送的”PAUSE“事件监听器,将暂停投掷物运动并打印状态。
Event.addClientListener("PAUSE", async (player: Player) => {
projectile.pause();
console.log("Projectile status " + projectile.status);
});
// 添加客户端发送的”RESUME“事件监听器,将恢复投掷物运动并打印状态。
Event.addClientListener("RESUME", async (player: Player) => {
projectile.resume();
console.log("Projectile status " + projectile.status);
});
}
// 下列逻辑在客户端执行
if(SystemUtil.isClient()) {
// 添加一个按键方法:按下按键”1“,向服务端派送一个”LAUNCH“事件,发射球
InputUtil.onKeyDown(Keys.One, () => {
Event.dispatchToServer("LAUNCH");
});
// 添加一个按键方法:按下按键”2“,向服务端派送一个”PAUSE“事件,发射球
InputUtil.onKeyDown(Keys.Two, () => {
Event.dispatchToServer("PAUSE");
});
// 添加一个按键方法:按下按键”3“,向服务端派送一个”RESUME“事件,发射球
InputUtil.onKeyDown(Keys.Three, () => {
Event.dispatchToServer("RESUME");
});
}
}
}
@Component
export default class Example_ProjectileMovement_Launch extends Script {
protected async onStart(): Promise<void> {
// 下列逻辑在服务端执行
if(SystemUtil.isServer()) {
// 在世界坐标(200,0,25)异步生成一个球
let ball = await GameObject.asyncSpawn("84121") as Model;
ball.worldTransform.position = new Vector(200, 0, 25);
ball.name = "ball";
ball.setCollision(CollisionStatus.QueryCollisionOnly);
// 在世界坐标(1000,0,0)异步生成一面墙
let wall = await GameObject.asyncSpawn("197386") as Model;
wall.worldTransform.position = new Vector(1000, 0, 0);
wall.worldTransform.scale = new Vector(1, 5, 5);
wall.name = "wall";
// 创建投掷物。
let projectile = new ProjectileMovement(ball);
// 设置初始发射速度为1500。
projectile.initialSpeed = 1500;
// 设置重力缩放为1。
projectile.gravityScale = 1;
// 设置投掷物旋转跟随速度方向。
projectile.isRotationFollowsVelocity = true;
// 设置投掷物碰撞维持速度比例为0.4。
projectile.speedRetention = 0.4;
// 给击中委托绑定一个函数,打印击中信息:角色X 发射 对象Y 击中 对象Z,并播放一个击中特效。
projectile.onProjectileHit.add((hitGameObject, HitResult) => {
console.log( "Projectile " + projectile.getRelatedGameObject().name + " thrown by Character " + projectile.owner.displayName + " hits the " + hitGameObject.name);
EffectService.playAtPosition("99599", HitResult.impactPoint);
});
// 给投掷物生命结束委托绑定一个函数,播放一个销毁特效。
projectile.onProjectileLifeEnd.add(() => {
EffectService.playAtPosition("133276", ball.worldTransform.position);
});
// 添加客户端发送的”LAUNCH“事件监听器,将球朝上方发射。
Event.addClientListener("LAUNCH", async (player: Player) => {
// 设置owner为玩家角色。
projectile.owner = player.character;
projectile.launch(new Vector(1, 0, 1));
});
// 添加客户端发送的”PAUSE“事件监听器,将暂停投掷物运动并打印状态。
Event.addClientListener("PAUSE", async (player: Player) => {
projectile.pause();
console.log("Projectile status " + projectile.status);
});
// 添加客户端发送的”RESUME“事件监听器,将恢复投掷物运动并打印状态。
Event.addClientListener("RESUME", async (player: Player) => {
projectile.resume();
console.log("Projectile status " + projectile.status);
});
}
// 下列逻辑在客户端执行
if(SystemUtil.isClient()) {
// 添加一个按键方法:按下按键”1“,向服务端派送一个”LAUNCH“事件,发射球
InputUtil.onKeyDown(Keys.One, () => {
Event.dispatchToServer("LAUNCH");
});
// 添加一个按键方法:按下按键”2“,向服务端派送一个”PAUSE“事件,发射球
InputUtil.onKeyDown(Keys.Two, () => {
Event.dispatchToServer("PAUSE");
});
// 添加一个按键方法:按下按键”3“,向服务端派送一个”RESUME“事件,发射球
InputUtil.onKeyDown(Keys.Three, () => {
Event.dispatchToServer("RESUME");
});
}
}
}
setRelatedGameObject
• setRelatedGameObject(value
): void
设置新的关联的逻辑对象
Parameters
value GameObject | 新的关联的逻辑对象,设置后,移动组件会重新生成并附加到此对象上 |
---|
ts
@Component
export default class Example_ProjectileMovement extends Script {
protected async onStart(): Promise<void> {
// 下列逻辑在服务端执行
if(SystemUtil.isServer()) {
// 创建一个模型数组balls和标识curBall。
let balls = new Array<Model>();
let curBall = 0;
// 在前方异步生成5个球,放入数组balls中。
for (let i = 0;
i < 5;
i++) {
let ball = await GameObject.asyncSpawn("84121") as Model;
ball.worldTransform.position = new Vector(200, i * 100, 25);
ball.name = "ball" + i;
ball.setCollision(CollisionStatus.QueryCollisionOnly);
balls.push(ball);
}
// 创建投掷物。
let projectile = new ProjectileMovement(balls[curBall]);
// 设置初始发射速度为1000。
projectile.initialSpeed = 1000;
// 给击中委托绑定一个函数,当击中对象是目标时,播放一个击中特效,0.5s后删除目标。
projectile.onProjectileHit.add((hitGameObject, HitResult) => {
EffectService.playAtPosition("99599", HitResult.impactPoint, {scale: new Vector(5, 5, 5)});
});
// 添加客户端发送的”LAUNCH“事件监听器,将球右前方发射。
Event.addClientListener("LAUNCH", async (player: Player) => {
projectile.launch(new Vector(1, 1, 1));
});
// 添加客户端发送的”DESTROY“事件监听器,从数组里面删除球对象,并切换投掷物关联的对象。
Event.addClientListener("DESTROY", async (player: Player) => {
console.error("DESTROY");
let deleteBall = projectile.getRelatedGameObject() as Model;
let deleteIndex = balls.indexOf(deleteBall);
balls.splice(deleteIndex, 1);
if(balls.length > 0) {
curBall = (deleteIndex) % balls.length;
projectile.setRelatedGameObject(balls[curBall]);
deleteBall.destroy();
} else {
projectile.destroy(true);
}
});
}
// 下列逻辑在客户端执行
if(SystemUtil.isClient()) {
// 添加一个按键方法:按下按键”1“,向服务端派送一个”LAUNCH“事件,发射球。
InputUtil.onKeyDown(Keys.One, () => {
Event.dispatchToServer("LAUNCH");
});
// 添加一个按键方法:按下按键”2“,向服务端派送一个”DESTROY“事件,切换至下一个球并删除上一个。
InputUtil.onKeyDown(Keys.Two, () => {
Event.dispatchToServer("DESTROY");
});
}
}
}
@Component
export default class Example_ProjectileMovement extends Script {
protected async onStart(): Promise<void> {
// 下列逻辑在服务端执行
if(SystemUtil.isServer()) {
// 创建一个模型数组balls和标识curBall。
let balls = new Array<Model>();
let curBall = 0;
// 在前方异步生成5个球,放入数组balls中。
for (let i = 0;
i < 5;
i++) {
let ball = await GameObject.asyncSpawn("84121") as Model;
ball.worldTransform.position = new Vector(200, i * 100, 25);
ball.name = "ball" + i;
ball.setCollision(CollisionStatus.QueryCollisionOnly);
balls.push(ball);
}
// 创建投掷物。
let projectile = new ProjectileMovement(balls[curBall]);
// 设置初始发射速度为1000。
projectile.initialSpeed = 1000;
// 给击中委托绑定一个函数,当击中对象是目标时,播放一个击中特效,0.5s后删除目标。
projectile.onProjectileHit.add((hitGameObject, HitResult) => {
EffectService.playAtPosition("99599", HitResult.impactPoint, {scale: new Vector(5, 5, 5)});
});
// 添加客户端发送的”LAUNCH“事件监听器,将球右前方发射。
Event.addClientListener("LAUNCH", async (player: Player) => {
projectile.launch(new Vector(1, 1, 1));
});
// 添加客户端发送的”DESTROY“事件监听器,从数组里面删除球对象,并切换投掷物关联的对象。
Event.addClientListener("DESTROY", async (player: Player) => {
console.error("DESTROY");
let deleteBall = projectile.getRelatedGameObject() as Model;
let deleteIndex = balls.indexOf(deleteBall);
balls.splice(deleteIndex, 1);
if(balls.length > 0) {
curBall = (deleteIndex) % balls.length;
projectile.setRelatedGameObject(balls[curBall]);
deleteBall.destroy();
} else {
projectile.destroy(true);
}
});
}
// 下列逻辑在客户端执行
if(SystemUtil.isClient()) {
// 添加一个按键方法:按下按键”1“,向服务端派送一个”LAUNCH“事件,发射球。
InputUtil.onKeyDown(Keys.One, () => {
Event.dispatchToServer("LAUNCH");
});
// 添加一个按键方法:按下按键”2“,向服务端派送一个”DESTROY“事件,切换至下一个球并删除上一个。
InputUtil.onKeyDown(Keys.Two, () => {
Event.dispatchToServer("DESTROY");
});
}
}
}
setVelocity
• setVelocity(v
): void
设置当前速度
Parameters
v Vector | 速度 |
---|
Precautions
能在 Launched 状态和 Ready 状态下调用
ts
@Component
export default class Example_ProjectileMovement extends Script {
protected async onStart(): Promise<void> {
// 下列逻辑在服务端执行
if(SystemUtil.isServer()) {
// 在r(2000, 0, 0)生成一个火箭模型。
let rocket = await GameObject.asyncSpawn("162807") as Model;
rocket.worldTransform.position = new Vector(2000, 0, 0);
// 将火箭的碰撞状态修改为无碰撞
rocket.setCollision(CollisionStatus.Off);
// 创建投掷物。
let projectile = new ProjectileMovement(rocket);
// 设置初始发射速度为1。
projectile.initialSpeed = 1;
// 设置最大速度为1000。
projectile.maxSpeed = 1000;
// 设置发射加速度为200
projectile.acceleration = 200;
// 设置重力缩放为0。
projectile.gravityScale = 0;
// 设置投掷物旋转不跟随速度方向。
projectile.isRotationFollowsVelocity = false;
// 设置投掷物运动时间10秒。
projectile.lifeSpan = 10;
// 添加客户端发送的”LAUNCH“事件监听器,将火箭朝上方发射。
Event.addClientListener("LAUNCH", async (player: Player) => {
projectile.launch(new Vector(0, 0, 1));
// 广播客户端给火箭挂载尾焰特效
Event.dispatchToAllClient("TAIL", rocket.gameObjectId);
// 每0.1秒都会给客户端广播火箭当前速度
let scaleInterval = TimeUtil.setInterval(() => {
if(projectile.getVelocity().length > 999) {
projectile.setVelocity(Vector.zero);
TimeUtil.clearInterval(scaleInterval);
rocket.worldTransform.position = new Vector(2000, 0, 0);
}
Event.dispatchToAllClient("SCALING", rocket.gameObjectId, projectile.getVelocity());
}, 0.1);
});
}
// 下列逻辑在客户端执行
if(SystemUtil.isClient()) {
// 添加一个按键方法:按下按键”1“,向服务端派送一个”LAUNCH“事件,发射火箭
InputUtil.onKeyDown(Keys.One, () => {
Event.dispatchToServer("LAUNCH");
});
// 添加服务端发送的”TAIL“事件监听器,给火箭挂载尾焰。
Event.addServerListener("TAIL", async (rocketId: string) => {
let rocket = await GameObject.asyncFindGameObjectById(rocketId);
if(typeof(rocket.getChildByName("tail")) != "undefined") {
return;
}
let tail = await GameObject.asyncSpawn("144098") as Effect;
tail.name = "tail";
tail.parent = rocket;
tail.localTransform.position = Vector.zero;
});
// 添加服务端发送的”SCALING“事件监听器,根据速度对尾焰进行缩放
Event.addServerListener("SCALING", async (rocketId: string, velocity: Vector) => {
let rocket = await GameObject.asyncFindGameObjectById(rocketId);
let tail = rocket.getChildByName("tail");
if(tail) {
tail.worldTransform.scale = Vector.one.multiply(velocity.length / 250);
}
});
}
}
}
@Component
export default class Example_ProjectileMovement extends Script {
protected async onStart(): Promise<void> {
// 下列逻辑在服务端执行
if(SystemUtil.isServer()) {
// 在r(2000, 0, 0)生成一个火箭模型。
let rocket = await GameObject.asyncSpawn("162807") as Model;
rocket.worldTransform.position = new Vector(2000, 0, 0);
// 将火箭的碰撞状态修改为无碰撞
rocket.setCollision(CollisionStatus.Off);
// 创建投掷物。
let projectile = new ProjectileMovement(rocket);
// 设置初始发射速度为1。
projectile.initialSpeed = 1;
// 设置最大速度为1000。
projectile.maxSpeed = 1000;
// 设置发射加速度为200
projectile.acceleration = 200;
// 设置重力缩放为0。
projectile.gravityScale = 0;
// 设置投掷物旋转不跟随速度方向。
projectile.isRotationFollowsVelocity = false;
// 设置投掷物运动时间10秒。
projectile.lifeSpan = 10;
// 添加客户端发送的”LAUNCH“事件监听器,将火箭朝上方发射。
Event.addClientListener("LAUNCH", async (player: Player) => {
projectile.launch(new Vector(0, 0, 1));
// 广播客户端给火箭挂载尾焰特效
Event.dispatchToAllClient("TAIL", rocket.gameObjectId);
// 每0.1秒都会给客户端广播火箭当前速度
let scaleInterval = TimeUtil.setInterval(() => {
if(projectile.getVelocity().length > 999) {
projectile.setVelocity(Vector.zero);
TimeUtil.clearInterval(scaleInterval);
rocket.worldTransform.position = new Vector(2000, 0, 0);
}
Event.dispatchToAllClient("SCALING", rocket.gameObjectId, projectile.getVelocity());
}, 0.1);
});
}
// 下列逻辑在客户端执行
if(SystemUtil.isClient()) {
// 添加一个按键方法:按下按键”1“,向服务端派送一个”LAUNCH“事件,发射火箭
InputUtil.onKeyDown(Keys.One, () => {
Event.dispatchToServer("LAUNCH");
});
// 添加服务端发送的”TAIL“事件监听器,给火箭挂载尾焰。
Event.addServerListener("TAIL", async (rocketId: string) => {
let rocket = await GameObject.asyncFindGameObjectById(rocketId);
if(typeof(rocket.getChildByName("tail")) != "undefined") {
return;
}
let tail = await GameObject.asyncSpawn("144098") as Effect;
tail.name = "tail";
tail.parent = rocket;
tail.localTransform.position = Vector.zero;
});
// 添加服务端发送的”SCALING“事件监听器,根据速度对尾焰进行缩放
Event.addServerListener("SCALING", async (rocketId: string, velocity: Vector) => {
let rocket = await GameObject.asyncFindGameObjectById(rocketId);
let tail = rocket.getChildByName("tail");
if(tail) {
tail.worldTransform.scale = Vector.one.multiply(velocity.length / 250);
}
});
}
}
}