2015-03-01 15:42:53 book_longssl 阅读数 1674

    



  介绍
  JSON是一个简单的,但功能强大的序列化数据格式。它定义了简单的类型,如布尔,数(int和float)和字符串,和几个数据结构:list和dictionnary。可以在http://JSON.org了解关于JSON的更多信息。
  litjson是用C #编写的,它的目的是要小,快速,易用。它使用了Mono框架。
  安装LitJSON
  将LitJSON编译好的dll文件通过Import New Asset的方式导入到项目中,再使用Using LitJSON即可使用JSONMapper类中的简便方法。dll的下载地址在这里.
  将JSON转化为Object并可逆向转化
  为了在.Net程序中使用JSON格式的数据。一个自然的方法是使用JSON文本生成一个特定的类的一个新实例;为了匹配类的格式,一般存储的JSON字符串是一个字典。
  另一方面,为了将对象序列化为JSON字符串,一个简单的导出操作,听起来是个好主意。
  为了这个目的,LitJSON包引入了JsonMapper类,它提供了两个用于做到 JSON转化为object 和 object转化为JSON 的主要方法。这两个方法是jsonmapper.toobject和jsonmapper.tojson。
  将object转化为字符串之后,我们就可以将这个字符串很方便地在文件中读取和写入了。
  一个简单的JsonMapper的例子
  在下面的例子中,ToObject方法有一个泛型参数,来指定返回的某种特定的数据类型:即JsonMapper.ToObjectT。
  
using LitJson;
  using System;
  public class Person
  {
  // C# 3.0 auto-implemented properties
  public string   Name     { get; set; }
  public int      Age      { get; set; }
  public DateTime Birthday { get; set; }
  }
  public class JsonSample
  {
  public static void Main()
  {
  PersonToJson();
  JsonToPerson();
  }
  public static void PersonToJson()
  {
  Person bill = new Person();
  bill.Name = "William Shakespeare";
  bill.Age  = 51;
  bill.Birthday = new DateTime(1564, 4, 26);
  string json_bill = JsonMapper.ToJson(bill);
  Console.WriteLine(json_bill);
  }
  public static void JsonToPerson()
  {
  string json = @"
  {
  ""Name""     : ""Thomas More"",
  ""Age""      : 57,
  ""Birthday"" : ""02/07/1478 00:00:00""
  }";
  Person thomas = JsonMapper.ToObjectPerson(json);
  Console.WriteLine("Thomas' age: {0}", thomas.Age);
  }
  }


  上文的输出:
  {"Name":"William Shakespeare","Age":51,"Birthday":"04/26/1564 00:00:00"}
  Thomas' age: 57
  使用非泛型的JsonMapper.ToObject
  当不存在特定的JSON数据类时,它将返回一个JSONData实例。JSONData是一种通用型可以保存任何数据类型支持JSON,包括list和dictionary。
  声明:此篇文档时来自于【狗刨学习网】社区-unity极致学院,是网友自行发布的Unity3D学习文章,如果有什么内容侵犯了你的相关权益,请与官方沟通,我们会即时处理。
