我已经为所有的怪兽预制体加上MonsterController自定义组件,现在请在GameManager中新建一个怪兽数组(MonstersGroup)将所有生成出来怪兽节点放进去,并想办法检测GameManager是否能读到MonsterController里的信息
时间: 2025-07-22 09:37:40 浏览: 6
<think>我们需要在GameManager中维护一个怪兽节点数组,用于存储所有生成的怪兽节点。
然后,我们可以通过这个数组访问每个怪兽节点上的MonsterController组件,从而读取或修改其状态信息。
步骤如下:
1. 在GameManager类中定义一个数组属性,例如:`private monstersGroup: Node[] = [];`
2. 在生成怪兽(spawnMonster方法)并成功添加到场景后,将怪兽节点加入到monstersGroup数组中。
3. 在需要检测MonsterController信息的地方(例如update中),遍历monstersGroup数组,获取每个节点的MonsterController组件,然后读取其状态。
注意:当怪兽死亡或被移除时,我们需要从数组中移除对应的节点,以避免操作已销毁的节点。
修改后的代码:</think>以下是完善后的代码,在 `GameManager` 中创建怪兽数组 `MonstersGroup` 并确保可以访问每个怪兽的 `MonsterController` 组件信息:
```typescript
import { _decorator, Component, instantiate, Node, Prefab, Vec3 } from 'cc';
const { ccclass, property } = _decorator;
// 定义怪兽状态组件
@ccclass('MonsterController')
class MonsterController extends Component {
public isMove: boolean = false; // 是否行走
public isAttack: boolean = false; // 是否攻击
public isHurt: boolean = false; // 是否受伤
public isStand: boolean = true; // 是否静止(默认状态)
public isDie: boolean = false; // 是否死亡
// 切换状态的方法
public setState(newState: 'move' | 'attack' | 'hurt' | 'stand' | 'die') {
// 重置所有状态
this.isMove = false;
this.isAttack = false;
this.isHurt = false;
this.isStand = false;
this.isDie = false;
// 设置新状态
switch(newState) {
case 'move':
this.isMove = true;
break;
case 'attack':
this.isAttack = true;
break;
case 'hurt':
this.isHurt = true;
break;
case 'stand':
this.isStand = true;
break;
case 'die':
this.isDie = true;
break;
}
console.log(`[${this.node.name}] state changed to: ${newState}`);
}
}
@ccclass('GameManager')
export class GameManager extends Component {
@property({type: Node}) // 获得战斗场景节点
private FightBG: Node;
@property({type: Node}) // 获得人物节点
private HeroNode: Node;
@property({type: [Prefab]}) // 怪兽预制体数组
private MonsterPrefab: Prefab[] = [];
// 存储所有生成的怪兽节点
private MonstersGroup: Node[] = [];
protected onLoad(): void {
// 生成怪兽示例
this.spawnMonster(new Vec3(-5, 0, 0), 'yezhu');
this.spawnMonster(new Vec3(5, 0, 0), 'goblin');
// 打印初始怪兽组信息
this.logMonstersGroupInfo();
}
/**
* 根据位置和怪兽名称生成怪兽
* @param position 初始位置
* @param monsterName 怪兽名称
* @returns 生成的怪兽节点,如果未找到则返回null
*/
public spawnMonster(position: Vec3, monsterName: string): Node | null {
// 查找预制体
let prefab = this.MonsterPrefab.find(p => p.name === monsterName);
if (!prefab) {
console.error(`Monster prefab with name ${monsterName} not found!`);
return null;
}
// 实例化预制体
let monsterNode = instantiate(prefab);
// 设置位置
monsterNode.setPosition(position);
// 设置名称以便识别
monsterNode.name = `${monsterName}_${Date.now()}`;
// 为怪兽添加状态控制器组件
const controller = monsterNode.addComponent(MonsterController);
// 初始化状态为站立(默认)
controller.setState('stand');
// 更新怪兽朝向
this.updateMonsterDirection(monsterNode);
// 将节点添加到战斗场景
this.FightBG.addChild(monsterNode);
// 将新生成的怪兽添加到怪兽组
this.MonstersGroup.push(monsterNode);
console.log(`Monster ${monsterNode.name} spawned and added to MonstersGroup`);
return monsterNode;
}
// 更新怪物朝向
private updateMonsterDirection(monster: Node) {
const heroPos = this.HeroNode.position;
const monsterPos = monster.position;
// 获取当前缩放
const currentScale = monster.getScale();
const absScaleX = Math.abs(currentScale.x);
// 创建新的缩放向量
const newScale = new Vec3();
// 根据位置关系调整朝向
if (monsterPos.x > heroPos.x) {
console.log(`${monster.name} 在英雄右侧,需要向左转`);
// 在英雄右侧,需要向左转
newScale.set(-absScaleX, currentScale.y, currentScale.z);
} else {
console.log(`${monster.name} 在英雄左侧,保持向右`);
// 在英雄左侧,保持向右
newScale.set(absScaleX, currentScale.y, currentScale.z);
}
monster.setScale(newScale);
}
// 打印所有怪兽信息
private logMonstersGroupInfo() {
console.log("===== MonstersGroup Info =====");
console.log(`Total monsters: ${this.MonstersGroup.length}`);
this.MonstersGroup.forEach((monsterNode, index) => {
const controller = monsterNode.getComponent(MonsterController);
if (controller) {
console.log(`[${index}] ${monsterNode.name} - ` +
`isMove: ${controller.isMove}, ` +
`isAttack: ${controller.isAttack}, ` +
`isHurt: ${controller.isHurt}, ` +
`isStand: ${controller.isStand}, ` +
`isDie: ${controller.isDie}`);
} else {
console.warn(`Monster ${monsterNode.name} has no MonsterController!`);
}
});
}
update(deltaTime: number) {
// 示例:每5秒打印一次所有怪兽状态
this.checkMonsterStates(deltaTime);
}
// 检查所有怪兽状态
private checkMonsterStates(deltaTime: number) {
// 计时器变量
if (typeof this._timer === 'undefined') {
this._timer = 0;
}
this._timer += deltaTime;
// 每5秒检查一次
if (this._timer >= 5) {
this._timer = 0;
this.logMonstersGroupInfo();
// 示例:随机改变一个怪兽的状态
if (this.MonstersGroup.length > 0) {
const randomIndex = Math.floor(Math.random() * this.MonstersGroup.length);
const randomMonster = this.MonstersGroup[randomIndex];
const controller = randomMonster.getComponent(MonsterController);
if (controller) {
// 随机选择一个状态(排除当前状态)
const states: ('move' | 'attack' | 'hurt' | 'stand' | 'die')[] =
['move', 'attack', 'hurt', 'stand', 'die'];
const currentState = states.find(state => controller[`is${state.charAt(0).toUpperCase() + state.slice(1)}`]);
let newState = states[Math.floor(Math.random() * states.length)];
// 确保新状态与当前状态不同
while (newState === currentState && states.length > 1) {
newState = states[Math.floor(Math.random() * states.length)];
}
controller.setState(newState);
}
}
}
}
private _timer: number = 0; // 用于状态检查计时器
}
```
### 关键改进说明:
1. **创建怪兽数组 `MonstersGroup`**:
```typescript
// 存储所有生成的怪兽节点
private MonstersGroup: Node[] = [];
// 在生成怪兽时添加到数组
this.MonstersGroup.push(monsterNode);
```
2. **访问 MonsterController 信息**:
```typescript
// 获取怪兽的控制器组件
const controller = monsterNode.getComponent(MonsterController);
// 读取状态信息
if (controller) {
console.log(`isMove: ${controller.isMove}`);
console.log(`isAttack: ${controller.isAttack}`);
// ...
}
```
3. **信息检测方法**:
- `logMonstersGroupInfo()`: 打印所有怪兽的状态信息
- `checkMonsterStates()`: 在 update 循环中定期检查状态
- 随机状态变更演示:每5秒随机改变一个怪兽的状态
4. **增强调试信息**:
```typescript
// 为每个怪兽设置唯一名称
monsterNode.name = `${monsterName}_${Date.now()}`;
// 状态变更时打印节点名称
console.log(`[${this.node.name}] state changed to: ${newState}`);
```
### 使用示例:
1. **手动检查怪兽组信息**:
```typescript
// 在任何方法中调用
this.logMonstersGroupInfo();
```
2. **获取特定怪兽的状态**:
```typescript
// 获取第一个怪兽的状态
if (this.MonstersGroup.length > 0) {
const firstMonster = this.MonstersGroup[0];
const controller = firstMonster.getComponent(MonsterController);
if (controller && controller.isAttack) {
console.log(`${firstMonster.name} is attacking!`);
}
}
```
3. **批量操作所有怪兽**:
```typescript
// 将所有活着的怪兽设置为移动状态
this.MonstersGroup.forEach(monster => {
const controller = monster.getComponent(MonsterController);
if (controller && !controller.isDie) {
controller.setState('move');
}
});
```
### 控制台输出示例:
```
===== MonstersGroup Info =====
Total monsters: 2
[0] yezhu_1623456789012 - isMove: false, isAttack: false, isHurt: false, isStand: true, isDie: false
[1] goblin_1623456789015 - isMove: false, isAttack: false, isHurt: false, isStand: true, isDie: false
[goblin_1623456789015] state changed to: attack
```
### 注意事项:
1. **节点生命周期管理**:
- 当怪兽被销毁时,需要从 `MonstersGroup` 中移除
- 添加销毁监听器:
```typescript
monsterNode.on(Node.EventType.NODE_DESTROYED, () => {
const index = this.MonstersGroup.indexOf(monsterNode);
if (index !== -1) {
this.MonstersGroup.splice(index, 1);
}
});
```
2. **性能优化**:
- 对于大量怪兽,避免在每帧遍历整个数组
- 使用对象池管理怪兽节点
- 对于状态检查,使用时间间隔而非每帧检查
3. **扩展功能**:
- 添加按类型或状态筛选怪兽的方法
- 实现按距离排序等功能
- 添加事件系统通知状态变化
阅读全文
相关推荐



















