- 計劃:
【腳本通信】
【委托】
【UI游戲界面-上下頁切換】
【單例模式】
【任務系統(tǒng)】
【對話系統(tǒng)】
【ScriptableObject實現(xiàn)技能樹】
【三種拖拽方法】
【異步場景加載】
【代碼整理 Inspector 里顯示的腳本變量整理】
2020年9月18日
DFA算法過濾文本的敏感詞
- Hashtable 的鍵值對可以是任何類型(均以object類為參數(shù))
- 相關部門網(wǎng)站上會有敏感詞庫提供
- 完成XML模板建立后,打開Excel可以自動映射成表格,然后擴展完了之后
2020年9月19日
【事件?語法篇】如何聲明自定義的事件以及事件的完整/簡略聲明格式..
事件是基于委托的,但事件不是委托類型。事件的本質(zhì)是委托字段的一個包裝器。既然是包裝器,那么就會在原有基礎上有更多限制。(在事件的完整聲明中就可以知道為什么了)
為什么說事件是基于委托的?
1.因為委托可以提供強制類型兼容的語法
2.因為委托可以存儲方法的引用事件在對委托的包裝上做出了哪些事?
1.事件只能使用+=、-=,不能使用= (在委托中使用=符號,叫做Reset Invocation List,重置調(diào)用列表)
2.事件的調(diào)用(OnXX.Invoke(...))只能在事件擁有者自身的觸發(fā)邏輯中調(diào)用,而委托可以在任意地方調(diào)用。
*3.事件的簡略聲明格式中可以用==、!=來判斷是否為空,但是完整聲明格式里不行。事件的一般聲明方式
一般在使用事件的時候,都是用public event EventHandler OnXX; 來定義的,
其中EventHanlder這個類型是一個約定,代表所有訂閱OnXX的方法,都要滿足EventHandler的形式。EventHandler的約定是void EventHandler(object sender, EventArgs e);它是一個委托類型。
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//1.事件擁有者
//2.事件
//3.事件響應者
//4.事件處理器
//5.訂閱
//1.我(類)要有一個事件(成員)
//2.一群別的類關心、訂閱我的事件(訂閱的時候要符合約定) custom.OnOrder += waitor.TakeAction;
//3.我的事件發(fā)生了! (一定是由事件擁有者的內(nèi)部邏輯觸發(fā)的) OnOrder.Invoke(this,e);
//4. 關心的類們被一次性通知到
//5. 被通知到的人,拿著事件參數(shù),做出相應 TakeAction(object _sender, EventArgs _e)
public class EventExample_Pro : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
Custom custom = new Custom("Jimmy");
Waitor waitor = new Waitor();
//訂閱
custom.OnOrder += waitor.TakeAction;
custom.Order("抹茶星冰樂",25,"大杯");
custom.Order("焦糖瑪奇朵", 28, "超大杯");
custom.PayBill();
}
}
//事件擁有者
public class Custom
{
public Custom(string name)
{
Name = name;
}
public string Name { get; set; }
public float Bill { get; set; }
public event EventHandler OnOrder;
public void Order(string coffeeName, float coffeeBasePrice, string cup)
{
if (OnOrder != null) //在事件的完整聲明中,是不可以通過!=符號來判斷的,這里是個語法糖
{
OrderEventArgs e = new OrderEventArgs(coffeeName, coffeeBasePrice, cup);
//事件觸發(fā)
OnOrder.Invoke(this, e);
}
}
public void PayBill()
{
Debug.Log(Name + "一共需要支付" + Bill);
}
}
//事件響應者
public class Waitor
{
//事件處理器
//按照自己的職責、任務做出特定處理
internal void TakeAction(object _sender, EventArgs _e)
{
Custom custom = _sender as Custom;
OrderEventArgs e = _e as OrderEventArgs;
float bill = 0;
switch (e.CoffeeCup)
{
case "中杯":
bill = e.CoffeeBasePrice;
break;
case "大杯":
bill = e.CoffeeBasePrice + 3;
break;
case "超大杯":
bill = e.CoffeeBasePrice + 6;
break;
default:
Debug.Log("只能在中杯、大杯、超大杯里挑選");
break;
}
custom.Bill += bill;
Debug.Log(custom.Name +"點了一杯"+ e.CoffeeName+",需要支付" + bill);
}
}
//事件消息
public class OrderEventArgs : EventArgs
{
public OrderEventArgs(string name, float basePrice, string cup)
{
CoffeeName = name;
CoffeeBasePrice = basePrice;
CoffeeCup = cup;
}
public string CoffeeName;
public float CoffeeBasePrice;
public string CoffeeCup;
}
-
事件的完整聲明方式(機理)
因為只在Custom中作了改變,所以只列出了Custom類。 事件的內(nèi)部機理可以和屬性的內(nèi)部機理比對著來理解。
public class Custom
{
public Custom(string name)
{
Name = name;
}
public string Name { get; set; }
public float Bill { get; set; }
//“事件是基于委托”這句話的核心↓↓↓
public EventHandler orderEventHandler;
//orderEventHandler是一個委托類型的字段,而OnOrder事件是它的包裝器
//OnOrder是依賴于orderEventHandler的
public event EventHandler OnOrder
{
add
{
orderEventHandler += value;
}
remove
{
orderEventHandler -= value;
}
}
public void Order(string coffeeName, float coffeeBasePrice, string cup)
{
if (orderEventHandler != null)
{
OrderEventArgs e = new OrderEventArgs(coffeeName, coffeeBasePrice, cup);
//事件觸發(fā)
//完整聲明中,只能通過事件內(nèi)部的委托字段來執(zhí)行
orderEventHandler(this, e);
}
}
public void PayBill()
{
Debug.Log(Name + "一共需要支付" + Bill);
}
}
- 另外EventHandler、Sender、EventArgs 都可以派生。
2020年9月20日
委托與事件
通過事件來改善腳本通信
本次例子,假設有以下三個類:
- Player : 會死亡
- Achievements(成就) :在死亡1000次的時候觸發(fā)成就
- UserInterface(用戶界面)這三個 : 顯示Player死亡信息
笨辦法:
public class Player{
void Die(){
FindObjectOfType<Achievements>().OnPlayerDeath();
FindObjectOfType<UIInterface>().OnPlayerDeath();
}
}
public class Achievements{
public void OnPlayerDeath(){
}
}
public class UserInterface{
public void OnPlayerDeath(){
}
}
在這里相當于是Player做了一件事情,就去主動調(diào)用其他類。
這樣做會發(fā)生什么?
后續(xù)當游戲系統(tǒng)復雜了,Player里頭就會有一堆雜七雜八的引用。讓Player的功能代碼看起來不那么專一。
也會使得代碼復用性變差,如果想在其他項目復用Player代碼。首先得剔除所有無關引用,因為這些引用壓根不在新項目中。那怎么做?
讓Player死亡時觸發(fā)一個事件去通知所有關注它死亡的類。
因為監(jiān)聽player是否死亡,實際上是其他想知道這個消息的類的職責因此正確的代碼應該如下:
public class Player{
public event Action deathEvent; //通過事件來通知其他類
void Die(){
if( deathEvent != null){
deathEvent(); //或者deathEvent.Invoke();
}
}
public class Achievements{
void Start(){
FindObjectOfType<Player>().deathEvent += OnPlayerDeath; // 訂閱
}
public void OnPlayerDeath(){
// TODO Something ...
// ....
FindObjectOfType<Player>().deathEvent -= OnPlayerDeath; // 記得取消訂閱
}
}
public class UserInterface{
void Start(){
FindObjectOfType<Player>().deathEvent += OnPlayerDeath; // 訂閱
}
public void OnPlayerDeath(){
// TODO Something ...
// ....
FindObjectOfType<Player>().deathEvent -= OnPlayerDeath; // 取消訂閱
}
}
- 另外:關于public event 后面跟的兼容類型,除了.Net給定的EventHandler,還可以用Action / Action<T> / Action<T1,T2> 、Func<ReturnT> / Func<T1,ReturnT>或是自定義的委托類型來約束。
- 還有在喚醒事件的時候,一定要實現(xiàn)判空。
2020年9月23日
使用事件制作3D自動開關門(附:3D人物移動和旋轉(zhuǎn),out輸出參數(shù),3D搭建使用的快捷鍵..
選中相機,Ctrl+Shift+F 相機角度自動變成Scene界面視角
-
按住Ctrl拖拽會對其網(wǎng)格。網(wǎng)格與對齊捕捉設置:
網(wǎng)格與對齊
每次移動的單位 按住V頂點對齊
在這期視頻中找到了別的想要的,Tween系列插件——LeanTween
Tween 事實上就是一種數(shù)學庫
能夠讓使用者更加方便的處理數(shù)學動畫
- 在AssetStore中下載免費版的之后,就可以用了。例如:
LeanTween.moveLocalY( gameObject, to , time);
也可以用鏈式寫法,設置運動過程中的速度曲線。例如:
LeanTween.moveLocalY( gameObject, 3.0f , 1.0f).setEaseInSine();

在OnDisable或者OnDestroy中記得取消訂閱,不然會報錯,而且導致內(nèi)存過大。
代碼中用枚舉類型定義一個字段的話,在Inspect界面會有下拉框。
Unity官方免費插件——ProGrids,方便搭建場景
Universal Render Pipeline
2020年9月24日
-
資源商城的FBX Exporter可以把Unity中的模型導出成.FBX格式文件(在上面視頻中的28:10有教程)
插件預覽
2020年9月24日
排序、DotTween、LeanTween、十大Array用法、富文本、模板方法
- 存入數(shù)據(jù)庫的時間,要用國際協(xié)調(diào)時區(qū)DataTime.UtcNow
...我還是從第一集開始看吧
委托第一集
最近在研究NLP,還有浮島星球的策劃,還有大創(chuàng)的一些事情。
女朋友在準備研究生面試,明天就要開始了,默默支持一下,嘿嘿!
2020年9月28日
- 以下兩篇,我就大概地看了下,停留在了解層面
游戲設計模式--Unity事件隊列
使用DoTween在Unity中制作隊列(Sequence)動畫
2020年10月16日
Unity 中制作虛擬搖桿
2020年10月18日
Unity官方社區(qū)中的Issue Tracker Bug記錄都在里頭,可以去查查有沒有解決方案。
Unity UI事件管理系統(tǒng)設計,看不懂TAT..
-
Unity MVC簡要說明 這里面提到了一個給初學者了解MVC的插件 :
Code Control | Easy MVC for Unity
Unity MVC初學者插件
- 【Unity3D】在Unity3d中如何使用MVC框架 較為具體地說了MVC,也給了例子,但我只看懂了 一到四節(jié),五感覺例子還是太簡單了,我沒咋有更具體的概念。
Model: 存數(shù)據(jù),一般都是定義一些數(shù)據(jù)字段(比如:用戶名稱、設備縮放比、貼圖材質(zhì)、也可以有數(shù)據(jù)庫增刪改查操作這樣的方法
View: 存放UI數(shù)據(jù)引用、事件監(jiān)聽
Control:實現(xiàn)業(yè)務邏輯功能,獲取Model的數(shù)據(jù),通知View層更新數(shù)據(jù)
// 以下說的都有點問題↓↓↓
// FIX : UnityEvent中沒有封裝UnityAction字段
- <封裝了UnityAction委托字段的UnityEvent> 和 <C#中以關鍵字形式存在的event的區(qū)別>
UnityEvent中包含
AddListener(UnityAction call)方法,Button.onClick就是UnityEvent類型的。
在AddListener中,會將參數(shù)call對應的函數(shù)引用,訂閱到該UnityEvent對象中。
//目前還沒找到AddListener內(nèi)部機理。
// ↑↑↑
依賴倒置原則:高層次的模塊不應該依賴于低層次的模塊,兩者都應該依賴于抽象接口。
題外話:
看到了評論區(qū)的爭辯有點意思:

我覺得兩個都說的挺對的,有時候我們需要事先預測一個需求的規(guī)模,也不是什么都要循規(guī)蹈矩。小的需求,做一個大的框架,確實要付出一些接口開發(fā)的成本。但是如果做的時候就考慮了后期要擴展這個功能,就需要想清楚了。
還有博主在這篇文章里說的最后一段,也挺有意思:
講了這么多依賴倒置原則的優(yōu)點,我們也來打擊一下大家,在現(xiàn)實世界中確實存在著必須依賴細節(jié)的事物,比如法律,就必須依賴細節(jié)的定義。 “殺人償命”在中國的法律中古今有之,那這里的殺人就是一個抽象的含義,怎么殺,殺什么人,為什么殺人,都沒有定義,只要是殺人就統(tǒng)統(tǒng)得償命,那這就是有問題了,好人殺了壞人,還要陪上自己的一條性命,這是不公正的,從這一點看,我們在實際的項目中使用依賴倒置原則時需要審時度勢,不要抓住一個原則不放,每一個原則的優(yōu)點都是有限度的,并不是放之四海而皆準的真理,所以別為了遵循一個原則而放棄了一個項目的終極目標:投產(chǎn)上線和盈利。作為一個項目經(jīng)理或架構師,應該懂得技術只是實現(xiàn)目的的工具,惹惱了頂頭上司,設計做得再漂亮,代碼寫得再完美,項目做得再符合標準,一旦項目虧本,產(chǎn)品投入大于產(chǎn)出,那整體就是扯淡!你自己也別想混得更好!
2020年10月19日
- UnityEvent如果要帶參數(shù)的話需要通過泛型的方式——UnityEvent<T0>,但這里有個坑,就是這個泛型的UnityEvent是抽象類,因此需要自己再定義一個類,去繼承它。例如:
public class SelectContentEvent : UnityEvent<string>
{
//空
}
還有一個和UnityEvent不一樣的點——在聲明事件中,需要new。例如:
public SelectContentEvent OnSelectContent = new SelectContentEvent();
2020年10月21日
- 修改某些Unity組件的值的時候,要注意獲取的對象是引用,還是拷貝。
例如在Render類中有一個屬性,它在get方法中做了處理,返回的是materials數(shù)組的一份拷貝。
public Material[] materials { get; set; }
- 在Render組件的API中有如下說明:
Render.materials:
Note that like all arrays returned by Unity, this returns a copy of materials array. If you want to change some materials in it, get the value, change an entry and set materials back.
- Unity封裝的類里頭,如果包含的屬性是數(shù)組,都會返回一份拷貝。如果需要修改數(shù)組中的元素,只能通過改變數(shù)組的入口地址(為數(shù)組整體賦值)。
Unity Connect不做了
Hi JimmyZou,
Today we’re announcing that on February 4, 2021, Unity Connect, our dedicated talent and sharing marketplace, will shut down. We’re proud of the community that rallied around Connect and we are inspired by the great sharing and discovery that came from it.
We want to make this transition as smooth as possible for everyone who uses Connect. If you are an active user on the platform, click here to learn more about the alternatives that will be provided for some Connect features. If you would like to download any part of your profile, please feel free to do so before we delete your information on February 4, 2021.
Unity Connect就業(yè)信息網(wǎng)頁:
https://connect.unity.com/jobs



