U3D 装备的添加和移除(Unity3D)

本案例主要实现功能如下:
1.创建UI界面,包含两个装备栏,四个武器选择栏以及显示人物的属性的文本框
2.每一个装备都有自己的属性(AD/AP/AR/MP)
3.人物也有自己的基础属性(AD/AP/AR/MP)
4.可添加或移除装备到人物的装备栏中,最多两个
5.丢弃装备后,可添加新的装备
6.添加装备,人物的对应属性增加
7.减少装备,人物的对应属性减少
8.界面属性值和数据库中数据同步

创建数据库,包括英雄(Hero)信息和装备(Equip)信息

创建DataController脚本,用于封装一些数据库的操作
该脚本为单例脚本,方便外部的调用.
引入Mono.Data.Sqlite命名空间(需要在Project中导入Plugins文件夹,里面含有对应的dll文件)

将脚本写为单例脚本
//单例脚本
    public static DataController Instance;
void Awake ()
    {
        Instance = this;
    }

脚本中声明是的字段
//数据库对象
    SqliteConnection connection;
    SqliteCommand command;
    SqliteDataReader reader;
    //数据库路径
    string sqlitePath;

1.创建数据库连接并打开数据库
/// <summary>
    /// 连接数据库方法
    /// </summary>
    /// <param name="DBName">数据库名称</param>
public void ConnectToSqlite (string DBName)
    {
        //如果不包含.sqlite  添加
        if (!DBName.Contains (".sqlite")) {
            DBName += ".sqlite";
        }
        //数据库路径配置
        sqlitePath = "Data Source =" + Application.streamingAssetsPath + "/" + DBName;
        //创建数据库连接对象
        connection = new SqliteConnection (sqlitePath);
        //创建数据了库命令对象
        command = connection.CreateCommand ();
        try {
            //打开数据库
            connection.Open ();
        } catch (System.Exception ex) {
            //异常信息
            Debug.Log (ex.Message);
        }
    }

2.关闭数据库方法
public void CloseSqliteConnection ()
    {
        try {
            //在数据库打开的前提下
            if (connection != null) {
                //关闭数据库
                connection.Close ();
            }
        } catch (System.Exception ex) {
            //异常信息
            Debug.Log (ex.Message);
        }
    }

3.查询属性的基本信息(人物或装备)
/// <summary>
    /// 查询属性的基本信息
    /// </summary>
    /// <returns>返回查询的结果(float数组)</returns>
    /// <param name="isHero">true:表示查询的某个英雄的信息
    ///                 false:查询某个装备的信息
    /// <param name="name">传入查询对象的方法</param>
    public float[] SelectProPertyInfo (bool isHero, string name)
    {
        try {
            //用于存储查询到的信息(AD/AP/AR/MP)
            float[] result = new float[4];
            //查询语句
            string sql;
            if (isHero) {
                //如果查询的是英雄
                sql = "select AD,AP,AR,MP from Hero where HeroName='" + name + "'";
            } else {
                sql = "select AD,AP,AR,MP from Equip where EquipName='" + name + "'";
            }
            //将SQL语句赋值给命令对象
            command.CommandText = sql;
            //执行语句
            reader = command.ExecuteReader ();
            //只读取一行
            reader.Read ();
            for (int i = 0; i < reader.FieldCount; i++) {
                //逐个获取字段值,存入数组
                result [i] = System.Convert.ToSingle (reader.GetValue (i));
            }
            reader.Close ();
            return result;
        } catch (System.Exception ex) {
            Debug.Log (ex.Message);
            return null;
        }
    }

