创建脚本 BuildSpawnCtrl 和 SpawnConfig
创建空节点BuildSpawn 关联脚本

脚本代码如下。
import { _decorator, Component, Node, Pool, math, Vec3, instantiate, CCInteger } from 'cc';
import { SpawnItemData, SpawnItem, SpawnConfig } from './SpawnConfig';
import { GameCtl } from '../GameCtl';
const { ccclass, property } = _decorator;
@ccclass('BuildSpawnCtrl')
export class BuildSpawnCtrl extends Component {
@property({
type: CCInteger,
displayOrder:2
})
public roadStartZ = 0;//道路 开始的位置
@property({
type: CCInteger,
displayOrder:5
})
public roadLength = 0;//道路长度
@property({
type: CCInteger,
displayOrder:8
})
public recoverOffset = 0;//超过相机多少米回收
@property({
type: [SpawnItemData],
displayOrder:12 //SpawnItemData就是 prefab预制体 和 int 预制的长度
})
public spawnItemDataArray: SpawnItemData[] = [];
startCreateZ: number = 0;
runtimeSpawnItemList: SpawnItem[] = [];
poolMap: Map<string, Pool<SpawnItem>> = new Map<string, Pool<SpawnItem>>();
start() {
for (let itemData of this.spawnItemDataArray) {
let temp = new Pool<SpawnItem>(() => { return this.CreateSpawnItem(itemData) }, 1)
this.poolMap.set(itemData.prefab._uuid, temp);
}
this.startCreateZ = this.roadStartZ;
}
update(dt: number) {
this.CreateInEnd_z();//创建物体到末尾
this.recoverLessZ();//超过范围的物体回收
}
protected endZ(): number {
//这个应该是随着 奔跑而变化的 一个数 我们的终点一直在变。 我们小车当前的位置加上道路的长度
return GameCtl._instance.getCurrentZ()+this.roadLength;
}
//创建物体到尽头
CreateInEnd_z() {
let p_endZ = this.endZ();//最后的z 是多少
while (this.startCreateZ < p_endZ) {
let spawnItem = this.DoSpawnItem(this.startCreateZ);
if (spawnItem != null) {
this.startCreateZ = this.startCreateZ + spawnItem.spawnItemData.node_length;
}
}
}
//创建物体 z是设置的位置
protected DoSpawnItem(z: number): SpawnItem | undefined {
//随机创建预制体
let rndIdk = math.randomRangeInt(0, this.spawnItemDataArray.length);
var spawnItemData = this.spawnItemDataArray[rndIdk];
let item = this.poolMap.get(spawnItemData.prefab._uuid)?.alloc();
if (item != null) {
this.node.scene.addChild(item.node);//取出
this.onSpawn(item.node, spawnItemData, z);
}
return item;
}
protected CreateSpawnItem(spawnItemDate: SpawnItemData) {
var newGo = instantiate(spawnItemDate.prefab) as Node;
this.node.scene.addChild(newGo);
let spawnItem = new SpawnItem();
spawnItem.node = newGo;
spawnItem.spawnItemData = spawnItemDate;
//给回收用的
this.runtimeSpawnItemList.push(spawnItem);
return spawnItem;
}
//设置物体的位置
protected onSpawn(newGo: Node, spawnItemDate: SpawnItemData, z: number) {
newGo.setPosition(new Vec3(0, 0, z));
/*
let rnd = math.randomRangeInt(0, 2);
let scale = newGo.scale.clone();
scale.x = 1;
if (rnd == 0) {
scale.x = -1;//x轴是朝向
}
newGo.setScale(scale);
*/
newGo.active = true;
}
recoverLessZ() {
//回收超出镜头的物体
for (const spawnItem of this.runtimeSpawnItemList) {
//item = spawnItemData(prefab预制体 和 node_length 预制的长度) + Node
if (spawnItem.node.active) {
let length = spawnItem.spawnItemData.node_length;//
if (spawnItem.node.position.z + length + this.recoverOffset < GameCtl._instance.getCurrentZ() ) {
this.poolMap.get(spawnItem.spawnItemData.prefab._uuid)?.free(spawnItem);
spawnItem.node.active = false;
}
}
}
}
}import { _decorator, Component, Node, CCInteger, Prefab } from 'cc';
const { ccclass, property } = _decorator;
export class SpawnItem{
public spawnItemData : SpawnItemData = null!;
public node : Node = null!;
}
@ccclass('SpawnItemData')
export class SpawnItemData{
@property({
type: CCInteger
})
public node_length = 0;//物体的长度
@property({
type: Prefab
})
public prefab:Prefab = null!;//物体的预设
}
@ccclass('SpawnConfig')
export class SpawnConfig extends Component {
@property({
type: CCInteger,
displayOrder:2
})
public roadStartZ = 0;//道路开始的位置
@property({
type: CCInteger,
displayOrder:5
})
public roadLength = 0;//道路长度
@property({
type: CCInteger,
displayOrder:8
})
public recoverOffset = 0;//超过相机多少米回收
@property({
type: [SpawnItemData],
displayOrder:12
})
public spawnItemDataArray:SpawnItemData[] = [];
}站长微信:xiaomao0055
站长QQ:14496453