You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity运行时修改对象Tag重启后重置 如何编写多站点通用脚本

问题背景

开发地铁模拟器时,需要实现点击按钮后StationBox对象永久保留Created标签的效果,实际重启游戏后标签会恢复初始值;同时需要一套可适配所有站点的通用脚本,原有实现代码如下:

using System;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;

public class AddStation : MonoBehaviour
{
    public InputField Input;
    public Text StationName;
    public GameObject Button;
    public GameObject CreateStation;
    public GameObject StationBox;

    public void OnMouseDown(){
        if (Input.text != ""){
            CreateStation.SetActive(false);
            StationName.text = Input.text.ToString();
            StationBox.tag = "Created";
        }
    }
}
问题原因
  • Unity运行时对场景对象的Tag、文本内容、激活状态等属性的修改仅保存在内存中,游戏退出后内存释放,所有修改会自动回退到编辑器预设的初始值,不会永久留存。
  • 原有脚本硬绑定单个StationBox对象,逻辑和单个站点强耦合,无法直接复用到多站点场景。
通用解决方案

使用Unity自带的PlayerPrefs做轻量持久化存储,将站点创建状态、站点名称写入本地存储;同时拆分逻辑为单站点组件和全局触发组件,实现一套逻辑适配所有站点。

实现代码

首先编写单站点通用组件,挂在每个StationBox对象上,负责自身状态的读取和保存:

using UnityEngine;
using UnityEngine.UI;

public class StationUnit : MonoBehaviour
{
    [Tooltip("站点全局唯一ID,不可重复,例如1号线_人民广场站")]
    public string stationId;
    [Tooltip("站点名称显示文本组件")]
    public Text nameText;
    [Tooltip("站点创建面板对象")]
    public GameObject createPanel;

    void Start()
    {
        // 启动时读取本地存储的站点状态,默认未创建
        int isCreated = PlayerPrefs.GetInt($"Station_{stationId}_Created", 0);
        if (isCreated == 1)
        {
            tag = "Created";
            createPanel.SetActive(false);
            nameText.text = PlayerPrefs.GetString($"Station_{stationId}_Name", string.Empty);
        }
        else
        {
            // 替换为你项目里站点的初始默认标签
            tag = "Untagged";
            createPanel.SetActive(true);
            nameText.text = string.Empty;
        }
    }

    /// <summary>
    /// 站点创建逻辑,由创建按钮触发
    /// </summary>
    /// <param name="nameInput">全局共用的名称输入框</param>
    public void CreateThisStation(InputField nameInput)
    {
        if (string.IsNullOrWhiteSpace(nameInput.text)) return;
        
        // 更新运行时状态
        tag = "Created";
        createPanel.SetActive(false);
        nameText.text = nameInput.text.Trim();
        
        // 写入本地持久化存储
        PlayerPrefs.SetInt($"Station_{stationId}_Created", 1);
        PlayerPrefs.SetString($"Station_{stationId}_Name", nameText.text);
        PlayerPrefs.Save();
        
        // 清空输入框
        nameInput.text = string.Empty;
    }
}

再编写按钮触发的通用脚本,挂在每个站点的创建按钮上:

using UnityEngine;
using UnityEngine.UI;

public class CreateStationTrigger : MonoBehaviour
{
    [Tooltip("全局共用的站点名称输入框")]
    public InputField nameInput;
    [Tooltip("当前按钮对应的站点对象")]
    public StationUnit targetStation;

    public void OnMouseDown()
    {
        targetStation.CreateThisStation(nameInput);
    }
}

使用步骤

  • 删除原有AddStation脚本,将上述两个脚本导入项目
  • 选中每个StationBox对象,挂载StationUnit组件,填写不重复的唯一stationId,将对象下对应的名称文本、创建面板拖到组件对应字段
  • 选中每个站点的创建按钮,挂载CreateStationTrigger组件,将全局输入框、按钮对应的站点对象拖到组件对应字段,将按钮点击事件绑定到组件的OnMouseDown方法
  • 后续新增站点时重复上述挂载操作即可,不需要修改代码;如果需要重置所有站点状态,调用PlayerPrefs.DeleteAll()即可清空本地存储的站点数据。

内容的提问来源于stack exchange,提问作者Ilya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 09:54:27