> 技术文档 > 【C#】【Unity 仓库管理系统开发】_unityc#

【C#】【Unity 仓库管理系统开发】_unityc#


1. 系统概述

本系统是基于 Unity 引擎开发的简易仓库管理系统,通过 C# 语言实现了基本的物品管理功能,包括添加、删除、搜索物品,以及数据的本地存储和统计信息展示。系统采用 MVC 架构思想,确保了代码的可维护性和扩展性。

2. 系统架构
2.1 架构模式

采用简化的 MVC 架构:

  • Model:数据模型层,包含 Item 和 WarehouseData 类
  • View:视图层,负责 UI 显示 (ItemUI 类)
  • Controller:控制层,处理业务逻辑 (WarehouseManager 类)
2.2 主要组件
  1. Item 类:表示单个物品的数据结构
  1. WarehouseData 类:管理所有物品的数据
  1. WarehouseManager 类:系统核心控制器
  1. ItemUI 类:单个物品的 UI 显示控制
  1. Unity UI 组件:构成用户交互界面
3. 功能模块
3.1 物品管理
  • 添加新物品(名称、数量、价格、类别)
  • 删除物品
  • 搜索物品(支持名称、类别、ID 搜索)
3.2 数据管理
  • 本地数据存储(JSON 格式)
  • 自动加载和保存数据
  • 数据验证和错误处理
3.3 统计功能
  • 计算总库存价值
  • 显示物品总数和种类数
4. 技术实现
4.1 数据持久化
  • 使用 JsonUtility 进行 JSON 序列化 / 反序列化
  • 数据存储路径:Application.persistentDataPath
  • 文件操作封装在 WarehouseManager 类中
4.2 UI 实现
  • 使用 Unity UI 系统
  • 动态生成物品列表
  • 事件驱动的交互设计
4.3 核心算法
  • 搜索过滤算法:基于 LINQ 的列表过滤
  • 数据验证:输入格式检查和范围验证
5. 安装与使用
5.1 系统要求
  • Unity 2019.4 或更高版本
  • .NET Framework 4.x 或更高
5.2 安装步骤
  1. 创建新的 Unity 项目
  1. 添加提供的 C# 脚本
  1. 创建 UI 界面并配置引用
  1. 设置场景并运行
5.3 使用方法
  1. 在输入框中填写物品信息
  1. 点击 \"添加物品\" 按钮添加到仓库
  1. 使用搜索框查找物品
  1. 点击物品卡片上的删除按钮移除物品
6. 代码结构

WarehouseManager/

├── Item.cs # 物品数据模型

├── WarehouseData.cs # 仓库数据模型

├── WarehouseManager.cs # 核心控制器

└── ItemUI.cs # 物品UI显示控制

7. 技术难点与解决方案

技术难点

解决方案

数据持久化

使用 JSON 序列化 / 反序列化,保存到本地文件

动态 UI 生成

使用预制体和对象池技术

事件管理

实现基于委托的事件系统

输入验证

添加格式检查和错误提示

跨平台兼容

使用 Unity API 处理文件路径

8. 扩展建议
8.1 功能增强
  • 添加物品编辑功能
  • 实现库存预警系统
  • 添加导出 / 导入数据功能
  • 支持多仓库管理
8.2 性能优化
  • 大数据量下的分页显示
  • UI 渲染优化
  • 数据访问层优化
8.3 界面改进
  • 添加动画和过渡效果
  • 实现数据可视化图表
  • 优化移动端适配
9. 故障排除
9.1 常见问题
  1. 数据无法加载
    • 检查文件权限
    • 验证 JSON 文件格式
  1. UI 显示异常
    • 检查 UI 元素引用是否正确
    • 确认预制体配置无误
  1. 搜索功能失效
    • 检查搜索输入框事件绑定
    • 验证过滤逻辑
9.2 日志与调试

系统在关键操作处添加了 Debug.Log 输出,可通过 Unity 控制台查看详细信息。

10. 附录:API 参考
10.1 WarehouseManager 类

// 添加物品到仓库

public void AddItem(string name, int quantity, float price, string category)

// 搜索物品

public void SearchItems(string keyword)

// 重置搜索

public void ResetSearch()

// 移除物品

public void RemoveItem(string itemId)

// 保存数据到文件

private void SaveData()

// 从文件加载数据

private void LoadData()

10.2 ItemUI 类

// 设置物品数据并更新UI

public void SetItem(Item item)

// 移除物品事件

public Action onRemoveItem;

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

///

/// 物品UI显示控制类 - 负责在界面上显示单个物品的信息并处理移除操作
///