4.当添加或移除装备,人物信息的变化
/// <summary>
    /// 添加或移除装备
    /// </summary>
    /// returns:当添加或移除装备后对应英雄变化后的数据
    /// <param name="isAdd" true:添加  false:移除装备
    /// <param name="heroInfo  要添加或移除装备的英雄信息
    /// <param name="equipInfo  要添加或移除的装备信息
    public float[] AddOrRemoveProperty (bool isAdd, float[] heroInfo, float[] equipInfo)
    {
        try {
            if (heroInfo.Length == 4 && equipInfo.Length == 4) {
                //声明存放运算结果的数组
                float[] result = new float[4];
                if (isAdd) {
                    //将两个数组的元素相加
                    for (int i = 0; i < result.Length; i++) {
                        result [i] = heroInfo [i] + equipInfo [i];
                    }
                } else {
                    //移除装备
                    for (int i = 0; i < result.Length; i++) {
                        result [i] = heroInfo [i] - equipInfo [i];
                    }
                }
                return result;
            }
            //参数不合法
            return null;
        } catch (System.Exception ex) {
            Debug.Log (ex.Message);
            return null;
        }
    }
5.更新英雄信息到数据库,修改信息后要将新的信息更新到数据库中
/// <summary>
    /// 更新英雄信息到数据库
    /// </summary>
    /// <param name="newHeroInfo" 更新后的英雄信息
    /// <param name="heroName"> 更新信息英雄名
    public void UpdateHeroPropety (float[] newHeroInfo, string heroName)
    {
        try {
            string sql = "update Hero set AD=" + newHeroInfo [0] + ",AP=" + newHeroInfo [1] + ",AR=" + newHeroInfo [2]+ ",MP=" + newHeroInfo [3] + " " + "where HeroName='" + heroName + "'";
            command.CommandText = sql;
            command.ExecuteNonQuery ();
        } catch (System.Exception ex) {
            Debug.Log (ex.Message);
        }
    }


在商店物品栏的父物体Shop上添加AddEquipScript脚本,实现点击装备对应的按钮后添加对应的装备到装备栏上,并修改人物的属性,跟新UI界面的显示.

脚本中定义的字段
//更新英雄信息的脚本
    HeroInfoDisplayScript heroInfoScr;
    //装备栏上的脚本
    EquipBoxesScript equipInfoScr;

在Start方法中初始化字段
void Start ()
    {
        heroInfoScr = GameObject.Find ("HeroInfoText").GetComponent<HeroInfoDisplayScript> ();
        equipInfoScr = GameObject.Find ("EquipBoxes").GetComponent<EquipBoxesScript> ();
    }

添加按钮点击响应事件
/// <summary>
    /// 点击背包中的装备按钮,给英雄添加装备
    /// </summary>
    /// <param name="btn">Button.</param>
    public void AddEquipBtnAction (GameObject btn)
    {
        int index = equipInfoScr.CanAddEquip ();
        if (index != -1) {
            //说明当前有空的装备栏,可以添加
            //1.先获取到点击要添加的图片
            Sprite equipImg = btn.GetComponent<Image> ().sprite;
            //2.将添加的按钮的图片赋值给装备栏中按钮
            equipInfoScr.transform.GetChild (index).GetComponent<Image> ().sprite = equipImg;
            //根据添加的装备名字查找这个装备
            string equipName = btn.name;
            //打开数据库
            DataController.Instance.ConnectToSqlite ("LOL");
            //找到装备信息
            float[] equipDatas = DataController.Instance.SelectProPertyInfo (false, equipName);
            // 找到英雄信息
            float[] heroDatas = DataController.Instance.SelectProPertyInfo (true, "EZ");
            //为英雄添加装备信息
            float[] newHweoDatas = DataController.Instance.AddOrRemoveProperty (true, heroDatas, equipDatas);
            //跟新信息到数据库
            DataController.Instance.UpdateHeroPropety (newHweoDatas, "EZ");
            //更新UI
            heroInfoScr.DisplayHeroInfo (newHweoDatas);
            //关闭数据库
            DataController.Instance.CloseSqliteConnection ();
        }
    }

在装备栏父物体上添加EquipBoxesScript脚本,控制装备栏中两个装备按钮的点击,主要是移除装备,并且减少英雄的属性,以及对外判断是否以继续添加装备,(在退出时记住装备栏中的装备,在程序重新加载时保持原状)

