玩法 / ObjectLauncher
ObjectLauncher Class
投掷物发射器
投掷物发射器是一种游戏中常见的机制,用于模拟投掷物体的发射和飞行。它可以让玩家或游戏角色通过选择合适的方向和力量,将物体发射到目标位置。
想象一下,你站在一个阳台上,手里拿着一个小球,并希望将它投向一个目标。投掷物发射器就像是你的手臂和手,它帮助你控制球的发射。你可以调整你的手臂的方向和力量,以便球以特定的方式飞行。
一旦玩家决定好发射的方向和力量,投掷物发射器就会将投掷物体发射出去。投掷物体会根据发射器设置的速度和发射角度开始飞行。它会在空中经过弧线路径,并受到重力和其他物理效应的影响。
ObjectLauncher 为发射器。发射器发射出的实例称为投掷物实例 ProjectileInst 。投掷物实例上挂载着实际发射的物体。
当 spawnProjectileInstanceLaunch 启动发射时,传入对象ID(注意是场景里的对象 id,不是资源 id),投掷物实例拖着传入的模型进行运动,发射器作为发射终端,维护投掷物发射相关的参数。
发射器接口调用端可以是服务器,也可以是客户端;发射投掷物的方式有3种:1.双端投掷物 2.发射全客户端投掷物 3.发射单客户端投掷物
在客户端还是服务端加载 ObjectLauncher 对象呢?
- 服务端
在服务端动态生成投掷物发射器,获得一个各端同步的投掷物发射器对象。修改投掷物发射器属性会同步至所有客户端。
在服务器添加投掷物发射器委托后,委托只会在服务器执行,同时执行前提是发射器要存在于服务器。
在服务器调用发射接口时,按服务器当前发射器属性生成双端投掷物发射,发射对象如果在服务端找不到(有可能是单客户端投掷物),直接返回,能找到(发射对象是双端对象),在投掷物上挂载发射物体。双端投掷物的碰撞和轨迹就是服务器计算,即以服务器的计算结果为准。
- 客户端
在客户端动态生成投掷物发射器,只能获得一个本地的投掷物发射器对象,仅支持本地发射。
在本地添加回调后,回调只会在本地执行,同时执行前提是发射器要存在于本地。
在本地调用广播发射:按本地当前发射器属性生成单端投掷物,同时通知服务器广播其他客户端按本地当前发射器属性生成单端投掷物。发射对象如果在服务端找不到,直接返回,能找到(发射对象是双端对象),挂上投掷物。
另外有控制发射器发射初始速度、重力、投掷物半径等参数。
Hierarchy
↳
ObjectLauncher
Table of contents
Properties
onProjectileHit: MulticastDelegate <(projectile : ProjectileInst , hitGameObject : GameObject , hitResult : HitResult ) => void > |
---|
投掷物击中物体时触发绑定函数 |
onProjectileHomingFail: MulticastDelegate <(projectile : ProjectileInst ) => void > |
投掷物追踪目标失败(即为被销毁时)触发绑定函数 |
onProjectileLifeEnd: MulticastDelegate <(projectile : ProjectileInst ) => void > |
投掷物生命周期结束(即速度降为0、LifeSpan 到期)时触发绑定函数 |
onProjectileLifeStart: MulticastDelegate <(projectile : ProjectileInst ) => void > |
投掷物生成实例时触发绑定函数,此时实例还没有开始移动 |
click
Properties
onBeforeDestroyDelegate: MulticastDelegate <() => void > |
---|
物体销毁前事件回调 |
onCustomPropertyChange: Readonly <MulticastDelegate <(path : string , value : unknown , oldValue : unknown ) => void >> other |
监听自定义属性同步事件 |
onDestroyDelegate: MulticastDelegate <() => void > |
物体销毁后事件回调 |
onPropertyChange: Readonly <MulticastDelegate <(path : string , value : unknown , oldValue : unknown ) => void >> |
监听系统属性同步事件 |
Accessors
acceleration(): number |
---|
投掷物运动的加速度(cm/s),正值会使投掷物加速,负值减速。default: 0,range: [-10000,10000]。 |
capsuleHalfLength(): number |
投掷物碰撞胶囊体的半长(cm),半长小于半径时为球体。default: 50。range: [1, 1000]。 |
capsuleRadius(): number |
投掷物碰撞胶囊体的半径(cm)。default: 25。range: [1, 1000]。 |
collisionVelocityRetention(): number |
碰撞后投掷物保持原来速度的比例。0表示。default: 0.6。range: [0, 1]。 |
gravityScale(): number |
投掷物受世界重力影响的倍率,正值会使投掷物下坠,负值上升,0可以使投掷物以直线运动。default: 1,range: [-10, 10]。 |
initialSpeed(): number |
投掷物的初始运动速度(cm/s),default: 5000,range: [1,100000]。 |
isRotationFollowsVelocity(): boolean |
投掷物的正方向(以及挂载对象)是否始终跟随运动方向。true:跟随。false:不跟随。default: true。 |
isShouldBounce(): boolean |
决定投掷物运动过程中与其他对象发生碰撞时是否能反弹。true:反弹。false:穿透。default: true。 |
isShouldReplicateDelegates(): boolean |
投掷物触发对应事件时是否广播(仅双端发射器生效),true:广播。false:仅本地 |
lifeSpan(): number |
投掷物存在的最长时间(s),0意味着没有限制。default: 10。range: [0, 1000]。 |
maxSpeed(): number |
投掷物的最大运动速度(cm/s),0意味着没有限制。default: 0,range: [0,100000]。 |
click
Accessors
assetId(): string |
---|
获取当前物体使用资源的GUID |
gameObjectId(): string |
获取物体的唯一标识(唯一标识一个对象的字符串)。 |
isDestroyed(): boolean |
当前物体是否被销毁 |
isReady(): boolean |
当前物体状态 |
localTransform(): Transform |
当前物体本地变换 |
name(): string |
返回当前物体名称 |
netStatus(): NetStatus |
获取当前物体同步状态 |
parent(): GameObject |
获取当前父物体 |
tag(): string |
获取当前物体的标签 |
worldTransform(): Transform |
当前物体世界变换 |
Methods
predictedTrajectory(startPosition : Vector , startDirection : Vector , density : number , duration : number ): Vector [] |
---|
按照预测时间和密度返回的路径点数组。不预测碰撞后的反弹路径。 |
spawnProjectileInstanceLaunch(childObjectId : string , startPosition? : Vector , direction? : Vector , isAllClientLaunch? : boolean ): ProjectileInst |
按照对象发射器当前参数生成的投掷物对象 |
spawnProjectileInstanceLaunchToTarget(childObjectId : string , target : GameObject , targetingAcceleration? : number , startPosition? : Vector , direction? : Vector , isAllClientLaunch? : boolean ): ProjectileInst |
按照对象发射器当前参数生成的投掷物对象 |
click
Methods
addComponent<T : extends Script <T >>(constructor : (...args : unknown []) => T : extends Script <T >, bInReplicates? : boolean ): T : extends Script <T > |
---|
添加一个脚本组件 |
asyncGetChildByName(name : string ): Promise <GameObject > |
异步根据名称查找子物体 |
asyncReady(): Promise <GameObject > |
物体准备好后返回 |
clone(gameObjectInfo? : GameObjectInfo ): GameObject |
复制对象 |
destroy(): void |
删除对象 |
getBoundingBox(nonColliding? : boolean , includeFromChild? : boolean , outer? : Vector ): Vector |
获取物体包围盒大小 |
getBounds(onlyCollidingComponents : boolean , originOuter : Vector , boxExtentOuter : Vector , includeFromChild? : boolean ): void |
获取物体边界 |
getChildByGameObjectId(gameObjectId : string ): GameObject |
根据 gameObjectId 查找子物体 |
getChildByName(name : string ): GameObject |
根据名称查找子物体 |
getChildByPath(path : string ): GameObject |
根据路径查找子物体 |
getChildren(): GameObject [] |
获取子物体 |
getChildrenBoundingBoxCenter(outer? : Vector ): Vector |
获取所有子对象包围盒中心点(不包含父对象,父对象不可用返回[0,0,0]) |
getChildrenByName(name : string ): GameObject [] |
通过名字查找所有的子物体 |
getComponent<T : extends Script <T >>(constructor? : (...args : unknown []) => T : extends Script <T >): T : extends Script <T > |
获取指定类型的组件 |
getComponentPropertys<T : extends Script <T >>(constructor : (...args : unknown []) => T : extends Script <T >): Map <string , IPropertyOptions > |
获取脚本组件属性 |
getComponents<T : extends Script <T >>(constructor? : (...args : unknown []) => T : extends Script <T >): T : extends Script <T >[] |
获取指定类型的所有组件 |
getCustomProperties(): string [] |
获取所有自定义属性 |
getCustomProperty<T : extends CustomPropertyType >(propertyName : string ): T : extends CustomPropertyType |
获取自定义属性 |
getCustomPropertyChangeDelegate(property ): Readonly <MulticastDelegate <(path : string , value : unknown , oldValue : unknown ) => void >> other |
给定对象属性修改时触发的事件代理 |
getPropertyChangeDelegate(property ): Readonly <MulticastDelegate <(path : string , value : unknown , oldValue : unknown ) => void >> other |
给定对象属性修改时触发的事件代理 |
getVisibility(): boolean |
获取物体是否被显示 |
moveBy(velocity : Vector , isLocal? : boolean ): void other |
按给定的速度矢量随时间平滑地移动对象 |
moveTo(targetPosition : Vector , time : number , isLocal? : boolean , onComplete? : () => void ): void other |
在指定时间内从当前位置平滑移动至目标位置 |
rotateBy(rotation : Quaternion Rotation , multiplier : number , isLocal? : boolean ): void other |
按给定的旋转量随时间平滑地旋转对象 |
rotateTo(targetRotation : Quaternion Rotation , time : number , isLocal? : boolean , onComplete? : () => void ): void other |
在指定时间内从当前旋转平滑变化至目标旋转 |
scaleBy(scale : Vector , isLocal? : boolean ): void other |
按每秒给定的缩放矢量随时间平滑缩放对象 |
scaleTo(targetScale : Vector , time : number , isLocal? : boolean , onComplete? : () => void ): void other |
在指定时间内从当前缩放平滑变化至目标缩放 |
setAbsolute(absolutePosition? : boolean , absoluteRotation? : boolean , absoluteScale? : boolean ): void |
设置物体localTransform是相对于父物体或者世界 |
setCustomProperty(propertyName : string , value : undefined CustomPropertyType ): void |
设置自定义属性 |
setVisibility(status : boolean PropertyStatus , propagateToChildren? : boolean ): void |
设置物体是否被显示 |
stopMove(): void other |
中断moveTo()、moveBy()的进一步移动 |
stopRotate(): void other |
中断从rotateTo()或rotateBy()的进一步旋转 |
stopScale(): void other |
中断从ScaleTo()或ScaleBy()的进一步缩放 |
asyncFindGameObjectById(gameObjectId : string ): Promise <GameObject > |
通过 gameObjectId 异步查找 GameObject |
asyncGetGameObjectByPath(path : string ): Promise <GameObject > |
通过路径异步查找物体 |
asyncSpawn<T : extends GameObject <T >>(assetId : string , gameObjectInfo? : GameObjectInfo ): Promise <T : extends GameObject <T >> |
异步构造一个物体 |
bulkPivotTo(gameObjects : GameObject [], transforms : Transform []): void |
批量设置位置 |
findGameObjectById(gameObjectId : string ): GameObject |
通过 gameObjectId 查找物体 |
findGameObjectByName(name : string ): GameObject |
通过名字查找物体 |
findGameObjectsByName(name : string ): GameObject [] |
通过名字查找物体 |
findGameObjectsByTag(tag : string ): GameObject [] |
通过自定义标签获取物体 |
getGameObjectByPath(path : string ): GameObject |
通过路径查找物体 |
spawn<T : extends GameObject <T >>(assetId : string , gameObjectInfo? : GameObjectInfo ): T : extends GameObject <T > |
构造一个物体 |
Properties
onProjectileHit
• onProjectileHit: MulticastDelegate
<(projectile
: ProjectileInst
, hitGameObject
: GameObject
, hitResult
: HitResult
) => void
>
投掷物击中物体时触发绑定函数
Precautions
所有投掷物都是使用的同一个回调,请不要循环添加事件绑定函数
onProjectileHomingFail
• onProjectileHomingFail: MulticastDelegate
<(projectile
: ProjectileInst
) => void
>
投掷物追踪目标失败(即为被销毁时)触发绑定函数
Precautions
所有投掷物都是使用的同一个回调,请不要循环添加事件绑定函数
ts
@Component
export default class Example_ObjectLauncher_OnHomingFail 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);
// 在世界坐标(2000,1000,130)异步生成一个NPC,2s后销毁。
let target = Player.spawnDefaultCharacter();
target.worldTransform.position = new Vector(2000, 1000, 130);
// 异步生成对象发射器
let myLauncher = await GameObject.asyncSpawn("ObjectLauncher") as ObjectLauncher;
// 设置发射初始速度为1000
myLauncher.initialSpeed = 1000;
// 设置碰撞半径为25
myLauncher.capsuleRadius = 25;
// 设置碰撞半长为25
myLauncher.capsuleHalfLength = 25;
// 开启反弹
myLauncher.isShouldBounce = true;
// 设置碰撞速度衰减为0.5
myLauncher.collisionVelocityRetention = 0.5;
// 给发射器追踪失败委托绑定函数,追踪失败时打印信息
myLauncher.onProjectileHomingFail.add((projectile) => {
console.log("Homing Fail");
});
// 添加客户端发送的”LAUNCHTOTARGET“事件监听器,将球朝斜上方发射并追踪NPC。
Event.addClientListener("LAUNCHTOTARGET", () => {
TimeUtil.delaySecond(1).then(() => {
target.destroy();
});
myLauncher.spawnProjectileInstanceLaunchToTarget(ball.gameObjectId, target, 2000, ball.worldTransform.position, new Vector(1, 0, 1));
});
}
// 下列逻辑在客户端执行
if(SystemUtil.isClient()) {
// 添加一个按键方法:按下按键”1“,向服务端派送一个”LAUNCHTOTARGET“事件,发射一个球追踪NPC。
InputUtil.onKeyDown(Keys.One, () => {
Event.dispatchToServer("LAUNCHTOTARGET");
});
}
}
}
@Component
export default class Example_ObjectLauncher_OnHomingFail 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);
// 在世界坐标(2000,1000,130)异步生成一个NPC,2s后销毁。
let target = Player.spawnDefaultCharacter();
target.worldTransform.position = new Vector(2000, 1000, 130);
// 异步生成对象发射器
let myLauncher = await GameObject.asyncSpawn("ObjectLauncher") as ObjectLauncher;
// 设置发射初始速度为1000
myLauncher.initialSpeed = 1000;
// 设置碰撞半径为25
myLauncher.capsuleRadius = 25;
// 设置碰撞半长为25
myLauncher.capsuleHalfLength = 25;
// 开启反弹
myLauncher.isShouldBounce = true;
// 设置碰撞速度衰减为0.5
myLauncher.collisionVelocityRetention = 0.5;
// 给发射器追踪失败委托绑定函数,追踪失败时打印信息
myLauncher.onProjectileHomingFail.add((projectile) => {
console.log("Homing Fail");
});
// 添加客户端发送的”LAUNCHTOTARGET“事件监听器,将球朝斜上方发射并追踪NPC。
Event.addClientListener("LAUNCHTOTARGET", () => {
TimeUtil.delaySecond(1).then(() => {
target.destroy();
});
myLauncher.spawnProjectileInstanceLaunchToTarget(ball.gameObjectId, target, 2000, ball.worldTransform.position, new Vector(1, 0, 1));
});
}
// 下列逻辑在客户端执行
if(SystemUtil.isClient()) {
// 添加一个按键方法:按下按键”1“,向服务端派送一个”LAUNCHTOTARGET“事件,发射一个球追踪NPC。
InputUtil.onKeyDown(Keys.One, () => {
Event.dispatchToServer("LAUNCHTOTARGET");
});
}
}
}
onProjectileLifeEnd
• onProjectileLifeEnd: MulticastDelegate
<(projectile
: ProjectileInst
) => void
>
投掷物生命周期结束(即速度降为0、LifeSpan 到期)时触发绑定函数
Precautions
所有投掷物都是使用的同一个回调,请不要循环添加事件绑定函数;客户端添加的回调,在发射双端对象时,此委托触发时无法保证实例是否依然存在
onProjectileLifeStart
• onProjectileLifeStart: MulticastDelegate
<(projectile
: ProjectileInst
) => void
>
投掷物生成实例时触发绑定函数,此时实例还没有开始移动
Precautions
所有投掷物都是使用的同一个回调,请不要循环添加事件绑定函数
Accessors
acceleration
• | • | ||||
---|---|---|---|---|---|
投掷物运动的加速度(cm/s),正值会使投掷物加速,负值减速。default: 0,range: [-10000,10000]。 Returns
| 投掷物运动的加速度(cm/s),正值会使投掷物加速,负值减速。default: 0,range: [-10000,10000]。 Parameters
|
capsuleHalfLength
• | • | ||||
---|---|---|---|---|---|
投掷物碰撞胶囊体的半长(cm),半长小于半径时为球体。default: 50。range: [1, 1000]。 Returns
| 投掷物碰撞胶囊体的半长(cm),半长小于半径时为球体。default: 50。range: [1, 1000]。 Parameters
|
capsuleRadius
• | • | ||||
---|---|---|---|---|---|
投掷物碰撞胶囊体的半径(cm)。default: 25。range: [1, 1000]。 Returns
| 投掷物碰撞胶囊体的半径(cm)。default: 25。range: [1, 1000]。 Parameters
|
collisionVelocityRetention
• | • | ||||
---|---|---|---|---|---|
碰撞后投掷物保持原来速度的比例。0表示。default: 0.6。range: [0, 1]。 Returns
| 碰撞后投掷物保持原来速度的比例。0表示。default: 0.6。range: [0, 1]。 Parameters
|
gravityScale
• | • | ||||
---|---|---|---|---|---|
投掷物受世界重力影响的倍率,正值会使投掷物下坠,负值上升,0可以使投掷物以直线运动。default: 1,range: [-10, 10]。 Returns
| 投掷物受世界重力影响的倍率,正值会使投掷物下坠,负值上升,0可以使投掷物以直线运动。default: 1,range: [-10, 10]。 Parameters
|
initialSpeed
• | • | ||||
---|---|---|---|---|---|
投掷物的初始运动速度(cm/s),default: 5000,range: [1,100000]。 Returns
| 投掷物的初始运动速度(cm/s),default: 5000,range: [1,100000]。 Parameters
|
isRotationFollowsVelocity
• | • | ||||
---|---|---|---|---|---|
投掷物的正方向(以及挂载对象)是否始终跟随运动方向。true:跟随。false:不跟随。default: true。 Returns
| 投掷物的正方向(以及挂载对象)是否始终跟随运动方向。true:跟随。false:不跟随。default: true。 Parameters
|
isShouldBounce
• | • | ||||
---|---|---|---|---|---|
决定投掷物运动过程中与其他对象发生碰撞时是否能反弹。true:反弹。false:穿透。default: true。 Returns
| 决定投掷物运动过程中与其他对象发生碰撞时是否能反弹。true:反弹。false:穿透。default: true。 Parameters
|
isShouldReplicateDelegates
• | • | ||||
---|---|---|---|---|---|
投掷物触发对应事件时是否广播(仅双端发射器生效),true:广播。false:仅本地 Returns
| 投掷物触发对应事件时是否广播(仅双端发射器生效),true:广播。false:仅本地 Parameters
|
lifeSpan
• | • | ||||
---|---|---|---|---|---|
投掷物存在的最长时间(s),0意味着没有限制。default: 10。range: [0, 1000]。 Returns
| 投掷物存在的最长时间(s),0意味着没有限制。default: 10。range: [0, 1000]。 Parameters
|
maxSpeed
• | • | ||||
---|---|---|---|---|---|
投掷物的最大运动速度(cm/s),0意味着没有限制。default: 0,range: [0,100000]。 Returns
| 投掷物的最大运动速度(cm/s),0意味着没有限制。default: 0,range: [0,100000]。 Parameters
|
Methods
predictedTrajectory
• predictedTrajectory(startPosition
, startDirection
, density
, duration
): Vector
[]
按照预测时间和密度返回的路径点数组。不预测碰撞后的反弹路径。
Parameters
startPosition Vector | 发射起始位置 |
---|---|
startDirection Vector | 发射起始方向 |
density number | 预测结果的点密度(个/秒),值越大路径点越细,性能消耗越大。 range:(0, density * duration + 1] type: 浮点数 |
duration number | 预测的时长。 range: 不做限制 type: 浮点数 |
Returns
Vector [] | 路径轨迹点,预测结果的点的最大数量为 density * duration + 1。 |
---|
Precautions
如果返回的数组长度为1,可能投掷物被卡住了
spawnProjectileInstanceLaunch
• spawnProjectileInstanceLaunch(childObjectId
, startPosition?
, direction?
, isAllClientLaunch?
): ProjectileInst
按照对象发射器当前参数生成的投掷物对象
Parameters
childObjectId string | 发射对象的 id。 range: 字符串长度取决于 ID 长度。 |
---|---|
startPosition? Vector | 发射起始位置 default: 发射对象的位置 |
direction? Vector | 发射起始方向 default: 发射对象的正前方 |
isAllClientLaunch? boolean | 仅在发射单客户端对象是有效, 是否广播到所有客户端发射实例 default: false |
Returns
ProjectileInst | 投掷物实例 |
---|
Precautions
发射后再更新其他属性无法对本次发射的投掷物产生影响
ts
@Component
export default class Example_ObjectLauncher_Acceleration extends Script {
protected async onStart(): `Promise`<`void`\> {
// 下列逻辑在服务端执行
if(SystemUtil.isServer()) {
// 在世界坐标(200,0,25)异步生成一个火箭
let rocket = await GameObject.asyncSpawn("162807") as Model;
rocket.worldTransform.position = new Vector(2000, 0, 25);
// 异步生成对象发射器
let myLauncher = await GameObject.asyncSpawn("ObjectLauncher") as ObjectLauncher;
// 设置发射初始速度为1
myLauncher.initialSpeed = 1;
// 设置发射最大速度为1000
myLauncher.maxSpeed = 1000;
// 设置发射加速度为200
myLauncher.acceleration = 200;
// 设置碰撞半径为25
myLauncher.capsuleRadius = 25;
// 设置碰撞半长为25
myLauncher.capsuleHalfLength = 25;
// 开启反弹
myLauncher.isShouldBounce = true;
// 设置重力缩放为0
myLauncher.gravityScale = 0;
// 设置旋转不跟随速度方向
myLauncher.isRotationFollowsVelocity = false;
// 运动时间为10s
myLauncher.lifeSpan = 10;
// 添加客户端发送的”LAUNCH“事件监听器,将火箭朝上方发射。
Event.addClientListener("LAUNCH", () => {
myLauncher.spawnProjectileInstanceLaunch(rocket.gameObjectId, rocket.worldTransform.position, new Vector(0, 0, 1));
rocket.localTransform.rotation = new Rotation(0, 90, 0);
});
}
// 下列逻辑在客户端执行
if(SystemUtil.isClient()) {
// 添加一个按键方法:按下按键”1“,向服务端派送一个”LAUNCH“事件,发射一个球。
InputUtil.onKeyDown(Keys.One, () => {
Event.dispatchToServer("LAUNCH");
});
}
}
}
___
### spawnProjectileInstanceLaunchToTarget <Score text="spawnProjectileInstanceLaunchToTarget" />
• **spawnProjectileInstanceLaunchToTarget**(`childObjectId`, `target`, `targetingAcceleration?`, `startPosition?`, `direction?`, `isAllClientLaunch?`): [`ProjectileInst`](mw.ProjectileInst.md)
按照对象发射器当前参数生成的投掷物对象
#### Parameters
| `childObjectId` `string` | 发射对象的 id。 range: 字符串长度取决于 ID 长度 |
| :------ | :------ |
| `target` [`GameObject`](mw.GameObject.md) | 追踪目标 |
| `targetingAcceleration?` `number` | 追踪加速度 default: 10000 range: 不做限制 type: 浮点数 |
| `startPosition?` [`Vector`](mw.Vector.md) | 发射起始位置 default: 发射对象的位置 |
| `direction?` [`Vector`](mw.Vector.md) | 发射起始方向 default: 发射对象的正前方 |
| `isAllClientLaunch?` `boolean` | 仅在发射单客户端对象是有效, 是否广播到所有客户端发射实例 default: false |
#### Returns
| [`ProjectileInst`](mw.ProjectileInst.md) | 投掷物实例 |
| :------ | :------ |
::: warning Precautions
发射后再更新其他属性无法对本次发射的子弹产生影响;
当在服务端调用方法广播,追踪模式发射时,会自带一个追踪的加速度,速度表现和预期会有差异
:::
<span style="font-size: 14px;">
使用示例:创建一个脚本放置在对象栏中,在脚本中复制下列"Example_ObjectLauncher_OnHomingFail"的代码保存,运行游戏,场景中将会生成一个对象发射器、一个用于发射的球以及一个NPC目标。给发射器对应事件的委托绑定函数。按下按键”1“,发射球并追踪NPC。设置对象代码如下:
</span>
@Component
export default class Example_ObjectLauncher_Acceleration extends Script {
protected async onStart(): `Promise`<`void`\> {
// 下列逻辑在服务端执行
if(SystemUtil.isServer()) {
// 在世界坐标(200,0,25)异步生成一个火箭
let rocket = await GameObject.asyncSpawn("162807") as Model;
rocket.worldTransform.position = new Vector(2000, 0, 25);
// 异步生成对象发射器
let myLauncher = await GameObject.asyncSpawn("ObjectLauncher") as ObjectLauncher;
// 设置发射初始速度为1
myLauncher.initialSpeed = 1;
// 设置发射最大速度为1000
myLauncher.maxSpeed = 1000;
// 设置发射加速度为200
myLauncher.acceleration = 200;
// 设置碰撞半径为25
myLauncher.capsuleRadius = 25;
// 设置碰撞半长为25
myLauncher.capsuleHalfLength = 25;
// 开启反弹
myLauncher.isShouldBounce = true;
// 设置重力缩放为0
myLauncher.gravityScale = 0;
// 设置旋转不跟随速度方向
myLauncher.isRotationFollowsVelocity = false;
// 运动时间为10s
myLauncher.lifeSpan = 10;
// 添加客户端发送的”LAUNCH“事件监听器,将火箭朝上方发射。
Event.addClientListener("LAUNCH", () => {
myLauncher.spawnProjectileInstanceLaunch(rocket.gameObjectId, rocket.worldTransform.position, new Vector(0, 0, 1));
rocket.localTransform.rotation = new Rotation(0, 90, 0);
});
}
// 下列逻辑在客户端执行
if(SystemUtil.isClient()) {
// 添加一个按键方法:按下按键”1“,向服务端派送一个”LAUNCH“事件,发射一个球。
InputUtil.onKeyDown(Keys.One, () => {
Event.dispatchToServer("LAUNCH");
});
}
}
}
___
### spawnProjectileInstanceLaunchToTarget <Score text="spawnProjectileInstanceLaunchToTarget" />
• **spawnProjectileInstanceLaunchToTarget**(`childObjectId`, `target`, `targetingAcceleration?`, `startPosition?`, `direction?`, `isAllClientLaunch?`): [`ProjectileInst`](mw.ProjectileInst.md)
按照对象发射器当前参数生成的投掷物对象
#### Parameters
| `childObjectId` `string` | 发射对象的 id。 range: 字符串长度取决于 ID 长度 |
| :------ | :------ |
| `target` [`GameObject`](mw.GameObject.md) | 追踪目标 |
| `targetingAcceleration?` `number` | 追踪加速度 default: 10000 range: 不做限制 type: 浮点数 |
| `startPosition?` [`Vector`](mw.Vector.md) | 发射起始位置 default: 发射对象的位置 |
| `direction?` [`Vector`](mw.Vector.md) | 发射起始方向 default: 发射对象的正前方 |
| `isAllClientLaunch?` `boolean` | 仅在发射单客户端对象是有效, 是否广播到所有客户端发射实例 default: false |
#### Returns
| [`ProjectileInst`](mw.ProjectileInst.md) | 投掷物实例 |
| :------ | :------ |
::: warning Precautions
发射后再更新其他属性无法对本次发射的子弹产生影响;
当在服务端调用方法广播,追踪模式发射时,会自带一个追踪的加速度,速度表现和预期会有差异
:::
<span style="font-size: 14px;">
使用示例:创建一个脚本放置在对象栏中,在脚本中复制下列"Example_ObjectLauncher_OnHomingFail"的代码保存,运行游戏,场景中将会生成一个对象发射器、一个用于发射的球以及一个NPC目标。给发射器对应事件的委托绑定函数。按下按键”1“,发射球并追踪NPC。设置对象代码如下:
</span>
@Component export default class Example_ObjectLauncher_OnHomingFail 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);
// 在世界坐标(2000,1000,130)异步生成一个NPC,2s后销毁。
let target = Player.spawnDefaultCharacter();
target.worldTransform.position = new Vector(2000, 1000, 130);
// 异步生成对象发射器
let myLauncher = await GameObject.asyncSpawn("ObjectLauncher") as ObjectLauncher;
// 设置发射初始速度为1000
myLauncher.initialSpeed = 1000;
// 设置碰撞半径为25
myLauncher.capsuleRadius = 25;
// 设置碰撞半长为25
myLauncher.capsuleHalfLength = 25;
// 开启反弹
myLauncher.isShouldBounce = true;
// 设置碰撞速度衰减为0.5
myLauncher.collisionVelocityRetention = 0.5;
// 给发射器追踪失败委托绑定函数,追踪失败时打印信息
myLauncher.onProjectileHomingFail.add((projectile) => {
console.log("Homing Fail");
});
// 添加客户端发送的”LAUNCHTOTARGET“事件监听器,将球朝斜上方发射并追踪NPC。
Event.addClientListener("LAUNCHTOTARGET", () => {
TimeUtil.delaySecond(1).then(() => {
target.destroy();
});
myLauncher.spawnProjectileInstanceLaunchToTarget(ball.gameObjectId, target, 2000, ball.worldTransform.position, new Vector(1, 0, 1));
});
}
// 下列逻辑在客户端执行
if(SystemUtil.isClient()) {
// 添加一个按键方法:按下按键”1“,向服务端派送一个”LAUNCHTOTARGET“事件,发射一个球追踪NPC。
InputUtil.onKeyDown(Keys.One, () => {
Event.dispatchToServer("LAUNCHTOTARGET");
});
}
}
}
ts