Unity如何实现角色选择场景材质数据传递到游戏场景且不修改模型
Unity跨场景传递选中材质/皮肤方案
你现有的注释代码无法生效是因为角色选择场景加载完成后,MainMenu实例会被默认销毁,跨场景无法直接获取前序场景的脚本实例,以下是适配你需求的可落地修改方案,无需修改原有模型资源:
方案1:基于PlayerPrefs实现(适配你现有逻辑,改动最小)
你已经用到了PlayerPrefs存储解锁皮肤状态,直接复用这套逻辑存选中索引即可:
- 选择侧补充存储逻辑:玩家确认选中皮肤后、加载玩法场景前,执行以下代码存选中索引:
// 填写实际选中的皮肤索引 PlayerPrefs.SetInt("SelectedSkinIndex", 当前选中的索引); PlayerPrefs.Save(); // 后续执行加载玩法场景逻辑
- 玩法场景接收侧代码修改:
public GameObject BabyPajama; public GameObject BabyDiaper; public SkinnedMeshRenderer BabyPajamaRenderer; // 补充和选择侧配置完全一致的睡衣纹理数组,拖入相同的纹理资源即可 public Texture[] PajamasTexture; // 补充你原有逻辑用到的头发数组,和选择侧配置一致 public GameObject[] Hair; public int selectedIndex; void Start() { // 读取选中索引,默认值0做异常兜底 int targetSkinIndex = PlayerPrefs.GetInt("SelectedSkinIndex", 0); ReplaceSuit(targetSkinIndex); } public void ReplaceSuit(int index) { selectedIndex = index; // 原逻辑优化:套装显隐不需要放到循环内重复判断 BabyDiaper.SetActive(index == 0); BabyPajama.SetActive(index != 0); // 切换对应发型 for (int i = 0; i < Hair.Length; i++) { Hair[i].SetActive(i == index); } // 非尿布套装时替换睡衣纹理 if(index != 0) { // 主动获取材质副本再修改,避免部分Unity版本属性不生效 Material[] renderMats = BabyPajamaRenderer.materials; renderMats[1].mainTexture = PajamasTexture[index]; BabyPajamaRenderer.materials = renderMats; } }
方案2:全局单例持久化存储(适合多数据跨场景传递)
如果后续有更多跨场景传值需求,可以做一个不随场景销毁的全局数据持有者:
- 新建空对象挂载以下脚本,放在角色选择场景中:
public class GameData : MonoBehaviour { public static GameData Instance; // 存储选中的皮肤索引,也可以直接存选中的纹理对象 public int selectedSkinIndex; private void Awake() { if(Instance == null) { Instance = this; // 标记为不随场景销毁 DontDestroyOnLoad(gameObject); } else { Destroy(gameObject); } } }
- 选择侧选完皮肤后直接赋值
GameData.Instance.selectedSkinIndex = 选中索引,玩法场景直接读取该值即可,无需做本地存储。
注意事项
- 不要跨场景传递Renderer、GameObject这类场景实例引用,每个场景的模型组件都是独立实例,传递引用无意义
- 运行时修改材质的纹理属性只会作用于当前游戏进程,不会修改你项目中的原始材质/模型资源,符合你的需求
- 如果你用的是URP/HDRP渲染管线,确认材质的主纹理属性名,如果不是默认的
_MainTexture,需要用renderMats[1].SetTexture("对应属性名", 纹理)赋值
内容的提问来源于stack exchange,提问作者Ahsan Ali
相关产品推荐
相关产品推荐

