当前位置: 编程技术>移动开发
本页文章导读:
▪unity动画片指定器 unity动画指定器
using UnityEngine;
using UnityEditor;
using System.Collections;
/// <summary>
/// 模型动画 分配器
/// </summary>
public class AnimationAssigner : EditorWindow
{
static readonly string STR_MYNAME = "模型.........
▪ 日常知识点记要 日常知识点记录
如果我们需要把硬盘中的数据读入到内存中,CPU首先需要把数据从硬盘中读入到寄存器中,然后再写入到内存中。如果我们需要把内存中的数据写入到硬盘中的时候,CPU首.........
▪ unity模型卡通分离器 unity模型动画分离器
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.IO;
/**
根据时间表分离骨骼动画.
时间表名字与模型一致.但后缀是txt.
模型须以@开.........
[1]unity动画片指定器
来源: 互联网 发布时间: 2014-02-18
unity动画指定器
using UnityEngine; using UnityEditor; using System.Collections; /// <summary> /// 模型动画 分配器 /// </summary> public class AnimationAssigner : EditorWindow { static readonly string STR_MYNAME = "模型动画2Prefab"; static readonly string STR_TARGET = "Project中的模型"; static readonly string STR_PREFAB = "场景中的prefab"; static readonly string STR_OK = "开始"; static readonly string STR_INTRODUCE = "将Project中模型的动画,直接复制到场景的某Prefab中."; //分离好动画的模型,Project内 GameObject model; //需要指定动画的 prefab.Hierarchy内 GameObject prefab; [MenuItem("Level4/AnimationTool/ModelAnimationAssign")] static void Init() { EditorWindow.GetWindow<AnimationAssigner>(false,STR_MYNAME); } void OnGUI() { GUILayout.Box(STR_INTRODUCE); model = EditorGUILayout.ObjectField(STR_TARGET, model, typeof(GameObject), true) as GameObject; prefab = EditorGUILayout.ObjectField(STR_PREFAB, prefab, typeof(GameObject), true) as GameObject; if (GUILayout.Button(STR_OK)) { if (model != null && prefab != null) { if (prefab.animation == null) prefab.AddComponent<Animation>(); AnimationUtility.SetAnimationClips(prefab.animation, AnimationUtility.GetAnimationClips(model.animation)); ShowNotification(new GUIContent("完成指定:" + prefab.animation.GetClipCount())); } } } void OnSelectionChange() { } }
[2] 日常知识点记要
来源: 互联网 发布时间: 2014-02-18
日常知识点记录
如果我们需要把硬盘中的数据读入到内存中,CPU首先需要把数据从硬盘中读入到寄存器中,然后再写入到内存中。
如果我们需要把内存中的数据写入到硬盘中的时候,CPU首先需要先把数据从内存中读入道寄存器中,然后再写入到硬盘中。
这就有了一个问题。CPU在放下手头工作之前,必须先把手边的一摊子工作找个地方暂存起来,以便一会儿回来接着干。那么,手头这摊子工作存在哪儿呢?当然是存在内存里。
我们可以看到,运行栈这种“先进后出,后进先出”的特点,恰好就是“栈”这个数据结构的特点,因而得名“运行栈”。
操作系统进程有可能在硬盘上开辟一块空间,作为虚拟内存的备用空间,当内存卡的物理内存容量不够时,就把内存中一些暂时不用的内容暂存道硬盘上,然后把需要的内容导入腾出的内存空间。这种技术叫做虚拟内存置换。
我们常听到,32位操作系统或64位操作系统之类的说法。这里的32位或者64位的说法,指的就是CPU的工作台(寄存器)的位数。
64位操作系统的内存单元32位操作系统大了一倍,那么,原子操作能够容纳的数据尺寸也大了一倍。这意味着,在取用某些“长”数据类型的时候,CPU按照64位操作系统的规则,只需要取一次,就可以把数据取到寄存器中。而CPU按照32位操作系统的规则,却分两次把数据取到寄存器中。因此,从处理长数据类型的速度上来说,64位操作系统是优于32位操作系统的。
我们前面提到的32位操作系统和64位操作系统,其中的“位”的意思就是一个二进制数字。32位就表示一个位数为32的二进制数字,表达的最大数量是2的32次方。64位就表示一个位数为64的二进制数字,表达的最大数量是2的64次方。“位”这个词,对应的英文单词是“bit”。这个词经常被音译为“比特”。比如,数字信号的传输速率就经常被译成“比特率”。
现在,我们这里澄清一下“Bit”(位)和“Byte”(字节)之间的区别。
Bit就是一位二进制数字,要么是0,要么是1,只能表达两个状态。
Byte(字节)则是一个位数为8的二进制数字,能够表达的状态数量达到2的8次方,即256个状态。Byte和Bit之间足足差了2的7次方的倍数,即128倍。
分配在运行栈(stack)上的数据,其生命周期由过程调用来决定。分配在内存堆(heap)的数据,其生命周期超出了过程调用的范围。内存堆中的数据,需要程序员写代码显式释放,或者由系统自动回收。
两者之间的区别在于,进程拥有一份独立的进程空间,而线程没有。线程只能依附于进程存在。一个进程下面的多个线程,只能共享同一份进程空间。因此,线程和进程的主要区别,就在于共享资源方面。除此之外,两者的运行、调度,几乎都是一样的。
volatile关键字可以加在任何类型的变量前面,可以加在Object Reference类型(即对象)的前面,也可以加在简单类型(比如char、int、float、long、double等)的前面。当变量是Object Reference类型(对象)的时候,在前面加volatile是没有意义的。因为对象的赋值只是一种Object Reference(内存地址)的赋值,并不引起对象内部结构数据的任何变化。而且,Object Reference的赋值,通常都是不需要同步的原子操作。
一般来讲,volatile关键字只对long、double等长类型才有意义。因为,短类型的操作基本上都是原子操作。而原子操作是一次操作就完成的,不需要分多次操作,因此也不需要进行同步处理。
我们只需要学习和思考“同步锁加在代码段上”的线程同步模型。
synchronized(同步锁) {
// 访问共享资源、需要同步的代码段
}
其中“同步锁”是什么呢?就是一个Object Reference。任何一个Java对象,或者说,任何一个Object Reference,都可以对应一个同步锁。换句话说,任何一个Java对象实例,都可以被synchronized关键字包裹起来,承担起同步锁的任务。
你不一定要把同步锁声明为static或者public,但是你一定要保证相关的同步代码之间,一定要使用同一个同步锁。
锁的粒度越小越好,不要直接放在方法前面偷懒!
如果我们需要把硬盘中的数据读入到内存中,CPU首先需要把数据从硬盘中读入到寄存器中,然后再写入到内存中。
如果我们需要把内存中的数据写入到硬盘中的时候,CPU首先需要先把数据从内存中读入道寄存器中,然后再写入到硬盘中。
这就有了一个问题。CPU在放下手头工作之前,必须先把手边的一摊子工作找个地方暂存起来,以便一会儿回来接着干。那么,手头这摊子工作存在哪儿呢?当然是存在内存里。
我们可以看到,运行栈这种“先进后出,后进先出”的特点,恰好就是“栈”这个数据结构的特点,因而得名“运行栈”。
操作系统进程有可能在硬盘上开辟一块空间,作为虚拟内存的备用空间,当内存卡的物理内存容量不够时,就把内存中一些暂时不用的内容暂存道硬盘上,然后把需要的内容导入腾出的内存空间。这种技术叫做虚拟内存置换。
我们常听到,32位操作系统或64位操作系统之类的说法。这里的32位或者64位的说法,指的就是CPU的工作台(寄存器)的位数。
64位操作系统的内存单元32位操作系统大了一倍,那么,原子操作能够容纳的数据尺寸也大了一倍。这意味着,在取用某些“长”数据类型的时候,CPU按照64位操作系统的规则,只需要取一次,就可以把数据取到寄存器中。而CPU按照32位操作系统的规则,却分两次把数据取到寄存器中。因此,从处理长数据类型的速度上来说,64位操作系统是优于32位操作系统的。
我们前面提到的32位操作系统和64位操作系统,其中的“位”的意思就是一个二进制数字。32位就表示一个位数为32的二进制数字,表达的最大数量是2的32次方。64位就表示一个位数为64的二进制数字,表达的最大数量是2的64次方。“位”这个词,对应的英文单词是“bit”。这个词经常被音译为“比特”。比如,数字信号的传输速率就经常被译成“比特率”。
现在,我们这里澄清一下“Bit”(位)和“Byte”(字节)之间的区别。
Bit就是一位二进制数字,要么是0,要么是1,只能表达两个状态。
Byte(字节)则是一个位数为8的二进制数字,能够表达的状态数量达到2的8次方,即256个状态。Byte和Bit之间足足差了2的7次方的倍数,即128倍。
分配在运行栈(stack)上的数据,其生命周期由过程调用来决定。分配在内存堆(heap)的数据,其生命周期超出了过程调用的范围。内存堆中的数据,需要程序员写代码显式释放,或者由系统自动回收。
两者之间的区别在于,进程拥有一份独立的进程空间,而线程没有。线程只能依附于进程存在。一个进程下面的多个线程,只能共享同一份进程空间。因此,线程和进程的主要区别,就在于共享资源方面。除此之外,两者的运行、调度,几乎都是一样的。
volatile关键字可以加在任何类型的变量前面,可以加在Object Reference类型(即对象)的前面,也可以加在简单类型(比如char、int、float、long、double等)的前面。当变量是Object Reference类型(对象)的时候,在前面加volatile是没有意义的。因为对象的赋值只是一种Object Reference(内存地址)的赋值,并不引起对象内部结构数据的任何变化。而且,Object Reference的赋值,通常都是不需要同步的原子操作。
一般来讲,volatile关键字只对long、double等长类型才有意义。因为,短类型的操作基本上都是原子操作。而原子操作是一次操作就完成的,不需要分多次操作,因此也不需要进行同步处理。
我们只需要学习和思考“同步锁加在代码段上”的线程同步模型。
synchronized(同步锁) {
// 访问共享资源、需要同步的代码段
}
其中“同步锁”是什么呢?就是一个Object Reference。任何一个Java对象,或者说,任何一个Object Reference,都可以对应一个同步锁。换句话说,任何一个Java对象实例,都可以被synchronized关键字包裹起来,承担起同步锁的任务。
你不一定要把同步锁声明为static或者public,但是你一定要保证相关的同步代码之间,一定要使用同一个同步锁。
锁的粒度越小越好,不要直接放在方法前面偷懒!
[3] unity模型卡通分离器
来源: 互联网 发布时间: 2014-02-18
unity模型动画分离器
using UnityEngine; using UnityEditor; using System.Collections; using System.Collections.Generic; using System.IO; /** 根据时间表分离骨骼动画. 时间表名字与模型一致.但后缀是txt. 模型须以@开头.如 @Model.fbx,时间表如:@Model.txt. 时间表内容,以 //开头的行不处理. 以 空格 分隔. 动画名 开始帧 结束帧 */ public class SplitAnimsProcessor : AssetPostprocessor { static readonly string STR_TIME_FILE_NOT_EXIST = "时间文件不存在."; static readonly string STR_SUCC_SPLIT_ANIMATION = "成功分离动画:"; //时间文件的后缀. public const string EXTENSION_NAME = ".txt"; //每行的分割符号 public const char SPLIT_SYMBOL = ' '; public void OnPreprocessModel() { if (assetPath.Contains("@")) { //读取 动画时间文件,并分离动画 SplitAnims(ReadTimeConfig()); } } /// <summary> /// 读取 时间配置文件. /// </summary> /// <returns></returns> private List<string> ReadTimeConfig() { string dirPath = Directory.GetParent(assetPath).ToString(); string fileName = Path.GetFileNameWithoutExtension(assetPath); string path = dirPath + "/" + fileName + EXTENSION_NAME; List<string> lines = new List<string>(); if (File.Exists(path)) { FileStream fs = new FileStream(path, FileMode.Open); StreamReader sr = new StreamReader(fs); while (!sr.EndOfStream) { string line = sr.ReadLine(); if (!string.IsNullOrEmpty(line) && !line.StartsWith("//")) lines.Add(line); } sr.Close(); fs.Close(); return lines; } return null; } /// <summary> /// 分离动画 /// </summary> /// <param name="lines"></param> private void SplitAnims(List<string> lines) { string result = STR_TIME_FILE_NOT_EXIST; if (lines != null) { ModelImporter importer = (ModelImporter)assetImporter; List<ModelImporterClipAnimation> clips = new List<ModelImporterClipAnimation>(); foreach (string line in lines) { string[] timeLine = line.Split(SPLIT_SYMBOL); string name = timeLine[0]; int start = int.Parse(timeLine[1]); int end = int.Parse(timeLine[2]); //---------- clips.Add(GenAnim(name, start, end)); } importer.clipAnimations = clips.ToArray(); result = STR_SUCC_SPLIT_ANIMATION + clips.Count; } Debug.Log(result); } /// <summary> /// 创建 动画剪辑. /// </summary> /// <param name="name"></param> /// <param name="startFrame"></param> /// <param name="endFrame"></param> /// <returns></returns> private ModelImporterClipAnimation GenAnim(string name, int startFrame, int endFrame) { ModelImporterClipAnimation clip = new ModelImporterClipAnimation(); clip.firstFrame = startFrame; clip.lastFrame = endFrame; clip.name = name; return clip; } }
最新技术文章: