plugin
plugin中的脚本最先编译
Movement = Camera.main.transform.rotation *Vector3.forward;
右侧等价于Camera.main.transform.forward
使用此函数可以使物体顺着摄像机正视的方向行走。
原理:
static Vector3operator *(Quaternion rotation, Vector3 point);
Description
Rotates the pointpoint with rotation.
Destroy
删除时会有延迟,下一帧的时候才会真正删除物体,想立即删除可以用DestroyImmediate
MeshTopology
MeshTopology.line是将数组中的点两两一组,进行画线。如(0,1,2,3),则0,1画一条线,2,3画一条线。若是LineStrip,则是0,1一条,1,2一条,2,3一条,共三条线。
Mesh.GetTriangles
返回的是三角形的顶点数组,包含重复顶点,重复顶点只存在于submesh内部,不会存在于submesh之间,长度是三角形数量的三倍。
Mesh.triangles
返回的是一个int数组,长度为模型三角形数量的3倍,也就是说每一个三角形的节点都能找到对应的数组元素,意味着包含了重复的节点。同一个节点在不同的三角形中可能是共用的,但在int数组中可能占据两个或者以上的位置。
RaycastHit.triangleIndex
这个东西返回的才是真正的三角形序号,总数和模型preview下方显示的tris总数相等。
SSOAEffect和Vignetting
这两个原声脚本在android不被支持,会导致黑屏
IEnumerator
Unity3d中,IEnumerator类型的函数,使用StartCoroutine开始运行,但是StartCoroutine之后的代码,也会开始运行,而不管IEnumerator是否运行结束,所以,需要使用yieldreturn StartCoroutine(),来控制线程。
unity固定间隔运行程序,几种方案:
1.可改为每5帧处理一次:
function Update()
{ if(Time.frameCount % 5 == 0) { DoSomeThing(); } }
2. 定时重复处理用 InvokeRepeating 函数实现
比如,启动0.5秒后每隔1秒执行一次 DoSomeThing 函数:
function Start() {InvokeRepeating("DoSomeThing", 0.5, 1.0); }
3.yield return waitforseconds
unity3d脚本中#pragma的作用
#pragma strict
#pragma implicit
#pragma downcast
这些都是什么作用?
经常用到的第一个#pragmastrict
严谨编译模式
性能优化:JS中强制使用静态类型,脚本顶部添加#pragmastrict。然后,unity将在脚本中禁用动态类型,强制使用静态类型,如果一个类型未知。Unity将报告编译错误。那么在这种情况下foo将在编译时产生一个错误:
#pragma strict
function Start()
{
var foo =GetComponent(MyScript);
foo.DoSomething();
}
正确写法:
#pragma strict
function Start()
{
var foo :MyScript = GetComponent(MyScript);
foo.DoSomething();
}
这里我们强制foo为指定类型,将获得更好的性能。
Unity3D:Coroutines & Yield
Coroutines& Yield是Unity3D编程中重要的概念,它可以实现将一段程序延迟执行或者将其各个部分分布在一个时间段内连续执行,但是在Javascript与C#中实现Coroutines& Yield,在语法上却有一些区别:
yield不可单独使用
需要与return配合使用,例如:
1 yield return 0; //等0帧
2 yield return 1; //等1帧
3 yield return WaitForSeconds(3.0); //等待3秒
所有使用yield的函数必须将返回值类型设置为IEnumerator类型,例如:
IEnumerator DoSomeThingInDelay() {...}
最后,也是在”UsingC#”这个章节中没有讲到的关键一点是,所有IEnumerator类型函数必须使用”StartCoroutine”这个函数触发,不能单独使用,例如:
StartCoroutine(DoSomeThingInDelay());
最后附上学习Coroutines&Yield时所做的小例子,脚本的作用是不断随机改变材质的颜色,演示demo使用”V字仇杀队”中的面具。
using UnityEngine;
using System.Collections;
public class RandomColor : MonoBehaviour {
public float delayInSecond = 1;
public Material targetMaterial;
// Use this for initialization
void Start () {
StartCoroutine(AutoChangeColor());
}
// Update is called once per frame
void Update () {
}
IEnumerator AutoChangeColor()
{
yield return 0; //确保Time.deltaTime为0
Color colorNew = GenerateRandomColor();
Color colorNow=targetMaterial.GetColor("_Color");
float timeEclapsed = 0;
for (timeEclapsed = 0; timeEclapsed<delayInSecond; timeEclapsed += Time.deltaTime)
{
float progress = timeEclapsed / delayInSecond;
Color colorTween = new Color(
(colorNew.r - colorNow.r) * progress + colorNow.r,
(colorNew.g - colorNow.g) * progress + colorNow.g,
(colorNew.b - colorNow.b) * progress +colorNow.b
);
targetMaterial.SetColor("_Color",colorTween);
yield return 1;
}
StartCoroutine(AutoChangeColor());
}
Color GenerateRandomColor(){
Color color = new Color();
color.r = Random.value;
color.g = Random.value;
color.b = Random.value;
return color;
}
}
Transform
改变父物体的rotation。子物体的rotation是会不规则变化的。所以,不要以为转父物体多少就是转子物体多少。
transform.position是继承了monobehavior的,而对一个transform类型的物体P,可以直接用P.position,跟P. transform.position很多情况下是一样的。
通过transform能获取整个Gameobjects,这个很关键哦。unity,camera的z值,摄像机后面的都是负值,但摄像机后面的点通过WorldToViewportPoint后,也有可能落在视口内(0,0)(1,1)之间,只是在摄像机背面,看不到。
Unity3d中的position是pivot模式下的位置,有的时候pivot模式和center模式下的position是不一样的。需要严格注意。
降低类库大小
Unity3D:Js 与 C#相互通信
由于Unity3D中一些脚本的方法只能用在JS中,在C#中是无效的,而C#可以与服务器端通讯,JS本身却不行。所以势必会遇到这两种语言脚本中方法的互相调用,以下是示例。
两个文件test1.js 和 test2.cs
test1.js:
functionOnGUI()
{
if(GUI.Button(Rect(25,25,100,30),"JSCallCS" ))
{
var c = gameObject.GetComponent("test2");
c.PrintTest();
}
}
function testPrint()
{
print("CS Call JS");
}
test2.cs:
usingUnityEngine;
usingSystem.Collections;
public class test2: MonoBehaviour {
void OnGUI()
{
if(GUI.Button(new Rect(25,70,100,30), "CSCallJS"))
{
test1 c=(test1)gameObject.GetComponent("test1");
c.testPrint();
}
}
void PrintTest()
{
print("JS Call CS");
}
}
这里必须要注意的是JS文件必须是在 "Standard Assets"、 "Pro Standard Assets" 和"Plugins" 这三个目录中的任何一个里,而CS文件不能与JS文件在一个目录中。原因是,这三个目录里的脚本被最先编译,"Editor"目录里的稍后编译,其他的脚本最后编译。目前Unity3D的2.5的版本似乎不支持C#3.0,所以无法用var的关键词,这样就只支持强类型,所以如果在一个目录下则CS文件无法读取JS里的方法,也就无法编译通过了。而JS调用CS方法则无此限制。
eulerAngles
rotation赋值的时候,要注意等号两边的角度表达方式,有时角度和弧度对应不起来就会出现晕。