如何实现按'1'键循环调用setMaterial遍历std::vector元素?
解决方案:跟踪当前索引实现循环切换
要实现每次按1键切换到下一个材质、遍历完后循环的效果,核心是维护一个状态变量来记录当前选中的材质索引,每次按键时更新这个索引并调用setMaterial。下面是具体的实现步骤:
1. 添加状态变量(推荐方式)
如果你的代码是在类成员函数中编写的,建议在类定义里添加一个成员变量来跟踪当前索引:
// 放在你的类的私有/保护成员区域 size_t mCurrentMaterialIdx = 0;
2. 修改按键绑定的Lambda函数
把原来一次性遍历所有材质的Lambda,改成每次按键更新索引并调用一次setMaterial:
auto buttonPress = [this] { // 递增索引,满足首次按'1'调用mMaterials[1]的需求 mCurrentMaterialIdx++; // 当索引超出范围时,重置为0(回到第一个元素) if (mCurrentMaterialIdx >= mMaterials.size()) { mCurrentMaterialIdx = 0; // 如果希望循环回到mMaterials[1]而非[0],就把这里改成1 // 但要确保mMaterials.size() > 1,避免越界 } // 边界保护:确保材质列表不为空时才调用 if (!mMaterials.empty()) { mAcoustics->setMaterial(mMaterials[mCurrentMaterialIdx]); } }; InputManager::bindKeyFunction(0x31 /* '1' key */, buttonPress, ETriggerEvent::OnRelease);
3. 可选:使用静态变量(不推荐多实例场景)
如果不想添加类成员变量,也可以在Lambda内部使用静态变量来保存状态,但这种方式在类的多个实例或多次绑定按键时会共享状态,需要谨慎使用:
auto buttonPress = [this] { static size_t currentIdx = 0; currentIdx++; if (currentIdx >= mMaterials.size()) { currentIdx = 0; } if (!mMaterials.empty()) { mAcoustics->setMaterial(mMaterials[currentIdx]); } };
关键细节说明
- 初始索引设为
0是为了满足你“首次按'1'调用mMaterials[1]”的需求——首次按键时索引先递增到1,正好对应目标元素。 - 添加了
!mMaterials.empty()的判断,避免材质列表为空时出现数组越界崩溃,这在单元测试中是很重要的边界处理。 - 如果你的材质列表第一个有效元素是索引
0,只需要把初始索引设为mMaterials.size()-1,或者调整递增逻辑为先调用再递增即可。
内容的提问来源于stack exchange,提问作者Shan Anis
相关产品推荐
相关产品推荐

