朝着目标点旋转(盯着目标点)Mathf.Atan2
这个意思就是返回弧度角的正切是y/x。
返回值是x轴与起始零点和终点2D向量(x,y)的之间夹角。
注意此函数,x为0的情况,返回正确的角度,而不是抛出被零除的异常。
using UnityEngine;
public class RotateToTarget : MonoBehaviour
{
public Transform trans;
public Transform target;
void Update()
{
RotationToTarget(trans, target);
}
//转向目标点
void RotationToTarget(Transform trans, Transform target)
{
Vector3 dir = trans.position - target.position;
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
trans.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
}
}
字符串转Enum
string value = defaultValue;
KeyCode code = (KeyCode)Enum.Parse(typeof(KeyCode),value);
Awake 和 Start 的执行时机
Awake函数是不管脚本是否启用,只要挂载的游戏物体显示就调用,
Start函数只有在脚本设置为可用并且游戏物体显示的情况下才会调用
当使用Application.OpenURL(m_BunleTargetPath+"/");打开文件时,末尾一定要加路径分隔符才能打开
private static string m_BunleTargetPath = Application.dataPath+"/../AssetBundle/" + EditorUserBuildSettings.activeBuildTarget.ToString();
UnityEngine.Events.UnityEvent
定义unity事件UnityEngine.Events.UnityEvent可以使定义的事件像可序列化的属性一样暴露在检视面板,通过拖拽给这个事件添加响应事件,类型UGUI里面的Button添加点击事件一样,如果扩展UnityEngine.Events.UnityEvent事件,则扩展类需要添加[Serializable]特性才可以让其定义的事件暴露在Inspector面板上,如果扩展的事件为泛型类,则不会显示在在Inspector面板上:
public UnityEngine.Events.UnityEvent TestEvent0;
[Serializable]
public class MyUnityEvent : UnityEngine.Events.UnityEvent { }
public MyUnityEvent myUnityEvent;
[Serializable]
public class MyEventTest1 : UnityEvent<int, int, string> { } //Inspector面板可见
//泛型参数事件,Inspector面板不可见
public class MyEventTest<T0, T1> : UnityEvent<T0, T1> { }
//int+int ;区别于上面情况,这个不能在面板绘制,所以必须new对象,否则对象为空异常。
public MyEventTest<int, int> m_TimeEvent0 = new MyEventTest<int, int>();
订阅事件:TestEvent0.AddListener(() => DoAction("参数来自于脚本添加"));
响应,触发事件:TestEvent0.Invoke();
协程
当禁用MonoBehaviour时,协程不会停止,只有MonoBehavirour被销毁,或主动停止协程时,协同才会停止。使用MonoBehaviour.StopCoroutine和MonoBehaviour.StopAllCoroutines来停止协同。
OnApplicationQuit()
拦截应用程序退出在 应用程序退出响应函数里面:
void OnApplicationQuit()
{ Application.CancelQuit();//退出拦截
MessageCtrl.Instance.OpenConfirmView("关闭界面将终止课程进程,确认关闭?", "", () =>
{
Application.Quit();
});
}
程序根目录路径:Application.dataPath + "/../config.ini"; //Application.dataPath Editor模式是Assets目录路径,打包后是*_Data目录路径
1.如何查看某个层(layer)有哪些物体:
点击右上角的Layers按钮,通过关闭或者打开眼睛可隐藏或显示设置为某个Layer的所有物体
脚本特性:
void OnValidate()//在Inspector中修改参数值,就会自动调用这个方法
[ExecuteInEditMode]//添加这个以后,Start方法会在添加脚本和点击run或stop的时候执行一遍
[AddComponentMenu("MyTool/MaterialOrder")] //脚本可以在添加脚本面板添加
#if UNITY_EDITOR
using UnityEditor;//自动调用OnValidate()方法
#endif
using UnityEngine;
[ExecuteInEditMode]//添加这个以后,Start方法会在添加脚本和点击run或stop的时候执行一遍
[AddComponentMenu("MyTool/MaterialOrder")]
public class MaterialOrder : MonoBehaviour {
[Range(3000,3300)]
public int renderLayer = 3000;
void Start()
{
ChangeQueue(renderLayer);
}
#if UNITY_EDITOR
void OnValidate()//在Inspector中修改参数值,就会自动调用这个方法
{
ChangeQueue(renderLayer);
}
#endif
void ChangeQueue(int layer)
{
if (layer >= 3300) layer = 3300;
gameObject.GetComponent<Renderer>().sharedMaterial.renderQueue = layer;
}
}
LayerMask
LayerMask实际上是一个位码操作,在Unity3D中一共有32个Layer层,并且不可增加。
位运算符
按位运算符:~、|、&、^
。位运算符主要用来对二进制位进行操作。
逻辑运算符:&&、||、!。
逻辑运算符把语句连接成更复杂的复杂语句。
按位运算符:左移运算符<<
,左移表示乘以2,左移多少位表示乘以2的几次幂。
LayerMask mask = 1 << 2; 表示开启Layer2。
LayerMask mask = 0 << 5;表示关闭Layer5。
LayerMask mask = 1<<2|1<<8;表示开启Layer2和Layer8。
LayerMask mask = 0<<3|0<<7;表示关闭Layer3和Layer7。
上面也可以写成:
LayerMask mask = ~(1<<3|1<<7);表示关闭Layer3和Layer7。
LayerMask mask = 1<<2|0<<4;表示开启Layer2并且同时关闭Layer4.
public class example : MonoBehaviour {
LayerMask mask = ~(1<<3|1<<7);
void Update() {
if (Physics.Raycast(transform.position, transform.forward, 100, mask.value))
Debug.Log("Hit something");
}
}
2.运行模式下可动态设置 physicsManager 下的Layer Collision Matrix : 在这里可以设置物体 分层碰撞
3.关闭日志输出:Debug.logger.logEnabled=false; 为输出日志添加回调函数:Application.logMessageReceived+=LogMessageReceivedFunc;使用 ILoggerHandle的子类讲Debug.Log的默认输出替换成可控的函数。
4.快捷高效替换UI,在编辑器外面替换掉原有UI,名字保持不变,不要删除 .meta文件,可实现替换掉所有引用到此图片的UI贴图
5. [SerializeField]表示将原本不会被序列化的私有变量和保护变量变成可以被序列化的,那么它们在下次读取的值就是你上次赋值的值。[HideInInspector]表示将原本显示在面板上的序列化值隐藏起来。凡是显示在Inspector 中的属性都同时具有Serialize功能(序列化的意思是说再次读取Unity时序列化的变量是有值的,不需要你再次去赋值,因为它已经被保存下来)。
Serializable是.Net自带的序列化
有时候我们会自定义一些单独的class/struct, 由于这些类并没有从 MonoBehavior 派生所以默认并不被Unity3D识别为可以Serialize的结构。自然也就不会在Inspector中显示。我们可以通过添加 [System.Serializable]这个Attribute使Unity3D检测并注册这些类为可Serialize的类型。具体做法如下:
[System.Serializable]
public class FooBar {
public int foo = 5;
public int bar = 10;
}
注意:Serializable只可以对class,struct,enum,delegate进行序列化,不可以对属性序列化
TransformPoint和InverseTransformPoint解析
一个是变换自身坐标到世界坐标 一个是变换世界坐标到自身坐标
比如说物体a的坐标内有一个3,3,3的点 你想知道这个点在世界坐标的位置 就应该用TransformPoint
反之在世界坐标下有一个点 你想知道这个点如果是在物体a的坐标下是一个什么位置 就应该用InverseTransformPoint
其实吧 就是在编辑器里把物体拽到根目录下的位置和物体在某物体内的位置之间的一个转换
冷门:
把某个shader总是添加到预定义shaders数组里面: 在 Edit-->Project Settings-->Graphics-->Always Included Shaders 的数组里面添加,这样做的好处是不需要把这个shader加载动态加载进来就可以使用这个shader,加载assetbundle时能感受到这样设置带来的好处
编辑器模式下运行:
在monobehavior脚本文件头添加[ExecuteInEditMode]标签就可以在编辑器模式下运行代码