脚本中定义的字段
//默认装备栏图片
    public Sprite defaultPic;
    //英雄属性的脚本
    HeroInfoDisplayScript heroInfoScr;
    //所有的装备
    public Sprite[] equipPics;

在Start方法中初始化
void Start ()
    {
        //获得展示英雄信息的脚本
        heroInfoScr = GameObject.Find ("HeroInfoText").GetComponent<HeroInfoDisplayScript> ();
        ShowImg ();
    }

添加或者移除装备
//添加装备栏中按钮时,如果该装备栏有装备,则移除装备
    //同时更新英雄属性展示,以及更新数据库英雄数据
    //参数equip:表示点击的是哪个装备按钮
    public void RemoveEquipBtnAction (GameObject equipbtn)
    {
        //装备的默认图片,(即没有装备时的图片)
        string defaultName = "InputFieldBackground";
        //如果点击的当前按钮的图片不是默认图片的名字
        //就表示当前点击的按钮是有装备的,执行移除装备操作
        if (equipbtn.GetComponent<Image> ().sprite.name
            != defaultName) {
            //获取当前按钮上展示的装备图片的名字
            string equipName = equipbtn.GetComponent<Image> ().sprite.name;
            //移除该装备,即将该装备按钮上的图片更换成默认
            equipbtn.GetComponent<Image> ().sprite = defaultPic;
            // 开始更新数据库英雄的数据(因为装备移除了)
            DataController.Instance.ConnectToSqlite ("LOL");
            //查询当前移除的装备信息
            float[] equipDatas = DataController.Instance.SelectProPertyInfo (false, equipName);
            //查询当前操作的英雄信息
            float[] heroDatas = DataController.Instance.SelectProPertyInfo (true, "EZ");
            //更新数据后的英雄信息
            float[] newHeroInfos = DataController.Instance.AddOrRemoveProperty (false, heroDatas, equipDatas);
            //将更新后的英雄信息存储到数据库中
            DataController.Instance.UpdateHeroPropety (newHeroInfos, "EZ");
            //更新UI界面英雄信息展示
            heroInfoScr.DisplayHeroInfo (newHeroInfos);
            //关闭数据库
            DataController.Instance.CloseSqliteConnection ();
        }
    }

判断是否可以添加装备
public int CanAddEquip ()
    {
        //获取装备上的图片名称
        string equip0 = transform.GetChild (0).GetComponent<Image> ().sprite.name;
        string equip1 = transform.GetChild (1).GetComponent<Image> ().sprite.name;
        //图片的默认名字
        string defaultName = "InputFieldBackground";
        if (defaultName == equip0) {
            return 0;
        } else if (defaultName == equip1) {
            return 1;
        } else {
            //不可以添加装备了
            return -1;
        }
    }

保留图片
方法一:使用PlayerPrefs将已有的图片信息存到本地

方法二:在数据库中创建一个表用来存储图片信息

具体的存,取功能 的实现与PlayerPrefs相同

在场景中HeroInfoText上添加脚本用来控制在脚本中显示英雄的基本信息

//获得要展示英雄数据的Text
    Text infoText;

    void Start ()
    {
        infoText = GetComponent<Text> ();
        //展示英雄数据
        //1.打开数据库
        DataController.Instance.ConnectToSqlite ("LOL");
        //2.查询英雄数据
        float[] infos = DataController.Instance.SelectProPertyInfo (true, "EZ");
        //展示英雄信息到heroInfoText上
        DisplayHeroInfo (infos);
        //关闭数据库
        DataController.Instance.CloseSqliteConnection ();
    }

    /// <summary>
    /// 展示英雄信息
    /// </summary>
    /// <param name="info">要展示的数据</param>
    public void DisplayHeroInfo (float[] info)
    {
        infoText.text = 
        "攻击力: " + info [0] + "
" +
        "法强: " + info [1] + "
" +
        "护甲值: " + info [2] + "
" +
        "魔抗值: " + info [3];
    }
原文地址:https://www.cnblogs.com/zpy1993-09/p/11818077.html