public class ItemUI : MonoBehaviour
{
    // UI组件引用
    [Header(\"UI References\")]
    public Text idText;         // 物品ID文本
    public Text nameText;       // 物品名称文本
    public Text quantityText;   // 物品数量文本
    public Text priceText;      // 物品价格文本
    public Text categoryText;   // 物品类别文本
    public Button removeButton; // 移除物品按钮

    // 事件委托 - 当物品被移除时触发
    public System.Action onRemoveItem;

    private string itemId; // 存储当前物品ID

    ///

    /// 设置物品数据并更新UI显示
    ///

    /// 要显示的物品数据
    public void SetItem(Item item)
    {
        // 存储物品ID并更新各UI文本显示
        itemId = item.itemId;
        idText.text = item.itemId;
        nameText.text = item.name;
        quantityText.text = item.quantity.ToString();
        priceText.text = \"¥\" + item.price.ToString(\"F2\"); // 格式化价格为两位小数
        categoryText.text = item.category;

        // 添加按钮点击事件监听
        removeButton.onClick.AddListener(RemoveItem);
    }

    ///

    /// 处理移除物品的按钮点击事件
    ///

    private void RemoveItem()
    {
        // 触发移除物品事件,传递物品ID
        if (onRemoveItem != null)
        {
            onRemoveItem(itemId);
        }
    }

    ///

    /// 当对象被销毁时调用,清理事件监听
    ///

    void OnDestroy()
    {
        // 移除按钮点击事件监听,防止内存泄漏
        removeButton.onClick.RemoveAllListeners();
    }
}    

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

///

/// 物品数据类 - 存储单个物品的基本信息
///

[Serializable]
public class Item
{
    public string itemId;      // 物品唯一ID
    public string name;        // 物品名称
    public int quantity;       // 物品数量
    public float price;        // 物品价格
    public string category;    // 物品类别
}

///

/// 仓库数据类 - 存储所有物品数据,用于JSON序列化/反序列化
///

[Serializable]
public class WarehouseData
{
    public List items = new List(); // 物品列表
}

///

/// 仓库管理主控制器 - 负责管理所有物品数据和UI交互
///

public class WarehouseManager : MonoBehaviour
{
    // UI组件引用
    [Header(\"UI References\")]
    public InputField nameInput;         // 物品名称输入框
    public InputField quantityInput;     // 物品数量输入框
    public InputField priceInput;        // 物品价格输入框
    public InputField categoryInput;     // 物品类别输入框
    public Button addButton;             // 添加物品按钮
    public InputField searchInput;       // 搜索输入框
    public Button searchButton;          // 搜索按钮
    public Button resetButton;           // 重置按钮
    public Transform itemsParent;        // 物品UI父对象
    public GameObject itemUIPrefab;      // 物品UI预制体
    public Text statusText;              // 状态文本
    public Text totalValueText;          // 总价值文本
    public Text itemCountText;           // 物品数量文本

    // 数据存储
    private WarehouseData warehouseData = new WarehouseData(); // 仓库数据
    private string dataPath; // 数据存储路径
    private string lastSearchTerm = \"\"; // 上次搜索关键词

    ///

    /// 初始化方法,在对象启用时调用
    ///

    void Start()
    {
        // 设置数据存储路径(使用Unity的持久化数据路径)
        dataPath = Path.Combine(Application.persistentDataPath, \"warehouse_data.json\");
        
        // 加载已保存的数据
        LoadData();
        
        // 更新UI显示
        UpdateUI();
        
        // 添加按钮事件监听
        addButton.onClick.AddListener(AddItem);
        searchButton.onClick.AddListener(SearchItems);
        resetButton.onClick.AddListener(ResetSearch);
        
        // 添加输入框提交事件监听
        searchInput.onEndEdit.AddListener(delegate { SearchItems(); });
    }

    ///

    /// 添加新物品到仓库
    ///

    public void AddItem()
    {
        // 获取输入值
        string name = nameInput.text.Trim();
        string category = categoryInput.text.Trim();
        
        // 验证输入
        if (string.IsNullOrEmpty(name))
        {
            ShowStatus(\"物品名称不能为空\", Color.red);
            return;
        }
        
        int quantity = 0;
        if (!int.TryParse(quantityInput.text, out quantity) || quantity < 0)
        {
            ShowStatus(\"请输入有效的数量\", Color.red);
            return;
        }
        
        float price = 0;
        if (!float.TryParse(priceInput.text, out price) || price < 0)
        {
            ShowStatus(\"请输入有效的价格\", Color.red);
            return;
        }
        
        // 创建新物品
        Item newItem = new Item
        {
            itemId = Guid.NewGuid().ToString(), // 生成唯一ID
            name = name,
            quantity = quantity,
            price = price,
            category = string.IsNullOrEmpty(category) ? \"未分类\" : category
        };
        
        // 添加到数据列表
        warehouseData.items.Add(newItem);
        
        // 保存数据
        SaveData();
        
        // 清空输入框
        ClearInputs();
        
        // 更新UI
        UpdateUI();
        
        // 显示成功状态
        ShowStatus(\"物品添加成功\", Color.green);
    }

    ///

    /// 搜索物品
    ///

    public void SearchItems()
    {
        lastSearchTerm = searchInput.text.Trim().ToLower();
        UpdateUI();
        
        if (string.IsNullOrEmpty(lastSearchTerm))
        {
            ShowStatus(\"显示所有物品\", Color.black);
        }
        else
        {
            int count = GetFilteredItems().Count;
            ShowStatus($\"找到 {count} 个匹配项\", Color.black);
        }
    }

    ///

    /// 重置搜索,显示所有物品
    ///

    public void ResetSearch()
    {
        searchInput.text = \"\";
        lastSearchTerm = \"\";
        UpdateUI();
        ShowStatus(\"显示所有物品\", Color.black);
    }

    ///

    /// 移除物品
    ///

    /// 要移除的物品ID
    public void RemoveItem(string itemId)
    {
        // 查找并移除物品
        Item itemToRemove = warehouseData.items.Find(i => i.itemId == itemId);
        if (itemToRemove != null)
        {
            warehouseData.items.Remove(itemToRemove);
            
            // 保存数据
            SaveData();
            
            // 更新UI
            UpdateUI();
            
            // 显示状态
            ShowStatus($\"已移除物品: {itemToRemove.name}\", Color.yellow);
        }
    }

    ///

    /// 更新UI显示
    ///

    private void UpdateUI()
    {
        // 清除现有物品UI
        foreach (Transform child in itemsParent)
        {
            Destroy(child.gameObject);
        }
        
        // 获取过滤后的物品列表
        List itemsToDisplay = GetFilteredItems();
        
        // 创建新的物品UI
        foreach (Item item in itemsToDisplay)
        {
            GameObject itemUIObj = Instantiate(itemUIPrefab, itemsParent);
            ItemUI itemUI = itemUIObj.GetComponent();
            
            if (itemUI != null)
            {
                // 设置物品数据并注册移除事件
                itemUI.SetItem(item);
                itemUI.onRemoveItem += RemoveItem;
            }
        }
        
        // 更新统计信息
        UpdateStats();
    }

    ///

    /// 更新统计信息(总价值和物品数量)
    ///

    private void UpdateStats()
    {
        // 计算总价值和物品总数
        float totalValue = 0;
        int totalItems = 0;
        
        foreach (Item item in warehouseData.items)
        {
            totalValue += item.price * item.quantity;
            totalItems += item.quantity;
        }
        
        // 更新统计文本
        totalValueText.text = \"总价值: ¥\" + totalValue.ToString(\"F2\");
        itemCountText.text = \"物品数量: \" + warehouseData.items.Count + \" 种 (\" + totalItems + \" 件)\";
    }

    ///

    /// 获取过滤后的物品列表(基于搜索关键词)
    ///

    /// 过滤后的物品列表
    private List GetFilteredItems()
    {
        if (string.IsNullOrEmpty(lastSearchTerm))
        {
            // 如果没有搜索关键词,返回所有物品
            return warehouseData.items;
        }
        else
        {
            // 否则返回包含搜索关键词的物品
            return warehouseData.items.FindAll(item => 
                item.name.ToLower().Contains(lastSearchTerm) ||
                item.category.ToLower().Contains(lastSearchTerm) ||
                item.itemId.ToLower().Contains(lastSearchTerm));
        }
    }

    ///

    /// 保存数据到JSON文件
    ///

    private void SaveData()
    {
        try
        {
            // 将数据转换为JSON字符串
            string jsonData = JsonUtility.ToJson(warehouseData, true);
            
            // 写入文件
            File.WriteAllText(dataPath, jsonData);
            
            Debug.Log(\"数据已保存到: \" + dataPath);
        }
        catch (Exception e)
        {
            Debug.LogError(\"保存数据失败: \" + e.Message);
            ShowStatus(\"保存数据失败\", Color.red);
        }
    }

    ///

    /// 从JSON文件加载数据
    ///

    private void LoadData()
    {
        try
        {
            // 检查文件是否存在
            if (File.Exists(dataPath))
            {
                // 读取文件内容
                string jsonData = File.ReadAllText(dataPath);
                
                // 将JSON字符串转换为数据对象
                warehouseData = JsonUtility.FromJson(jsonData);
                
                Debug.Log(\"数据已加载: \" + dataPath);
                ShowStatus(\"数据加载成功\", Color.green);
            }
            else
            {
                Debug.Log(\"数据文件不存在,创建新数据\");
                warehouseData = new WarehouseData();
            }
        }
        catch (Exception e)
        {
            Debug.LogError(\"加载数据失败: \" + e.Message);
            ShowStatus(\"加载数据失败,使用新数据\", Color.red);
            warehouseData = new WarehouseData();
        }
    }

    ///

    /// 清空所有输入框
    ///

    private void ClearInputs()
    {
        nameInput.text = \"\";
        quantityInput.text = \"\";
        priceInput.text = \"\";
        categoryInput.text = \"\";
        
        // 设置焦点到名称输入框
        nameInput.ActivateInputField();
    }

    ///

    /// 显示状态消息
    ///

    /// 要显示的消息
    /// 消息文本颜色
    private void ShowStatus(string message, Color color)
    {
        statusText.text = message;
        statusText.color = color;
        
        // 2秒后清除状态消息
        CancelInvoke(\"ClearStatus\");
        Invoke(\"ClearStatus\", 2f);
    }

    ///

    /// 清除状态消息
    ///

    private void ClearStatus()
    {
        statusText.text = \"\";
    }
}