https://docs.unity3d.com/Manual/index.html
https://blog.csdn.net/weixin_57504000/article/details/124868632
http://www.360doc.com/content/21/1201/13/77937936_1006683453.shtml
https://blog.csdn.net/u012433546/article/details/126387188
https://www.pianshen.com/article/40421717306/
Ctrl+Shift+M 启动 MonoBehavior 向导。
Ctrl+H访问 Unity 文档
https://blog.csdn.net/Q540670228/article/details/126120975
https://blog.51cto.com/itMonon/5251258
https://blog.csdn.net/m1234567q/article/details/127119940
https://blog.csdn.net/m1234567q/article/details/127119940
https://blog.csdn.net/o_ojjj/article/details/111357710
http://www.kaotop.com/it/900587.html
https://blog.csdn.net/o_ojjj/article/details/111357710
https://www.cnblogs.com/vuciao/p/10363607.html
Create() 创建文件夹
CreateSubdirectory() 创建子文件夹
GetDirectories() 获取所有子文件夹信息 返回DirectoryInfo数组类型 可以对子文件夹做其他操作
GetFiles()获取文件下所有子文件信息 返回FileInfo数组类型 可以对子文件进行其它操作 比如读和写
Root 获取根目录信息 返回DirectoryInfo类型
Parent 获取父目录的信息 返回DirectoryInfo类型
https://blog.csdn.net/alayeshi/article/details/124952143
https://blog.51cto.com/itMonon/5251258
https://blog.csdn.net/qq_39342142/article/details/103781728
https://blog.csdn.net/qq_39342142/article/details/103781728
https://blog.csdn.net/weixin_45023328/article/details/120035597
https://zhuanlan.zhihu.com/p/51932515
关于Editor脚本,
using UnityEditor;
要创建的编辑器窗口类应该继承EditorWindow;
public class OneEditorWindow : EditorWindow
{
//MenuItem是一个特性,会在顶部按路径生成选项,点击就会调用下面的方法,也就是打开窗口
[MenuItem(“Unity编辑器/OneEditorWindow”)]
public static void OpenWindow(){}
private void OnGUI()
{
EditorGUILayout.LabelField(“一个label”);
f = EditorGUILayout.FloatField(“一个数字框”, f);
col=EditorGUILayout.ColorField(“一个颜色选择框”,col);
}
}
https/www.jianshu.com/p/27280468288c**
https://blog.csdn.net/qq_51947882/article/details/128224087
http://www.360doc.com/content/21/1201/13/77937936_1006683453.shtml
https://www.cnblogs.com/sakuraneko/p/16078118.html
[CustomEditor(typeof(xxx), true)]
[CustomEditor(typeof(MonoTest), true)]
特性来描述要自定义的是哪个类, 第二个参数代表是否对其子类起效.
将类继承父类public class MonoTestEditor : Editor
.
CustomEditor类有两个关键的属性target和serializedObject, 前者代表要自定义的类的实例化对象, 默认是Object类型, 我们一般在OnEnable里将其转换为对应的类: _target = target as MonoTest;, serializedObject属性封装了对应类上所有的序列化字段和一些有用的方法, 每个字段对应一个序列化属性SerializedProperty, 并在使用之前把两者做绑定: m_IntValue = serializedObject.FindProperty(“intValue”);.
重写OnInspectorGUI
方法, 这个方法会在对象获得焦点或者对象属性变化或者其他一些情况下调用, base.OnInspectorGUI();
表示按照Editor默认的行为将所有的序列化属性绘制出来.
然后对serializedObject
进行刷新和应用修改: serializedObject.Update();
, serializedObject.ApplyModifiedProperties();
.
public class MonoTest : MonoBehaviour
{
public enum EnumValue
{
EnumValue1,
EnumValue2,
EnumValue3,
}
public int intValue;
public bool boolValue;
public EnumValue enumValue;
}
[CustomEditor(typeof(MonoTest), true)]
public class MonoTestEditor : Editor
{
private MonoTest m_Target;
private SerializedProperty m_IntValue;
private SerializedProperty m_EnumValue;
private void OnEnable()
{
_target = target as MonoTest;
m_IntValue = serializedObject.FindProperty("intValue");
m_EnumValue = serializedObject.FindProperty("enumValue");
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
serializedObject.Update();
//......//
serializedObject.ApplyModifiedProperties();
}
}
}
private SerializedProperty m_IntValue;
m_IntValue = serializedObject.FindProperty(“intValue”);
https://www.bilibili.com/read/cv12843014
https://zhuanlan.zhihu.com/p/569798161
http://www.c-s-a.org.cn/html/2021/6/7974.html
https://blog.51cto.com/dasein58/4584410
http://www.gimoo.net/t/1603/56e54309cac53.html
https://github.com/umasteeringgroup/UMA/releases/tag/v2.13a3
https://zhuanlan.zhihu.com/p/564863299
https://www.cnblogs.com/yuiyui19911002/p/14525873.html
https://www.readkong.com/page/uma-unity-multipurpose-avatar-5870040
UMA,Unity Multipurpose Avatar,是一个开源Avatar创建框架,通过它可以实现自定义人物(或任何生物)的模型,包括换装,改变身材样貌等功能。
使用UMA需要的内容包括以下三个主要方面:基础网格(base meshes),插槽(slots)和覆盖图(overlays)。
https://www.readkong.com/page/uma-unity-multipurpose-avatar-5870040
https://wenku.baidu.com/view/29b50340a75177232f60ddccda38376baf1fe096.html?wkts=1676540023314&bdQuery=%E9%97%AA%E8%80%80%E6%9A%96%E6%9A%96%E7%9A%84%E6%8D%A2%E8%A3%85%E7%B3%BB%E7%BB%9F%E5%BC%80%E5%8F%91
http://www.umawiki.secretanorak.com/Wardrobe
https://github.com/umasteeringgroup/UMA/releases/tag/v2.13a3
http://www.gimoo.net/t/1603/56e54309cac53.html
https://indienova.com/u/%25E6%2582%259F%25E7%25A9%25BA%25E5%25AE%259E%25E9%25AA%258C%25E5%25AE%25A4/blogread/5104
https://indienova.com/u/%25E6%2582%259F%25E7%25A9%25BA%25E5%25AE%259E%25E9%25AA%258C%25E5%25AE%25A4/blogread/4866
*1) Slot:*就是 mesh,组成 character 的基本单位。SlotList是有顺序的,这个顺序视频有给出,我不太明白的是在特定位置加 slot 怎么反应在代码里(比如加翅膀),总隐约感觉是3D软件里处理好后,放到基础 slot 列表里最后一个,这个我以后做的时候会验证一下。
*2) Overlay:*蒙在 mesh 上的贴图,就是 character 的皮肤。
*3) DNA:*改变外形的一组参数。
*4) Race:*一组链接到特定用途 mesh 的 slots,分为男人和女人。
**什么是 pipeline?**先建模,再骨骼,然后蒙皮,最后导入 Unity
每個創建的UMAAvatar有他自己的唯一的mesh和貼圖,需要額外的內存。標準的貼圖分辨率是2048x2048,但推薦使用較少的Avatar數量,若果遊戲創建了大量的Avatar,那麼使用較低分辨率的貼圖、共享mesh和貼圖是有必要的。UMA最初計劃在屏幕最多同屏50個Avatar,但最近版本可以輕易上百個獨特的Avatar。
每個slot需要至少一個overlay但通常會有一個overlay列表。Overlay帶有所有必須的用來創建最終材質的貼圖并可以有額外的映射信息。列表中的第一個overlay為基礎貼圖,其它的都被組合到第一個上,按隊列順序,創建最終atlas。
UMA標準shader需要overlay提供兩張材質,一張Diffuse(RGB)+overlay遮罩(A),另一張Normal貼圖(GA),Specular®和Gloss(B)。這些非標準貼圖讓我們壓縮大量信息在2張材質裡,減少最終內存消耗。
Unity 角色自动播放随机动画
https://www.codenong.com/cs106882222/
https://www.joyindie.com/articles/14891.html
https://blog.csdn.net/weixin_44302602/article/details/108408888
https://blog.csdn.net/liang_704959721/article/details/80880422
https://blog.csdn.net/f_957995490/article/details/109789771
https://www.cnblogs.com/uplugin/p/13728103.html
用本地持久化类PlayerPrefs、使用二进制的方法序列化和反序列化(Serialize、Deserialize)、使用Json方法、使用XMl方法。
https://zhuanlan.zhihu.com/p/260157229
https://www.jianshu.com/p/17e7b289f48a
https://www.bbsmax.com/A/nAJvZPPGJr/
https://blog.csdn.net/lsyiwxy/article/details/121913419
https://blog.csdn.net/u014732824/article/details/85055915
https://blog.csdn.net/u014361280/article/details/108531150
https://zhuanlan.zhihu.com/p/37298440
https://zhuanlan.zhihu.com/p/564148934
https://zhuanlan.zhihu.com/p/397409871
https://zhuanlan.zhihu.com/p/28060135
https://zhuanlan.zhihu.com/p/216116684
https://zhuanlan.zhihu.com/p/24553860
https://zhuanlan.zhihu.com/p/23733044
https://blog.51cto.com/u_8378185/5990637
https://blog.csdn.net/q764424567/article/details/122474949
https://blog.csdn.net/weixin_44453949/article/details/116902791
https://betheme.net/news/txtlist_i62699v.html?action=onClick
https://www.pianshen.com/article/6880163927/
https://blog.csdn.net/Ha1f_Awake/article/details/103096541
https://zhuanlan.zhihu.com/p/33475078
https://blog.csdn.net/ysn11111/article/details/127706192
https://www.likecs.com/show-204598466.html
https://mp.weixin.qq.com/s/HldDEKQs5yAjMFdz0VoKOg
https://www.cnblogs.com/revoid/p/10647060.html
设计模式与游戏完美开发 (蔡升达 著)
https://blog.csdn.net/x73901/article/details/107260344/
https://blog.csdn.net/float_freedom/article/details/126221260
单例模式在系统设置了全局的访问点,优化和共享资源的访问。但是滥用单例也带来的上述的三个方面的危害,无法统一管理对象的生命周期、增加耦合、针对实现编程而不是针对接口编程。如何享受单例模式带来的好处并且解决她带来的危害在于,如何通过一种解耦的方式全局获取一个单例对象,并且这个单例对象的生命周期是可管理的,并且这个单例对象是针对接口的抽象实现。
https://blog.csdn.net/awodwde/article/details/108914763
https://blog.csdn.net/java_dazhuzhu/article/details/119548564
有一个命令暂存类(invoke),定义了list容器添加需要暂存的命令,定义了run命令的机制。在产生命令的对象中,不要直接执行命令,而是将命令暂存add进invoke类。最后定期更新去执行命令的时候,通过遍历兵营系统中的营,进行统一执行。
在兵营界面上,除了训练需要这么做,而兵营升级和武器升级可以直接执行。一律用添加监听的方式添加监听函数来实现,原因在于:
在实现网络在线型游戏时,对于client/server间数据封包的传递,大多会使用命令模式。但是这个不会有撤销操作,而是侧重于执行和记录上。记录是另外一个重点,通过记录可以分析玩家与游戏服务间的互动。
记录拥有者产生内部信息提供给记录保存者(备忘录),给了提供记录,定义了get和set函数。在Unity3D里面提供一个类:PlayerPrefs,用key-value的形式将信息存放在文件系统中。有一个类caretaker专门负责保存备忘录,用dictionary范性容器保存多个备忘录,决定最后恢复到哪个版本。
可以搭配命令模式,将执行前的状态都保存好,用于回复命令前版本。
有一个vistor类去定义查询的操作,不同任务的vistor去继承重写这个类。每一个被查询的对象都提供调用这个vistor的公共接口,去实现具体的不同的任务。这样,又可以运用对象的信息,又可以提供不同的任务操作。
优点:新增功能时,在不改变任何类接口的情况下,只需要添加子类作为新的角色访问者即可,大幅增加了系统稳定性,也减少了对类接口不必要的修改。
缺点:被访问类的封装性变差。
装饰模式和建造者模式很像。区别在于,建造者模式要求建造的过程必须是稳定的(由被建造者管理执行顺序)。而装饰模式的建造过程不是稳定的,衣服你可以先穿裤子,再穿褂子,或者干脆不穿褂子,穿个短袖等等,是内部的建造过程不是稳定的。
在热更新中,如果一个资源还没有被使用。则用一个资源代理人先呈现在画面上,让玩家知道这个游戏资源还在下载。
https://zhuanlan.zhihu.com/p/85026259
https://zhuanlan.zhihu.com/p/23821422
https://blog.csdn.net/qq_41841482/article/details/107774028
http://www.readke.com/c/03204IV32022.html
http://www.360doc.com/content/16/0829/11/110467_586723113.shtml
https://blog.csdn.net/m0_50488845/article/details/120835278
https://www.lmlphp.com/user/58486/article/item/1609601/
https://blog.csdn.net/qq_41841482/article/details/107774028
https://blog.csdn.net/qq_41841482/article/details/107774028
https://blog.csdn.net/fuzhongmin05/article/details/105976982
https://blog.csdn.net/Littewood/article/details/124801581
https://baijiahao.baidu.com/s?id=1694911077228884017&wfr=spider&for=pc
https://blog.csdn.net/qq_52690206/article/details/128852922
https://blog.csdn.net/m0_51776409/article/details/126150120
https://blog.51cto.com/u_15075520/4543779
https://www.bbsmax.com/A/E35pNMGEzv/
1,class 是引用类型,structs是值类型
既然class是引用类型,class可以设为null。但是我们不能将struct设为null,因为它是值类型。
2.资源管理系统-Addressable Asset
https://www.jianshu.com/p/e79b2eef97bf
3.Dictionary字典:实例化:Dictionary<键key,值value> 名字dic=new Dictionary<键key,值value>();
Dictionary
方法:
Dic.Add(key,value)给字典添加值
Dictionary[key]表示key所对应的值
ContainsKey(key)判断key是否存在
注意:方法首字母是大写,有小括号,属性第一个单词首字母小写后边单词首字母大写
嵌套字典
嵌套实例化:Dictionary
Instantiate函数实例化:Instantiate函数实例化是将original对象的所有子物体和子组件完全复制,成为一个新的对象。这个新的对象拥有与源对象完全一样的东西,包括坐标值等。
original:用来做复制操作的对像物体,源对象
position:实例化的对象的位置坐标
rotation:实例化的对象的旋转坐标(旋转四元数)
parent:实例化对象的父对象,就是给这个实例化对象找的爹,在完成实例化函数处理后,实例化对象将在父对象下,是父对象的子对象
1.语法糖:计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。语法糖能够增加程序的可读性,从而减少程序代码出错的机会。
在C语言里用a[i]表示*(a+i),用a[i][j]表示*(*(a+i)+j)
2.代码注意:性能、可读、(正确)简化
3.lua 的pairs和ipairs:ipairs适用于数组(i估计是integer的意思),pairs适用于对象,因为数组也是对象,所以pairs用于数组也没问题。
4.lua: for in:for in在自己内部保存三个值:迭代函数、状态常量、控制变量。更通用的for in语法应该是:
for k,v in iter,tab,var do
body
end
for in在内部保存了迭代函数、状态常量、控制变量,后两者是可以封装到迭代函数内部的
elementIterator(array)返回一个匿名函数作为迭代函数,该迭代函数会忽略掉传给它的参数,array和控制变量已被保存在迭代函数中。
将for in展开来看会更明显:
iterator = elementIterator(array)
element,value = iterator(nil,nil)–忽略参数,value置为nil
if(element) then
repeat
print(element)
element,value = iterator(nil,element)–忽略参数
until(not element)
end
5.lua中table存储方式:table组成:哈希表:Key-value键值队,当哈希表有冲突时候,同个链表方式组织冲突元素。数组用来存储数据(数字、表等)
先哈希(键值对),后数组(值)的方式进行分配,
table在存储值的时候是按照顺序的,但是在存储键值对的时候是按照键的哈希值存储的,
并不会按照键的字母顺序或是数字顺序存储。
请注意最后一个table,即使元素为空nil的时候,也会分配一个key给它
ipairs( i开头的巧记 int类型的数值开头只是为了助记 不是实际含义)
遍历的索引的特点
1.必须是从1开头的 int类型的连续整数 1 2 3 4 5 6 7 8 9 ……………………
2.索引不能断开,断开则终止遍历(当存在nil 类型的数据)
终止时机
1.索引断开
2.下一个索引不存在
pairs
遍历的索引的特点
1.遍历的顺序是随机的,但是一定会遍历整个表
2.pairs是先按照索引值打印(数字型key,可以用[ ]访问),然后打印哈希(键值对)
终止时机
1.所有元素遍历完毕
异步模式:
1.异步方法的执行流通常遵守下列流程。
(1) 执行某些操作。
(2) 开始异步操作,并记住返回的token。
(3) 可能会执行其他操作。(在异步操作完成前,往往不能进行任何操作,此时忽略该步骤。)
(4) 等待异步操作完成(通过token)。
(5) 执行其他操作。
(6) 完成。
2.可等待模式:
异步方法再碰到await表达式之前都是使用同步方式,所以awit表达式在其他表达式前加入await。
等待await一个异步操作:包含以下含义操作:1. 告知是否已经完成;
2. 如未完成可附加后续操作;
3. 获取结果,该结果可能为返回值,但至少可以指明成功或失败。
3.所以C#只提供了一个从 System.Runtime.CompilerServices 命名空间中的 INotifyCompletion接口。await表达式的接口。
表示完成时计划延续的操作。它带有的方法:方法OnCompleted(Action) 计划实例完成时调用的延续操作。
4.Action委托事件:
将不变的逻辑封装,变化的部分使用委托Action(c#系统内置的委托类型,它可以指向一个没有返回值、没有参数的方法,泛型委托)
委托类似于 C++ 函数指针,但它们是类型安全的。
委托允许将方法作为参数进行传递。
委托可用于定义回调方法。
委托可以链接在一起;例如,可以对一个事件调用多个方法。
方法不必与委托签名完全匹配。
5.IEnumerbale 和 IEnumerator:https://www.cnblogs.com/vaevvaev/p/7117355.html
IEnumerable接口是非常的简单,只包含一个抽象的方法GetEnumerator(),它返回一个可用于循环访问集合的IEnumerator对象。IEnumerator对象有什么呢?它是一个真正的集合访问器,
IEnumerator接口定义了一个Current属性,MoveNext和Reset两个方法,这是多么的简约。既然IEnumerator对象时一个访问器,那至少应该有一个Current属性,来获取当前集合中的项吧。
MoveNext方法只是将游标的内部位置向前移动(就是移到一下个元素而已)。
(一个类型是否支持foreach遍历,必须满足下面条件:
方案1:让这个类实现IEnumerable接口
方案2:这个类有一个public的GetEnumerator的实例方法,并且返回类型中有public 的bool MoveNext()实例方法和public的Current实例属性。)
6.invoke和begininvoke:
https://www.cnblogs.com/lsgsanxiao/p/5523282.html
7.Event?.Invoke()
event不为null,则invoke,这是C#6的新语du法。 ?.称为空zhi值传播运算符。
8.C#Dispose模式:为了及时释放宝贵的非托管资源和托管资源,并且保证资源在被gc回收的时候可以正确释放资源,同时兼顾执行效率
https://www.cnblogs.com/xyzf/p/9021513.html
可以自定义这个函数
9.c#实现每隔规定时间自动执行程序代码
https://www.cnblogs.com/dullbaby/p/4902346.html
https://zhuanlan.zhihu.com/p/25844861
C#的扩展方法:
1.概念:扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的。
它们的第一个参数指定该方法作用于哪个类型,并且该参数以 this 修饰符为前缀。
扩展方法当然不能破坏面向对象封装的概念,所以只能是访问所扩展类的public成员。
必须是静态类才可以添加扩展方法
注意调用扩展方法,必须用对象来调用
string str = “quzijing”;
//注意调用扩展方法,必须用对象来调用
string Newstr = str.Add();
//声明扩展方法
//扩展方法必须是静态的,Add有三个参数
//this 必须有,string表示我要扩展的类型,stringName表示对象名
//三个参数this和扩展的类型必不可少,对象名可以自己随意取如果需要传递参数,//再增加一个变量即可
public static string Add(this string stringName)
{
return stringName+ “a”;
}
}
public static class ExtensionStudentInfo
{
//声明扩展方法
//要扩展的方法必须是静态的方法,Add有三个参数
//this 必须有,string表示我要扩展的类型,stringName表示对象名
//三个参数this和扩展的类型必不可少,对象名可以自己随意取如果需要传递参数,再增加一个变量即可
public static string ExtensionStuInfo(this Student stuName)
{
return stuName.StuInfo();
}
//声明扩展方法
//要扩展的方法必须是静态的方法,Add有三个参数
//this 必须有,string表示我要扩展的类型,stringName表示对象名
//三个参数this和扩展的类型必不可少,对象名可以自己随意取如果需要传递参数,在此我们增加了两个string类型的参数
public static string ExtensionGetStuInfo(this Student student, string stuname, string stunum)
{
return student.getStuInfo(stuname, stunum)+ “\n读取完毕”;
}
}
关于GameObject:https://docs.unity3d.com/Manual/class-GameObject.html
所有GameObject都隐式具有一个Transform
using UnityEngine;
public class WaypointManager : MonoBehaviour {
public Transform[] waypoints;
void Start()
{
waypoints = new Transform[transform.childCount];
int i = 0;
foreach (Transform t in transform)
{
waypoints[i++] = t;
}
}
}