当前位置: 编程技术>移动开发
本页文章导读:
▪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;
}
}
最新技术文章: