特性
字段上添加的 可以显示在监视面板
比如有
Header
Range
HideInInspector
Json解析里 JsonUtility里的System.Serializable 这个查询需要在MSDN里查询
查询办法
unityAPI 打开 脚本API 打开 UnityEngine 打开 Attributes 里面都是
特性需要通过反射手段 获取
三个预定义特性 .Net 写的
AttributeUsage 自定义特性
Conditional 条件
Obsolete 过时
AddComponentMenu 在Component菜单里可以找到 括号里传入的是路径 比如:("wo/wodejiaoben")
RequireComponent 绑定添加某些东西 比如:(typeof(Rigidbody))
SerializeField 私有字段显示在监视器面板上
Obsolete
using UnityEngine;
public class DemoFrame {
//[Obsolete]//Obsolete有三个重载
//[Obsolete("这个方法过时了,使用NewDemoShowMe代替")]
[Obsolete("这个方法过时了,使用NewDemoShowMe代替"),true]//默认是false
public static void OldDemoShowMe(){
Debug.Log("OldDemoShowMe");
}
public static void NewDemoShowMe(){
Debug.Log("NewDemoShowMe");
}
}
public class UseObsoleteDemo : MonoBehaviour {
private void Start(){
DemoFrame.OldDemoShowMe();
}
}
Conditional
#define ABC
using UnityEngine;
using System.Diagnostics;
public class ConditionalDemo {
[Conditional("ABC")]
public static void ShowMe(){
Debug.Log("ShowMe");
}
}
public class UseConditionalDemo : MonoBehaviour {
private void Start(){
ConditionalDemo.ShowMe();
}
}
AttributeUsage
using UnityEngine;
using System;
//[AttributeUsage(AttributeTargets.Class)]
[AttributeUsage(AttributeTargets.Class,AllowMultiple = true)]//是否可以多次使用 默认false 不可以
//还有一个参数是设置是否可以被继承 一般不用
public class AuthorAttribute : Attribute {
public string author;
//最后修改日期
private string lastDate;
public string LastDate{
get{
return lastDate;
}
set{
lastDate = value;
}
}
//当前特性的构造函数
public AuthorAttribute(string author){
this.author = author;
}
}
[AttributeUsage(AttributeTargets.Method,AllowMultiple = true)]
public class MyConditionAttribute : Attribute {
public MyConditionAttribute(){
}
}
//写一个新脚本 看看UsersAttributes里的这两个特性
[Author("这里就可以写名字了",LastDate = "1111.11.11"),Author("再来个名字"),LastDate = "1111.11.12"]
public class UsersAttributes : MonoBehaviour {
//[Author("123")] <----这里就会报错 因为上面参数里只能放在类上
public static string log = "abc";
[MyCondition] // 这里的特性如果没写下面会报错
public static void ShowLog(){
Debug.Log(log);
}
}
using UnityEngine;
public class UsesAttributeObserver : MonoBehaviour {
private void Start(){
InvokeMethodByAttribute(typeof(UsersAttributes),"ShowLog",true,true,null);
}
//如果有特性就执行 没有特性不执行
//执行某个方法依据某个特性
private void InvokeMethodByAttribute(Type methodClassType,//方法所在的类的类型
string methodName,//方法名
bool isStatic,//是否是静态
bool isPublic,//是否是公有
object methodObj = null)//成员方法所在对象
{
BindingFlags staticFlags = isStatic ? BindingFlags.Static : BindingFlags.Instance;
BindingFlags publicFlags = isPublic ? BindingFlags.Public : BindingFlags.NonPublic;
//获取到该方法
MethodInfo info = methodClassType.GetMethod(methodName, staticFlags | publicFlags);
//获取MyCondition类型的特性
object[] atts = info.GetCustomAttributes(typeof(MyConditionAttribute),false);
if(atts.Length > 0){
info.Invoke(null,null);
}
else{
Debug.LogError("没有添加MyCondition特性,该方法不能执行!");
}
}
private void PrintAttributeMsg(){
//获取类型
Type type = typeof(UsersAttributes);
//获取信息 得到该类型不可继承的特性
// 获取自定义的特性
object[] atts = type.GetCustomAttributes(false);
for(int i = 0; i < atts.Length; i++){
//判断当前特性是不是某个特性类型
if(atts[i] is AuthorAttribute){
//将特性转换为该类型
AuthorAttribute authorObj = atts[i] as AuthorAttribute;
Debug.Log(authorObj.author);
}
}
}
}
异常处理
应用于产品层次
处理运行代码时出现的错误,比如用户在使用时密码输错了,给他一种很直观的提示
using UnityEngine;
public class TryCatchDemo : MonoBehaviour {
private GameObject prefab; // <-----这样写肯定会报错 空引用 因为没有实例化
private void Start(){
//两种方式
//第一种
/*if(prefab != null){
prefab.name = "asdf";
}*/
//第二种 先尝试执行try 里面的内容 有问题了 catch接住
try{
prefab.name = "asd";
}
catch(NullReferenceException e){
Debug.Log(e.Message);
Debug.Log("预设体不存在,设置预设体");
}
finally{ // <---这个一般不写
}
}
}
一个try 可以接多个catch
catch与catch之间有继承关系
子类的异常放前面