using LitJson;
  using System;
  public class JsonSample
  {
  public static void Main()
  {
  string json = @"
  {
  ""album"" : {
  ""name""   : ""The Dark Side of the Moon"",
  ""artist"" : ""Pink Floyd"",
  ""year""   : 1973,
  ""tracks"" : [
  ""Speak To Me"",
  ""Breathe"",
  ""On The Run""
  ]
  }
  }
  ";
  LoadAlbumData(json);
  }
  public static void LoadAlbumData(string json_text)
  {
  Console.WriteLine("Reading data from the following JSON string: {0}",
  json_text);
  JsonData data = JsonMapper.ToObject(json_text);
  // Dictionaries are accessed like a hash-table
  Console.WriteLine("Album's name: {0}", data["album"]["name"]);
  // Scalar elements stored in a JsonData instance can be cast to
  // their natural types
  string artist = (string) data["album"]["artist"];
  int    year   = (int) data["album"]["year"];
  Console.WriteLine("Recorded by {0} in {1}", artist, year);
  // Arrays are accessed like regular lists as well
  Console.WriteLine("First track: {0}", data["album"]["tracks"][0]);
  }
  }
  上面例子的输出:
  Reading data from the following JSON string:
  {
  "album" : {
  "name"   : "The Dark Side of the Moon",
  "artist" : "Pink Floyd",
  "year"   : 1973,
  "tracks" : [
  "Speak To Me",
  "Breathe",
  "On The Run"
  ]
  }
  }
  Album's name: The Dark Side of the Moon
  Recorded by Pink Floyd in 1973
  First track: Speak To Me
  Reader和Writer
  一些人喜欢使用stream的方式处理JSON数据,对于他们, 我们提供的接口是jsonreader和jsonwriter。
  JSONMapper实际上是建立在以上两个类的基础上的,所以你可以把这两个类当成是litJSON的底层接口。
  使用JsonReader
  using LitJson;
  using System;
  public class DataReader
  {
  public static void Main()
  {
  string sample = @"{
  ""name""  : ""Bill"",
  ""age""   : 32,
  ""awake"" : true,
  ""n""     : 1994.0226,
  ""note""  : [ ""life"", ""is"", ""but"", ""a"", ""dream"" ]
  }";
  PrintJson(sample);
  }
  public static void PrintJson(string json)
  {
  JsonReader reader = new JsonReader(json);
  Console.WriteLine ("{0,14} {1,10} {2,16}", "Token", "Value", "Type");
  Console.WriteLine (new String ('-', 42));
  // The Read() method returns false when there's nothing else to read
  while (reader.Read()) {
  string type = reader.Value != null ?
  reader.Value.GetType().ToString() : "";
  Console.WriteLine("{0,14} {1,10} {2,16}",
  reader.Token, reader.Value, type);
  }
  }
  }


  输出如下:
  
Token      Value             Type
  ------------------------------------------
  ObjectStart                           
  PropertyName       name    System.String
  String       Bill    System.String
  PropertyName        age    System.String
  Int         32     System.Int32
  PropertyName      awake    System.String
  Boolean       True   System.Boolean
  PropertyName          n    System.String
  Double  1994.0226    System.Double
  PropertyName       note    System.String
  ArrayStart                           
  String       life    System.String
  String         is    System.String
  String        but    System.String
  String          a    System.String
  String      dream    System.String
  ArrayEnd                           
  ObjectEnd





2018-04-27 15:24:47 yuyingwin 阅读数 840

一、封装一个基类,实现继承类创建一次后,脱离调用Unity3D先找到gameObject,才能访问物体上上脚本组件。

      实现原理,在Awake方法内,将脚本添加到一个字典Dictionary里面。使用时,从字典里获取。

      基类源码:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
[ExecuteInEditMode]
public class ZeroneXMono : MonoBehaviour
{
    /// <summary>
    /// string 代指当前 gameObject.Name
    /// </summary>
    public static Dictionary<string, Component> scriptsMonobehaviours = new Dictionary<string, Component>();


    public void Awake()
    {
        scriptsMonobehaviours.Add(name, this);
    }


    private void Start()
    {


    }


    public static T GetComponent<T>(string name)
    {
        return scriptsMonobehaviours[name].GetComponent<T>();
    }

}

测试脚本 B:

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


public class B : ZeroneXMono
{
    private void Start()
    {


    }
    public void DebugB()
    {
        Debug.Log("B");
    }

}

测试脚本 A:

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


public class A : MonoBehaviour
{
    private void Start()
    {


    }
    public void DebugD()
    {
        ZeroneXMono.GetComponent<B>("B").DebugB();
    }

}

测试方法:将脚本A、B分别挂在两个空物体上,将脚本B的gameObject名称改为"B",通过执行A脚本DebugD()方法来实现调用功能。


