unity 清空unity3d 查找子对象象temporarycachepath什么时候会清空

Unity中文培训脚本手册|unity3D官网学习教程大全
unity培训unity3d游戏开发培训专业教程,unity学习教程大全,unity官方学习网站几年的Unity学习总结 - CSDN博客
几年的Unity学习总结
stream:其中类Stream为抽象类。由此有三个派生类。 需要引入命名空间:using System.IO
MemoryStream:对内存进行读取与写入&
BufferedStream:对缓冲器进行读取/写入&
FileStream:对文件执行读取与写入&
TextReader/Writer为抽象类。由此派生类:&
StreamReader/StreamWirter 分别用于对流的读取与写入。
public abstract int Read(byte[] buffer, int offset, int count)
buffer: 字节数组。此方法返回时,该缓冲区包含指定的字符数组,该数组的 offset 和 (offset + count -1) 之间的值由从当前源中读取的字节替换。
offset: buffer 中的从零开始的字节偏移量,从此处开始存储从当前流中读取的数据。
count: 要从当前流中最多读取的字节数。
返回值:读入缓冲区中的总字节数。如果当前可用的字节数没有请求的字节数那么多,则总字节数可能小于请求的字节数,或者如果已到达流的末尾,则为零 (0)。此方法的实现从当前流中读取最多的 count 个字节,并将它们存储在从 offset 开始的 buffer 中。流中的当前位置提升已读取的字节数;
FileStream stream=new FileStream(url,FileMode.Open);
stream.Seek(offset,SeekOrigin.Begin);//本句相当于stream.position=//stream的position默认是0,读一次后position会对应加到读的位置。
//每次读之前最好都先设置一下流的读取位置。SeekOrigin.Begin表示从0开始偏移offset个数开始读,还有SeekOrigin.End和Current表示从结尾和当前位置开始偏移offset个数指定给Position。
int ret =stream.Read(data,offset,count);//这里的offset是data数组的偏移和大小,
stream.Close();//本句必须要加 不要忘记
& & //代码意思是从流偏移量为offset的地方开始读,一共读count个字节,存在data数组的offset偏移处,该数组的 offset 和 (offset + count -1) 之间的值由从当前源中读取的字节替换。
Stream.Write(byte[] buffer, int offset, int count)
FileStream stream= new FileStream(url,FileMode.Create);
if(stream!=null){
stream.position=0;
stream.write(data,offset,count);//从stream的0开始写入 一共写count字节。data从offset开始写到stream。
stream.Flush();//如果暂时不close &默认是暂时不写数据的,那么flush是立刻写入数据。
stream.Close();//关闭后 也是立刻写入数据。
------------------------------------------------------------------序列化-------------------------------------------------------------------
FileStream stream= new FileStream(url,FileMode.Create);
sdFormater.Write(stream,(int)1);//int
sdFormater.Write(stream,&name&);//string
stream.close();
sdBinaryReader stream=new sdBinaryReader(data,length);//test
sdFormater.Read(stream,ref a);//a=1
sdFormater.Read(stream,ref b);//b=&name&
//只要满足读取和写入的顺序完全一样,数据的序列化和反序列就可以完成,因为每次读取和写入的数据类型所占的字节数是固定的。比如byte1个字节,int占4个字节。
//另外文件的读写分2种,一种是整个数据结构的读写 比如一个大的string 写到byte文件文件里,那么读出来直接转换string就可以获取到数据;另外一种就是上边的 多个数据写到一个文件里边,那么读取也要按照分部读取再来转换(string)类型。直接转换肯定是错误的,读取顺序乱了 也是错误的。
一. 二进制转换成图片
MemoryStream ms = new MemoryStream(bytes);
ms.Position = 0;
Image img = Image.FromStream(ms);
ms.Close();
this.pictureBox1.Image
二. C#中byte[]与string的转换代码
1、System.Text.UnicodeEncoding converter = new System.Text.UnicodeEncoding();
  byte[] inputBytes =converter.GetBytes(inputString);
  string inputString = converter.GetString(inputBytes);
2、string inputString = System.Convert.ToBase64String(inputBytes);
  byte[] inputBytes = System.Convert.FromBase64String(inputString);
FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
三. C# Stream 和 byte[] 之间的转换
/// 将 Stream 转成 byte[]
public byte[] StreamToBytes(Stream stream)
& & byte[] bytes = new byte[stream.Length];
& & stream.Read(bytes, 0, bytes.Length);
& & // 设置当前流的位置为流的开始
& & stream.Seek(0, SeekOrigin.Begin);
/// 将 byte[] 转成 Stream
public Stream BytesToStream(byte[] bytes)
& & Stream stream = new MemoryStream(bytes);
四. Stream 和 文件之间的转换
将 Stream 写入文件
public void StreamToFile(Stream stream,string fileName)
& & // 把 Stream 转换成 byte[]
& & byte[] bytes = new byte[stream.Length];
& & stream.Read(bytes, 0, bytes.Length);
& & // 设置当前流的位置为流的开始
& & stream.Seek(0, SeekOrigin.Begin);
& & // 把 byte[] 写入文件
& & FileStream fs = new FileStream(fileName, FileMode.Create);
& & BinaryWriter bw = new BinaryWriter(fs);
& & bw.Write(bytes);
& & bw.Close();
& & fs.Close();
五. 从文件读取 Stream
public Stream FileToStream(string fileName)
{ & & & & & &
& & // 打开文件
& & FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
& & // 读取文件的 byte[]
& & byte[] bytes = new byte[fileStream.Length];
& & fileStream.Read(bytes, 0, bytes.Length);
& & fileStream.Close();
& & // 把 byte[] 转换成 Stream
& & Stream stream = new MemoryStream(bytes);
六.FileStream 读文件
byte[] byData = new byte[100];//用stream读到byte数组里边
char[] charData = new char[1000];
FileStream sFile = new FileStream(&文件路径&,FileMode.Open);
sFile.Seek(55, SeekOrigin.Begin);
sFile.Read(byData, 0, 100); //第一个参数是被传进来的字节数组,用以接受FileStream对象中的数据,第2个参数是字节数组中开始写入数据的位置,它通常是0,表示从数组的 开端文件中向数组写数据,最后一个参数规定从文件读多少字符.
七.StreamReader读取文件:
StreamReader objReader = new StreamReader(文件路径);
& & & string sLine=&&;
& & & ArrayList LineList = new ArrayList(); & &
& & & while (sLine != null)
& & & & sLine = objReader.ReadLine();
& & & & if (sLine != null&&!sLine.Equals(&&))
& & & & & LineList.Add(sLine);
& & & & & & objReader.Close();
& & & & & & return LineL
八.StreamWriter写文件:
& FileStream fs = new FileStream(文件路径, FileMode.Create);
StreamWriter sw = new StreamWriter(fs);
//开始写入
sw.Write(String);
&//清空缓冲区
sw.Flush();
sw.Close();
fs.Close();
九.读byte[]
File和Directory
File类支持对文件的基本操作,包括创建、拷贝、移动、删除和打开一个文件。Directory类则用于执行常见的各种目录操作,如创建、移动、浏览目录及其子目录。
File类和Directory类都是密封类。不象抽象类Stream,File类和Directory类可以被实例化,但它们不能被其它类继承。
File类和Directory类的基类都是抽象类FileSystemEntry。本文发表于(编程入门)
File类的静态方法主要是用于创建FileStream类。一个FileStream类的实 例实际上代表一个磁盘文件,它通过Seek()方法进行对文件的随机访问,也同时包含了流的标准输入、标准输出、标准错误等。FileStream默认对 文件的打开方式是同步的,但它同样很好地支持异步操作。
TextReader和TextWriter
TextReader和TextWriter类都是抽象类。和Stream类的字节形式的输入和输出不同,它们用于Unicode字符的输入和输出。
StringReader和StringWriter
StringReader和StringWriter在字符串中读写字符。
StreamReader和StreamWriter
StreamReader和StreamWriter在流中读写字符。
BufferedStream
BufferedStream是为诸如网络流 的其它流添加缓冲的一种流类型。其实,FileStream流自身内部含有缓冲,而MemorySteam流则不需要缓冲。一个BufferStream 类的实例可以由多个其它类型的流复合而成,以达到提高性能的目的。缓冲实际上是内存中的一个字节块,利用缓冲可以避免操作系统频繁地到磁盘上读取数据,从 而减轻了操作系统的负担。
MemoryStream
MemoryStream是一个无缓冲流,它所封装的数据直接放在内存中,因此可以用于快速临时存储、进程间传递信息等。
NetworkSteam
Networksteam表示在互联网络上传递的流。
当使用名字空间System.IO中提供的类时,对存储数据的访问权限必须符合操作系统的安全性要求。
注意:不要使用这些类来编写应用程序对网络文件进行的操作。因为Internet默认的安全政策是不允许对文件直接访问。可以使用IsolatedStroage类来处理网络文件。
--------------------------------------------------------------------------------------------
c#封装下的各个操作系统都可用的读写文件功能。
using System.IO;
using System.T
using System.Runtime.Serialization.Formatters.B
1.FileMode.Create//指定操作系统应创建新文件。 如果文件已存在,它将被覆盖。 这需要 FileIOPermissionAccess.Write 权限。
2.创建文件:
FileStream file=new FileStream(&Assets/text.txt&, FileMode.Create);/FileMode.Append 是增加新内容,不删旧内容。
byte[]data=Encoding.UTF8.GetByte(&aaa&);//need using System.Text
byte[]data=new byte[]{0xef,0xbb,0xbf};//之前写这个是csv的utf8格式。
file.Write(data,0,data.Length);//byte,offset,count
file.Close();关闭当前流并释放与之关联的所有资源(如套接字和文件句柄)。
3.文件的读写xml csv 序列化,csv自己解析 比较好 但是大量数据内存大 效率不好。最好的是序列化。序列化有2种方式:1.是保存成prefab模式,直观 好看 参考fbd.cs。2.是保存成byte文件:效率更高。因为unity的prefab序列化过程可能还需要申请临时内存 保存临时数据。不过我觉得差不多吧。
[Serializable]
public class People
& & public string Name { }
& & public int Age { }
}//prefab 模式就是在mono里定义public的 People对象,把数据写进去,存成prefab。unity编辑器方便的查看修改序列化内容。
void Write(){//序列化写byte文件
FileStream fs = new FileStream(&Asset\test.byte&, FileMode.Create);
BinaryFormatter bf = new BinaryFormatter();
List&People& ps = new List&People&();//也可以只new 一个对象
ps.Add(new People() { Name = &gg&, Age = 24 });
ps.Add(new People() { Name = &yy&, Age = 23 });
bf.Serialize(fs, ps);
fs.Close();
void Read(){//读byte文件
FileStream fs = new FileStream(&Asset\test.byte&, FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();
List&People& ps = bf.Deserialize(fs) as List&People&;
debug.log(ps[0].name)
///ustcwhc/archive//2232195.html
4.文件读写:string[] allline = File.ReadAllLines(path);File.Datele(path),File.Exist(path),StreamReader r=File.OpenText(path)
4.2在java中FileInputStream用来读文件;FileOutputStream用来写文件。
4.3 DirectoryInfo.GetFiles():获取目录中(不包含子目录)的文件,返回类型为FileInfo[],支持通配符查找;
& & DirectoryInfo.GetDirectories():获取目录(不包含子目录)的子目录,返回类型为DirectoryInfo[],支持通配符查找;
文章来源于易贤网/n3.aspx
5.关于内存优化,进入退出战斗关卡把所有资源释放,保证每次进同一关卡的时候内存值是一样的。
如果内存值波动太大,说明有东西没有释放 需要优化。
关于主页内存优化:主页需要加载大量的UIprefab到场景中,玩家每多进入一个功能,加载了一个prefab 内存都会变大。
&1.建议内存大于512的时候把前边加载不用的prefab释放掉。
&2.建议切换场景的时候释放所有资源内存。把引用obj=Destroy(obj)再调用Resources.UnloadUnusedAssets();
&3 优化最重要的还是分析unity的profile,当运行在某个地方卡的时候,profile都会显示哪些东西耗cpu最高,然后根据对应的函数地方去修改哪些不对的逻辑内容。
6.关于版本更新,以前的思路是服务器资源只留一个最新版本,容易出问题。最好的方法是 每打一个版本apk CDN上就多保留一套资源目录。
然后以后的服务器任何修改都只在该版本资源文件内,不同版本不会相互牵扯和升级。要升级的话 就强制客户端apk升级,才能用服务器新版本的资源。
7. &object lockd = new object(); void common (){ lock(object ){ &}}//锁定内容,防止多线程调用函数里边内容。用在通用模块的通用功能上,防止多处代码同时调用该处代码,有了lock后 会按先后排队执行。
8.关于内存优化写法:
以前:obj.mainTexture=Resources.load(& &) as Texture或实例出来。
以后: Texture tex = obj.mainT
obj.mainTexture = image.
Resources.UnloadAsset(tex);
9.注意脚本中对资源的引用。大部分脚本将在场景转换时随之失效并被回收,但是,在场景之间被保持的脚本不在此列(通常情况是被附 着在DontDestroyOnLoad的GameObject上了)。
而这些脚本很可能含有对其他物体的Component或者资源的引用,这样相关的 资源就都得不到释放,
这绝对是不想要的情况。另外,static的单例(singleton)在场景切换时也不会被摧毁,同样地,如果这种单例含有大量的对资源的引用,也会成为大问题。
因此,尽量减少代码的耦合和对其他脚本的依赖是十分有必要的。如果确实无法避免这种情况,那应当手动地对这些不再使用的引用对象调用Destroy()
或者将其设置为null。这样在Resources.UnloadUnusedAssets()垃圾回收的时候,这些内存将被认为已经无用而被回收。
10 .ref的作用应该是把参数传过去 修改后,代表直接修改的原值。不然传过去的只是临时变量。
11.Stopwatch可以检测程序运行时间,System.Diagnostic.Stopwatch watch=new System.Diagnostic.Stopwatch()
watch.Start()
watch.Stop
long velocity=watch.ElapsedT可以用来计算下载时间.测算哪组cdn服务器时间小,就用哪组。
12.Caching.CleanCache(); 可以删除LoadFromCacheOrDownload不能自动删除磁盘的内容,不然需要等磁盘满了才自动删。
新版本的Caching可以设置包的最大caching大小,超过了就自动释放。这个可以解决他们项目组包大的问题了。
Caching.IsVersionCached(url,int)检测该资源是否存在
13.CSV格式的文件比xml效率好,比单纯的text方便易用。但是要注意编码格式,utf8编码前先写(0xEF).(0xBB).(0xBF)这3个byte到byte数组里边。
14内存优化看我的csdn博客
15StringBuilder:如果我们的程序是在单线程下运行,或者是不必考虑到线程同步问题,我们应该优先使用StringBuilder类;
& StringBuffer如果要保证线程安全,自然非StringBuffer莫属了。
& 单纯的string进行字符串连接的时候效率极低。
内存冗余最多的同一个功能,当刷新的界面时候,生产了很多的临时list,每刷新一次内存增加一次。这样的东西只能一个个慢慢改了。
16关于内存动态变化:总内存=分配内存+临时内存。当一个新的ui加载后,分配内存会增加,临时内存可能减少 总内存不变,也可能临时内存增加 总内存增加很多。
当加载很多UI后,分配内存需要增加,临时内存慢慢被耗完,那么就会去申请一些临时内存,那么总内存就增加了。当场景内切换,所有分配内存被释放到临时内存,但是总内存几乎不会变化。
所以内存越来越大的原因是东西多后,临时内存被撑大,释放的时候又不能释放临时内存,这是系统管的。不能释放是因为内存被碎片化了,比如一块整的100k内存,可能里边的1k还在用,就释放不了,另外碎片化后,新申请的内存如果大于碎片内存,就无法使用,只能申请新的了。
最好的做法是 在主页ui多的地方 加大优化力度,gc和unload。关闭一个ui就优化一次,或者定时优化,或者是当加载过多的prefab后,把之前加载的ui destroy掉。
少产生临时内存的写法:少用string的字符串连接,少用临时变量,在for循环下的临时变量最好都在for外声明一个,然后用完置为null、
分析内存用profiler的 Deep Profile模式,跑一遍看是哪cpu和内存增加得多,然后可以直接看出是哪些代码造成的。
17 Android遇到bug就用logcat调试。控制台输 adb logcat 然后插入手机就可以调试了。IOS遇到bug就用xcode调试或者pp助手实时同步日志。PC平台就用process explorer或者VS的进程工具Ctrl+Alt+P。
-----log:可以查看bluestack
adb kill-server
adb devices
adb logcat&
adb logcat & d:\log2.txt
18 移动平台的播放视频: Handheld.PlayFullScreenMovie(&test.mp4&, Color.black, FullScreenMovieControlMode.CancelOnInput);PC平台可以直接MovieTexture 纹理播放。
& &对于IOS平台一定需要转换为H264编码的格式才能播放,可以用格式工厂转换成该编码的mp4文件。H.264 Baseline Profile Level 3.0 video, up to 640 x 480 at 30 fps. Note that B frames are not supported in the Baseline profile.
19 对于服务器定义的发送数据函数,一般最好都定义为static类型,随时可以调到。如果只是普通类型的话,数据过来也是能调用到该函数,但是函数内部所有的普通变量都是空的,一旦使用就会崩溃。
所以最好的是static,判断当instance!=null的时候处理一些实例。当然普通的这么判断也可以,但是这个写法不好,容易忘记或者弄错,因为普通类型不需要通过实例去访问变量。static才需要。
20关于通讯,底层socket会把数据都转换为byte流进行发送。零世界之前的服务器是有key优化的,key转换为id发送。
21 对于继承类 要调用基类的函数可用:base.Start();用于需要基类先初始化。
22 关于Resources.load和实例化与内存的关系:
1.加载,单纯的Resources.load后消耗的内存很低,可能只是基础的引用预载、当对象被实例化后才会占用大量内存,当实例化多个对象后和实例化一个相差不大,可能后边实例的对象引用了第一个。
2.卸载,单纯的把所有实例的obj给destroy后,内存不会释放,但是再次实例也不会耗内存,若Object b = Resources.Load(&Canvas&);这样写,还需要把b=null后再调用Resources.UnloadUnusedAssets()后整个内存才会被释放。
///最好不要给Resources.Load(&Canvas&);单独定义变量,如果忘记清除变量引用后,内存就释放不了、清除引用是指Resources.Load的引用而不是实例化对象的引用。
所以建议GameObject a = GameObject.Instantiate (Resources.Load(&Canvas&) as GameObject这样直接写,然后destroy 这个实例对象后,调用unload 就可以释放内存。
23 关于assetbundle的加载和实例化与内存的关系:
1.对于WWW.LoadFromCacheOrDownload方式加载,单纯的load进来也不耗什么内存,实例化后会耗很多内存,destroy实例对象后,不释放内存。调用Resources.UnloadUnusedAssets()或www.assetBundle.Unload (true);才能完全释放Unload (false)后似乎没有释放或者可能释放量极小。
结论:建议使用assetbundle.Unload (false),实例对象销毁后需要调用Resources.UnloadUnusedAssets()
2.对于WWW www = new &WWW()方式加载,单纯的load需要消耗一份内存,实例化后再消耗一份内存。实例destroy后需要调用Resources.UnloadUnusedAssets()或www.assetBundle.Unload (true);才能释放实例对象内存,不能释放load的内存。Unload (false)后似乎没有释放或者可能释放量极小。
结论:一般最好不要使用该方法加载,会消耗双倍内存,可以用Resources.UnloadUnusedAssets()回收实例对象内存,本身load的内存无法手动回收。
3.对于AssetBundle.CreateFromFile():应该和1的情况类似。卸载资源只要引用没有了调用unload是有效的。
24 打bundle:
Application.persistentDataPath::C:/Users/guoyuan02/AppData/LocalLow/DefaultCompany/test
Application.dataPath::C:/Users/Public/Documents/Unity Projects/test/Assets
BuildAssetBundleOptions.CollectDependencies会去查找依赖,
pleteAssets会强制包含整个资源,
BuildAssetBundleOptions.DeterministicAssetBundle会确保生成唯一ID,在打包依赖时会有用到,其他选项没什么意义
BuildAssetBundleOptions.DisableWriteTypeTree 禁用写入类型树
BuildAssetBundleOptions.DeterministicAssetBundle 编译资源包使用一个哈希表储存对象ID在资源包中。
25 windows 查看堆栈,用process explorer工具,这个只能看到win层次的堆栈。另外用VS的进程工具Ctrl+Alt+P打开。附到某个进程,然后点暂停就可以看到该时刻的调用堆栈了。
26 splash:作为splash的图片不能用ToNearest来压缩,一定要用原大小。
Center (only scale down) 居中(只是缩小),以正确的像素显示图片,不会缩放图片除非需要。
Scale to fit (letter-boxed)自适应缩放大小(高宽比不变)尝试满屏显示,但不会裁剪,并用黑色填充空白的地方。
Scale to fill (cropped) 自适应填充(裁切不正的)满屏显示,屏幕外的部分将不显示.。
27.关于主城性能的优化:
1.在IOS平台有最大句柄的限制,当句柄达到最高的时候部分资源出错,新的资源加载不进来,解决方法:合并bundle资源,减少句柄。
2.主城玩家的名字Bar优化,主页UI过多,当玩家的bar跟随玩家移动的时候,只要x,y轴有变化会触发NGUI的排序功能,过多的bar和过快的移动会导致性能低下、解决方法:对于玩家的血条bar还是放在3d场景中 用3dText 来显示比较好。放UI层太耗了、
3.当出现了在好机子比在差机子上卡或者发热严重 耗电多的问题,一般都是显卡渲染引起的,好的机子开启了更好的效果所以负载大。所以建议所有机子的quality setting设置成一样。quality setting删后会出现bundle资源的显示不正常 各种uv错乱 黑块、应该修改Debug模式下的Second.
28.IOS自动打包设置用XUPorter工具:/onevcat/XUPorter。。。/archives/2720/
29 在unity里边使用多线程做一些事情是非常好的,比如解压资源 更新资源等。因为单开线程的话 不会影响主线程卡顿,这样UI就不会卡了。但是开的线程里边不能执行unity主线程的mono代码。线程启动后,执行完毕自动结束该线程、可以同时启动多个线程做事。
代码如下: using System.T
void Awake()
& & & & Thread athread = new Thread(new ThreadStart(goThread));
& & & & athread.Start();
& & object lockd = new object();
& & void goThread()
& & & & int index = 0;
& & & & while (true)
& & & & & & lock (lockd)//防止其他线程访问当前线程使用的数据
& & & & & & {
& & & & & & & & Debug.Log(&in thread& + index);
& & & & & & & & index++;
& & & & & & & & if (index == 100)
& & & & & & & & {
& & & & & & & & & & Thread.Sleep(10000);// & 将当前线程挂起指定的时间 毫秒 &时间结束后 继续执行下一步 &和yield类似
& & & & & & & & }
& & & & & & & & else if (index == 200)
& & & & & & & & {
& & & & & & & & & &//该函数执行完自动结束该线程
& & & & & & & & }
& & & & & & }
30 关于事件回调:
EventDelegate.Add(button.onClick, Click);//该委托无参数
EventDelegate.Add(button.onClick,delegate() { Click(&click&); });//该委托无参数,但可把参数存在临时变量里边,相当于回调有参数
EventDelegate.Add(button.onClick,delegate() {Debug.Log(UIButton.current.name); });//直接处理
UIEventListener.Get(imageButton.gameObject).onClick=C void Click(GameObject go){ }//该委托带参数
UIEventListener.Get(imageButton.gameObject).onClick = delegate(GameObject go ) {Debug.Log(go.name);};//直接写里边 不用函数转换
31 unity资源路径标准情况是斜杠/ &Windows资源路径标准是反斜杠\。c#中的反斜杠用转义符\\表示。单纯的反斜杠\被用来做\n换行等字符识别了。
Unity常用目录对应的Android && iOS平台地址
Application.dataPath : Application/xxxxx/xxx.app/Data & & //ipa安装目录
Application.streamingAssetsPath : Application/xxxxx/xxx.app/Data/Raw & //ipa安装目录; &移动设备不可写 只可读,IOS和Windows用File.Read ,安卓用java代码读;安卓内属于压缩文件类型 读取比persistentDataPath慢
//然后路径问题IOS PC用File.Read路径需要全路径,安卓InputStream in = getResources().getAssets().open(fileName); 用这个读 只需要文件名就可以了。
Application.persistentDataPath : Application/xxxxx/Documents & & &//文档目录 &;所有设备可写可读,可直接用File.Read读
Application.temporaryCachePath : Application/xxxxx/Library/Caches & //缓存目录 ;所有设备可写可读
IOS还有tmp目录Application/xxxxx/tmp & &//临时缓存目录
Application.dataPath : /data/app/xxx.xxx.xxx.apk & & //apk内
Application.streamingAssetsPath : jar:file:///data/app/xxx.xxx.xxx.apk/!/assets & //apk内
Application.persistentDataPath : Android/data/data/xxx.xxx.xxx/files & & //文档目录
Application.temporaryCachePath : /data/data/xxx.xxx.xxx/cache & //缓存目录
Application.dataPath : C:/Users/guoyuan02.SNDA/Documents/New Notify/Assets & & //工程内
Application.streamingAssetsPath : C:/Users/guoyuan02.SNDA/Documents/New Notify/Assets/StreamingAssets & //工程内
Application.persistentDataPath : C:/Users/guoyuan02.SNDA/AppData/LocalLow/DefaultCompany/New Notify & &//文档目录
Application.temporaryCachePath : C:/Users/GUOYUA~1.SND/AppData/Local/Temp/DefaultCompany/New Notify & //缓存目录
当然PC下用File.ReadAllText可以读任意目录 &移动也可以有其他方法读。
33 .关于Android里边的各个目录的获取方法:
Environment.getDataDirectory() = /data
Environment.getDownloadCacheDirectory() = /cache
Environment.getExternalStorageDirectory() = /mnt/sdcard
Environment.getExternalStoragePublicDirectory(“test”) = /mnt/sdcard/test
Environment.getRootDirectory() = /system
getPackageCodePath() = /data/app/com.my.app-1.apk
getPackageResourcePath() = /data/app/com.my.app-1.apk
getCacheDir() = /data/data/com.my.app/cache
getDatabasePath(“test”) = /data/data/com.my.app/databases/test
getDir(“test”, Context.MODE_PRIVATE) = /data/data/com.my.app/app_test
getExternalCacheDir() = /mnt/sdcard/Android/data/com.my.app/cache
getExternalFilesDir(“test”) = /mnt/sdcard/Android/data/com.my.app/files/test
getExternalFilesDir(null) = /mnt/sdcard/Android/data/com.my.app/files & //对应Application.persistentDataPath的SD卡目录
getFilesDir() = /data/data/com.my.app/files & &//可能对应Application.persistentDataPath的本地目录
34排序用List的Sort函数挺好用的:List&int& a=new List&int&(); a.Sort(OnSort); int OnSort(int a,int b){if(a&b)return 1;else return -1; }
35.IOS安装后会把安装文件直接解压到目录,所以包大小会变大,加载速度会变快。Android安装后仍然是用压缩的方式存在目录,所以包大小不会变太多,但是加载会慢些。
这还涉及安装的apk和ipa包里边本身是解压的还是压缩的,如果ipa打包前就是压缩的 在IOS/android下边安装后包变得不会很大。但是ipa打包前是没有经过压缩,而是完全靠ipa和apk本身来压缩大小的话,安装后ios包大小就会差很多。
36.移位问题 2&&1 这是2向左移动1位,2&&1这是2向右移动1位。
37.函数参数传object类型:
一个参数 void BuildA(object para){ &List&int& list=para as List&int&;...} &BuildA(list);
多个参数 void BuildB(object para){ &object[] ps= para as object[];List&int& list=ps[0] as as List&int&;GameObject b=ps[1] as GameO...} &BuildB(new object[]{list,obj});//把多个参数塞到object数组里边 传过去,相当于只传一个参数。
38.stream:其中类Stream为抽象类。由此有三个派生类。 需要引入命名空间:using System.IO。一般调用完stream后 都需要调stream.close()来保证资源回收。
MemoryStream:对内存进行读取与写入&
BufferedStream:对缓冲器进行读取/写入&
FileStream:对文件执行读取与写入&
TextReader/Writer为抽象类。由此派生类:&
StreamReader/StreamWirter 分别用于对流的读取与写入。
File和Directory
File类支持对文件的基本操作,包括创建、拷贝、移动、删除和打开一个文件。Directory类则用于执行常见的各种目录操作,如创建、移动、浏览目录及其子目录。
File类和Directory类都是密封类。不象抽象类Stream,File类和Directory类可以被实例化,
Stream.Read(byte[] buffer, int offset, int count) 从当前流读取字节序列,表示从stream里边 buffer: 此方法返回时该缓冲区包含指定的字符数组,该数组的 offset 和 (offset + count -1) 之间的值由从当前源中读取的字节替换。for循环下返回值为0 代表读完了。每次读前要设Stream.position=这样才能定位流里的位置。
Stream.Write(byte[] buffer, int offset, int count)表示写入该byte数组到流。
39.关于C#中 List和数组 GameObject 结构体等类型传递到函数或赋值给新参数的时候 是引用传递,一边修改数据另外一边也会变。int等数据是值传递,函数传递后就与原数据无关。
40.关于句柄限制 对于persistentDataPath目录 IOS有句柄限制最好不超过200,安卓没有,对于streamingAssetsPath目录IOS还是200个限制,但是安卓只能通过www异步加载或者ja另外va层面同步加载,异步加载有端口限制,同步加载有证据表明句柄数也不能太多。另外对于Http下载的文件流 端口也有数量限制 数量不能超6553个。所以除了可以用File.read方法以外的文件流 最好都及时关闭,若不关闭 一定要处理好引用关系 和防止句柄超。
41.yield return null 和Thread.Sleep(100)的区别 协成是等待一帧 再执行下边的内容;Thread.Sleep是当前线程阻塞0.1秒 然后继续执行,主线程使用会导致其他逻辑也阻塞。所以主线程一般不推荐使用。
----------------------------------------------------------------
1.在string中:equals方法对于字符串来说是比较内容的,“==”方法在字符串中比较的是首地址,对于值比较2者完全一样。
2.在c#中不支持中文的时候,要在visual中打开该文件,点文件-高级保存选项,保存为Unicode-;式。
3.访问其他脚本的方法,除了声明为static以外,还可以继承:public class FuLi_dailyClick : Fuli_dailyUI {}这样在这个脚本中的方法和变量就可以直接访问Fuli_dailyUI脚本了。继承一般不用,因为继承自己写的方法后,就不能用unity官方的功能了,update等都无效。
还可以采用在脚本中声明一个静态对象,然后其他脚本通过这个对象访问该脚本的其他方法。如:
public class JiusiUI : MonoBehaviour {//一定要保证这个脚本被active后 s_jiusiUI =才会生效
& & static JiusiUI s_jiusiUI =//那么其他脚本可以采用s_jiusiUI.init()的方法来调用这边的函数
& & void Awake()
& & & & s_jiusiUI =//这个很重要,必须有才能调用,不然不行。
& &public GameObject item1 =
& & void OnDestroy()
& & & & s_jiusiUI =
& & public static void init()
& & {//这里可是是实例化的东西
& & s_jiusiUI.item1.gameObject.SetActiveRecursively(bShow);//这样静态方法和实例化就结合了。
& & }//这儿是指在本脚本中可以将方法定义为静态,其他脚本可以调用该方法。而不是调用对象。
4.只有在主界面改变没有prefab的或者增加prefab的时候需要上传scenegame文件,其他的改变prefab的直接上次prefab就可以了。
5.想要自己的数据每次都更新,就不要把初始化数据放在start里边,而是自己定义一个init函数,没次进去都调用。
6.开始等待时间和终止等待
& & IEnumerator Start() {
& & & & StartCoroutine(&DoSomething&, 2.0F);//开始计时
& & & & yield return new WaitForSeconds(1);
& & & & StopCoroutine(&DoSomething&);//停止计时
& & IEnumerator DoSomething(float someParameter) {
& & & & while (true) {
& & & & & & print(&DoSomething Loop&);
& & & & & &
7 position和localPosition的区别是position是世界坐标,localpositon是基于父物体的坐标。
8 时间的显示格式:lblWaitTime.Text = string.Format(&{0:D2}:{1:D2}:{2:D2}&, waitTime.Hours, waitMinutes, waitSeconds);
9 关于叶签和内容最好的搭配方式参考福利。当需要打开第二页的时候,同时使第二页的叶签打开。但都得放在update后执行一次。尽量不要放在update后边,不然会导致显示闪一下。
10 关于等待时间的问题,最好少用协成yield waitforseconds,用updata下Time.time比较本次time和上次time的差值比较好。
11字体text必须要先等它处于active==true状态后再赋值,才能自动适应宽度。如果先赋值后使它active会导致它只会使用上次text数据的宽度显示出问题。
12所有系统要考虑场景切换后能否使用,所以最好存static数据,系统只是显示,每次回场景都要重新联网取数据不好
13对于字体设置 while 比for有效。for有时候根本不起用。
14.DragMove赋给图片,在加上collider后,就可以实现随意拖拽图片了。ngui中用。
15.关于摄像机设置显示的问题无论是否NGUI中,每个物体都有一个Layer层次,
&在摄像机中有一个Culling mask可以选中需要渲染的层次,那么其他层次在game中就
&不会显示了。
16active和enabled的区别:active是只针对物体的有效,enabled是只针对组件有效。
17.碰撞器和触发器要生效最好2个碰撞的物体都加上刚体。若只有一个是刚体,则用刚体去撞另外一个物体才触发事件,反之不触发。这个月layer无关。
18.Unity里边批量选择,鼠标点击一个,再按住SHIFT点另外一个就会批量选择他们之间所有东西。
19 出错时,在调试台打开open Editor Log,搜索Error的就知道哪错了,这是很重要的一个调试手段。
20 打包注意Resource和StreamingAssets目录,这2个目录都会打包,其他的按引用打包。
21.我们的零世界项目库只支持 xp系统的unity3.5.5版本。
22.动画animation的制作方法,在project中建造Animation文件,然后拖到场景中的物体上,然后用动画组件打开,才能编辑和保存。
23.正确的关卡加载做法是,1,showLoad(true),2用协成来异步加载,3.等级协成加载完自动showLoad(false),而不是在start里边showLoad(false),
24.协成最好是只在本地方法使用,不使用static类型。
25.使用多个camera的时候,只有Layer和Depth这2个参数影响各种渲染的内容效果,与各自的z轴无关。
& &正常camera:depth=2,layer=&UI&//正常相机是先渲染depth小的,也就是depth越大显示越考前。
& &load的camera:depth=3,layer=&UI&//load要遮住其他UI,所以layer必须和maincamera一样,layer相同的组件,前后关系和z轴有关,所以load的camera整体z=-1200。
& &特效的camera:depth=4:layer=&Touch&//特效的只要出效果,与其他无关,可以共同显示,所以layer不一样。
& &layer由culling Mask来控制渲染。
26 关于回调函数 public delegate void ClickEventHandler();
& & public event ClickEventHandler DialogOver = 可以把函数名用init传过来赋值给DialogOver,结束了调用DialogOver()就可以回调了。
27 报System.IO.DirectoryInfo错误,是因为平台web上不行,换成 其他平台也许就好了。
28 做战斗节奏加速 或者减速,用Time.timeScale = 1.0F;
29 abstract & override:
&public setUUid(ID){ ...;setInfo(heroInfo) }//父类
&abstract public void setInfo(RCardInfo heroInfo);//父类 用这个得时候 该父类 也得声明成abstract public abstract class HeroBaseDetail : BaseInfoObj{}
&public override void setInfo(RCardInfo heroInfo){}//子类
这个的用法:多个子类都需要调用基类相同的数据部分setUUid,然后也有各自单独的实现部分setInfo就是单独抽象来的。不然setUUid的相同内容得写多遍。
30 设置帧频:先设置quality setting的(垂直同步)vsync count为dont sync,然后用Application.targetFrameRate = 300;就可以了
31 所有会卡的东西,都放在协成里边来做,等一帧执行下一个内容。
32 关于回调的delegate 和event:如果单是回调: public delegate void ClickEventComplete(); ClickEventHandler loadCompleteOnce=null;就可以了。调过来的方法让他等于loadCompleteOnce就可以了。
但很多时候可能会并行使用像msgBox一样:
用法: public delegate void Click();
& & public event Click yesClick =//event
调用的时候:用btnYes.yesClick += onYesC btnYes.yesClick += onYesClick2的形式才调用。+=和=的区别是:+= 的话会调用所有的方法1和2,等于只会调用最后一次覆盖的方法2。参考:/haiyang1985/archive//1407936.html
建议参考UIButtonClick方法:如果2次刷新的id不一样,第二次要调用ClearClick方法。//2者差不多,event更佳严谨。
33 将对象进行序列化 加:[System.Serializable]具体参考FBDtool 和fbddata和AutoHome
[System.Serializable]//加了这句话 下边的public Data[] data =这个内容 才能在编辑器中显示出来。
public class Data
& & public Vector2 ContentRect = Vector2.
& & public Transform content =
public class AutoHome : MonoBehaviour
& public Data[] data =
34 常用 & #region A & & & #endregion A &将代码包裹开来。这样一个脚本里边 各种的功能分开,方便查看。
35.关于次数限制的问题,最好是初始化设为0 ,然后每用一次加1,当最大次数增加后,可以马上生效。
如果你的初始化设为最大值,一直减到0 ,如果最大次数变了 只能明天才能生效,马上生效就比较麻烦。
36 DestroyImmediate 同一帧内如果要destroy一些东西,然后又要生成该物体或要立即生效,就用这个,不要同一帧销毁的话就用Desroy
-----------------------------------------------------
& &1、 if(Input.GetKeyDown(KeyCode.W))//指按下W,下面的内容会执行一次,用来调用按钮。按一次执行一次。
& & & &if(Input.GetKey(KeyCode.W)) & // 指按住W,下面的内容会一直执行,用于走路等。
& & & &if(Input.GetKey(&1&) ) & &//若是引用数字键要用(&1&)
& & & & & & Input.GetKeyUp //按下起来后有效一次和上面Down一样
& &2、 Vector3(x,y,z)既是:(right,up,forward)
& & & &Vector2(x,y) & 做2d游戏用
& &3、鼠标的光标和滑轮只能监听 &不能判断,只读。
& &4、鼠标键分别是Input.GetMouseButton(0) &左边
& & & & & & & & & Input.GetMouseButton(2) 中间
& & & & & & & & & Input.GetMouseButton(1)右边
& &5、GUIskin可以从 Assets-creat-gui skin创建
& &6 &直接查找KeyCode可以得到所以键盘码
&7 &要想实现一个展示品,相机围绕物体旋转。
& & 则把相机作为那个物体的子物体就可以了,再给物体加上mouselook,
& & 最好做一个空物体放那个需要展示的物体里边。不过我的mouselook还不是很好用 用官方的吧.
&8 &Screen.width,Screen.height既是表示当前运行窗口的宽度与长度,不管是测试和正式运行都是如此。最好在函数中用 不要在定义里用。
&9 、android屏幕的调用,就是相当于windows的鼠标光标的感应,意思就是直接用一个mouselook就可以满足了。
&10 &android横屏:Screen.orientation = ScreenOrientation.LandscapeL放在function Start()函数下。
&11导出fbx模型时 要在max里把位图路径设置一样的。fbx和位图在一个文件夹里导入unity
&12 相机:Projection选项:Perspective:正常的个人视角
& & & & & & & & & & & & & Orthographic:做2D游戏必备的视角,正交视角。
&13 重载本关卡:Application.LoadLevel(Application.loadedLevel);
&14 Rigidbody: Mass质量 &Drag阻力,减慢速度 &Angular Drag角阻力,减慢旋转。2D游戏还可以把Freeze Position 的z选中,Freeze Rotation 的X Y选中,只能饶z旋转,x y面可移动。
&15 function Start () 用来初始化的,重载场景后,只要初始化就好了,不需要赋值了。
&16 在android上设置开始欢迎界面:Player Settings(Splash Image section)中选择为启动画面准备好的素材
&17 要显示2D效果除了用2d tooltit外还可以用讲cube的scale 调为0,为保持碰撞效果可设为0.1很小(大点好)。
&18 设计蹦床的效果:把2个刚体部分重合,然后固定rigidbody position xyz,那么其他物体来碰撞都有自动弹性效果。质量来调节效果。刚体只是一种效果,要碰撞还是得collider。
&19摩擦力:collider.material.dynamicFriction = 0;//静摩擦与动摩擦 0为摩擦小,1为摩擦大。
& & & & & &collider.material.staticFriction = 0;
& &反弹力:collider.material.bounciness = 0;//反弹力 &0为无反弹力 &1为大 &摩擦和反弹力值越大力越大 值越小力越小
&20 在函数里边定义变量的时候不要var,如 function Explosion(explode: Transform){}就可以了。
&21 截屏代码function OnMouseDown(t:Collider) { if(t.gameObject.tag==&&) Application.CaptureScreenshot(&Screenshot.png&);}
&22 做绳的效果 :用很多个固定结点fixed joint,用很多cylinder模型,不能要重力,不然力大了会乱反弹。
&23 判断物体不在当前相机(屏幕)显示下就摧毁之:function OnBecameInvisible () { &Destroy(this.gameObject);}//同样还有function OnBecameVisible () { }//相机可见函数
&24 //定义鼠标有效区域:
& & & & Rect screenRect = new Rect(0,0,Screen.width,Screen.height);
& & & & if( !screenRect.Contains(Input.mousePosition))
&26 关于物体材质颜色和透明度:用这个的前提是把材质设为Transparent。透明度改变很容易卡,所以间隔时间要长点:1s。
transform.renderer.material.color = Color.//完全透明; RGB(0,0,0)为黑 (1,1,1)原色,Color32(255,255,255)白色
transform.renderer.material.color = &Color(1, 1, 1, 1);//分别代表RGBA,A代表alpha通道 从0完全透明--- 1不透明;
在做GUI或者2d时要想透明部分不显示成白色也要将材质设为Transparent就可以显示透明色了,前提在ps里面用透明背景。c#要用new Color()
&27 在android上调用退出: & & if (Input.GetKey(&escape&))
& & & & { Application.Quit(); }
&28 GUI的数组function OnGUI () {
& & & & & & & & &GUI.BeginGroup (new Rect (Screen.width / 2 - 400, Screen.height / 2 - 300, 800, 600));
& & & & & & & & &GUI.Box (new Rect (0,0,800,600),&&);
& & & & & & & & &GUI.EndGroup ();}&
&29 GUIText显示参数: GameObject.Find(&PETGUI&).guiText.text =&收服蚂蚁:&+ PetN//放在Update下,&&为新建的GUI Text的名字,PetNum为参数。
&30 要在别的脚本里调用其他脚本的变量用static var qq = 0; ///用public var qq =0;也可以在别的脚本调用,但不安全。
& & 在别人脚本里调用其他的脚本的函数也是static function qq(){} //调用当然都得用Pet.qq 或者Pet.qq();Pet为脚本名。
&31 为保证效率在用while循环时一定要用yield,效率会提高N多倍。不卡
&32 Application.OpenURL();//打开网页
&33 & Destroy (this);删除脚步Destroy (this.gameObject);删除物体或者Destroy (other);//摧毁的物体放在括号内,不是前面,this也不行。Instantiate&
&34要想判断鼠标在屏幕哪一个区域,就在这个区域放一个GUITexture,然后在GUITexture里边放上function OnMouseEnter()就可以判断了,之前怎么没想到了靠!
-----------------------------------------------------
1、获取对象:a = GamoObject.Find(&cube&);
& & & & & b = GamoObject.Find(&a/cube&);
& & & & & c = GamoObject.FindWithTag(&cube&);
& & & & & d = GamoObject.FindGameObjectsWithTag(&cube&);//获得tag为cube的所有对象
& & & & & d[2].tag = &box&;//d.length获得数组长度;
2、广播:gameObject.BroadcastMessage (&ApplyDamage&, 5.0);向子对象的函数ApplyDamage发送消息5.0
& & & & &gameObject.SendMessage (&ApplyDamage&, 5.0);//给自己发送消息;
& & & & &gameObject.SendMessageUpwards (&ApplyDamage&, 5.0);给父对象发送消息&
& function ApplyDamage (damage : float) {
& & & & print (damage);
& & & & & }
3、四元素:transform.rotation =Quaternion.Slerp (from.rotation, to.rotation, Time.time * speed);
& & & & & & //插值旋转,就是慢慢旋转到to.rotation;//Quaternion.Lerp 比Slerp快而且效果没它好
& & & & & &transform.rotation = Quaternion.Euler(Vector3(0, 30, 0));//立即旋转到这个角度
& & & & & &var t=transform.eulerAngles.y; &&
//返回绕z轴旋转的度数 ,既是读取当前z轴度数
& & & & & var angle : float = Quaternion.Angle(transform.rotation, target.rotation);//返回2物体间的角度
& & & & transform.rotation = Quaternion.AngleAxis(30, Vector3.up);//绕y轴旋转30度
4 Mathf函数里边的角度是π方式表示的,欧拉角要转换过来。
5 获得物体的位置,旋转值,缩放值:
&var quare = room.transform.
&var rotationQ = room.transform.eulerA&
&var ScaleQ = room.transform.localS
&transform.rotation = &Quaternion.//设置旋转角度为(0,0,0)
设置位置和缩放倍数就用=Vector3(2,2,2);就可以了。在c#中是= new Vector3(1f,2f,3f);
设置人物旋转一般用 transform.localEulerAngles = new Vector3(-rotationY, rotationX, 0);//不要用Rotate了
6. Mathf.Clamp (value, min, max);&
限制value的值在min和max之间, 如果value小于min,返回min。 如果value大于max,返回max,否则返回value
7 C#中的等待: StartCoroutine(WAIT()); 这个是接口开始计时,否则直接调用不计时。 & &IEnumerator WAIT() {yield return new WaitForSeconds(5);}
8 驱动官方角色行走的脚本在animation里边,都是修改Input.GetAxis (&Mouse X&);y旋转 Input.GetAxis (&Horizontal&);Vertical移动Input.GetAxis (Fire1&);开火等
9 颜色问题:Color是0-1范围,Color32范围是0-255;c#用transform.renderer.material.color = new color(,,,);
10 在用官方guitext字体的时候,把Pixel correct 选中,再放大Font Size就可以有最好的效果了。设置颜色: GameObject.Find(&PETGUI&).guiText.material.color = Color.
11,UIAtlas item1 =Resources.Load(&head&,typeof(UIAtlas) as UIA如果没有typeof则默认的Resources.Load()只能加载物体(Object)类型的东西。
本文已收录于以下专栏:
相关文章推荐
photon truesync、photon unity networking、photon voice、photon chat 导入到同一个工程中,会出现问题
Photon TrueSync
两个小功能
从服务器下载资源和资源保存到本地~
/// 下载并保存资源到本地
public class Singleton
where T : new()
public static T Instance
当开发人员想将一个类以单例模式实现时,可以在类中定义。
今年是对我个人成长和程序员生涯冲击很大的一年。
有了小孩之后,家里发生了太多太多的事情,现在已经慢慢步入正轨,还好撑过来了,当然还有老婆、岳父岳母、我爸妈、还有好多关心支持我的人的帮助。在各种挫折交替...
时光飞逝,转眼工作将近三年,这三年中,有收获,也有失望。学习到不少东西,不管是技术还是为人。
人生总不能按照自己的想法来实现。刚毕业那年,一心想做嵌入式开发,却走上了测试的道路,本来就不多的技术墨水逐...
他的最新文章
讲师:宋宝华
讲师:何宇健
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)}

我要回帖

更多关于 unity获取子对象 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信