创建脚本 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