2016-09-06 09:09:14 sinat_35761779 阅读数 252

蓝鸥Unity开发基础——字典

一,字典

Dictionary是存储键和值的集合

Dictionary是无序的,键Key是唯一的

 

using System;
//引用泛型集合命名空间
using System.Collections.Generic;

namespace Lesson_24
{
    class MainClass
    {
        public static void Main (string[] args)
        {
            //创建一个字典对象,key的类型是string,Value的类型是int
            Dictionary<string,int> dic=new Dictionary<string,int>();

            //Add方法用来添加键值对
            dic.Add("laowang",13);
            dic.Add("laozhang",18);

            //从字典中移除键值对
            dic.Remove ("laowang");

            //清空当前字典
            dic.Clear ();

            //获取当前字典中KeyValue的个数
            int count = dic.Count;
            Console.WriteLine ("当前字典中有"+count+"个keyvalue");

            //检查字典中是否包含指定的Key
            bool b=dic.ContainsKey("xiaoming");

            //检查字典中是否包含指定的Value
            bool c = dic.ContainsValue (15);

            //尝试获取指定的key所对应的Value
            int s;
            dic.TryGetValue ("xiaoming",out s);

            //如果当前字典中包含xiaoming这个key,那么就获取对应的Value并保存在s中bb=true
            //如果当前字典中不包含xiaoming这个key,那么s=null,bb=false


            //通过Key获取Value
            int age= dic["laowang"];
            Console.WriteLine (age);

        }
    }
}

 

 

2020-01-12 21:20:07 achivieme 阅读数 1295

关于Unity3d ScriptableObject储存的问题

无法保存的类型

1 二维以上的数组(list包含一个数组也不行)
2未标记为可序列化的类 结构体等或者不可序列化的对象
3 字典
4 泛型
5 7层以上深度序列化

解决办法

1 把二维以上的数组或者list转换为1维
2 加上[Serializable],加上这个还不够,因为如果这个类或者结构体等等里面的内容有部分无法序列化,这一部分依然无法储存。
3 把字典转换为1维数组等若干数据
4 不要出现泛型

具体解决方法

二维数组

[Serializable]
public struct TwoDimensionAlarray<T1>
{
    T1[] array1;
    int[] index;
    int total;
    public void Save(T1[][] data)
    {
       
        index = new int[data.Length] ;
        for (int i=0;i<data.Length;i++)
        {
            total += data[i].Length;
            index[i] = data[i].Length;
        }
        array1 = new T1[total];
       
        var nowindex = 0;
        for (int i = 0; i < data.Length; i++)
        {
            for (int j = 0; j < data[i].Length; j++)
            {
                array1[nowindex] = data[i][j];
                nowindex++;
            }
        }
        Debug.Log("储存" + array1);
    }
    public void ReLoad(ref T1[][] data)
    {
        data = GetTheArray();
    }
    public T1[][] GetTheArray()
    {
        Debug.Log("读取" + array1);
        T1[][] data;
        if (index == null)
        {
            Debug.LogWarning("好歹你得先save再读取吧!");
            data = null;
        }
        else
        {
            var nowindex = 0;
            data = new T1[index.Length][];
            for (int i = 0; i < index.Length; i++)
            {
                data[i] = new T1[index[i]];
                for (int j = 0; j < index[i]; j++)
                {
                    data[i][j] = array1[nowindex];
                    nowindex++;
                }
            }
        }
        return data;
    }
}

这样子可以将2维数组转为1维,但是问题来了,因为表达为泛型的话,他是无法保存的。所以使用的时候,我们必须要把泛型具体化。比如我要转换二维int。

[Serializable]
public struct TwoDimensionAlarrayint
{
   int[] array1;
   int[] index;
     int total;
    public void Save(int[][] data)
    {

        index = new int[data.Length];
        for (int i = 0; i < data.Length; i++)
        {
            total += data[i].Length;
            index[i] = data[i].Length;
        }
        array1 = new int[total];

        var nowindex = 0;
        for (int i = 0; i < data.Length; i++)
        {
            for (int j = 0; j < data[i].Length; j++)
            {
                array1[nowindex] = data[i][j];
                nowindex++;
            }
        }
        Debug.Log("储存" + array1);
    }
    public void ReLoad(ref int[][] data)
    {
        data = GetTheArray();
    }
    public int[][] GetTheArray()
    {
        Debug.Log("读取" + array1);
        int[][] data;
        if (index == null)
        {
            Debug.LogWarning("好歹你得先save再读取吧!");
            data = null;
        }
        else
        {
            var nowindex = 0;
            data = new int[index.Length][];
            for (int i = 0; i < index.Length; i++)
            {
                data[i] = new int[index[i]];
                for (int j = 0; j < index[i]; j++)
                {
                    data[i][j] = array1[nowindex];
                    nowindex++;
                }
            }
        }
        return data;
    }
}

这样子就可以将二维保存为1维,但是就是每储存一种类型就要写一个 ,很不方便。list的话可以用表达式的tolist()转换。

未标记序列化

。。那就加上去。。。[Serializable]

字典

因为泛型不能使用,所以,字典的储存也是比较麻烦的。
但是思路是和二维数组差不多,把字典转换为1维数组就可以了。

三维数组的一个技巧。若要三维数组的话,只要在二维数组的转换对象基础上TwoDimensionAlarrayxx,声明一个数组。如

 TwoDimensionAlarrayObject[] valueser2;
储存
 for (int i = 0; i < valueser2.Length; i++)
        {
            valueser2[i].Save(values2[i]);
        }
读取
 for (int i=0;i<values2.Length;i++)
        {
            values2[i] = valueser2[i].GetTheArray();
        }

values2是一个三维数组。
更多维度的就以此类推。

7层以上的深度序列化

另一个文章里面写了
https://blog.csdn.net/achivieme/article/details/103949800
实际上,学好数据结构是很重要的,我没有学过数据结构,而且之前对这个也不是很了解,所以导致游戏的一个编辑器系统做到后期储存出现了这种重大问题,懒得重构系统框架,只能用这种耗费内存的办法来适配。也就是代码里面的save 和 load方法。做事情之前,一定要先想好,不然后面有大麻烦。

2017-05-19 21:12:22 BIGMAD 阅读数 1208

##Unity3d - 动态读取Multiply的Sprites

今日在敲代码的时候发现一个问题,就是不能用Resources.Load()读取设置了Multiply的Sprites,难道要一个一个做出来然后再一个一个读取吗?太麻烦,于是在网上搜,搜到的并不完整,自己捣鼓一番补完整。

首先开头要引用

using System.Collections.Generic

然后要定义字典

private Dictionary<string, object> spritesDictionary = new Dictionary<string, object>();

定义Sprites数组

private Sprite[] sprites;

下面是读取所有Sprites的代码。

public void LoadAllSprites()
        {
            sprites = Resources.LoadAll<Sprite>("Path");//Path是路径,Sprite是类型,改成Sprites的目录就行。当前的目录为工程目录"Assets/Resources/Path"
            for (int i = 0; i < sprites.Length; i++)
            {
                print("sprites[" + i + "]: " + sprites[i]);
                spritesDictionary.Add(sprites[i].name, sprites[i]);
            }
        }

下面是使用的代码,根据输入的string来返回Sprites

public Sprite ReadSpritesByString(string name)
        {
            Sprite a = null;
            foreach (KeyValuePair<string, object> pair in spritesDictionary)
            {
                Debug.Log(pair.Key + " " + pair.Value);
                if (pair.Key.ToString() == name)
                {
                    a = pair.Value as Sprite;
                }
            }
            return a;
        }

使用的方式就像如下这样

ABC.GetComponent<SpriteRenderer>().sprite = ReadSpritesByString("ABC");
没有更多推荐了,返回首页