加強(qiáng)門戶網(wǎng)站建設(shè)南寧網(wǎng)站seo排名優(yōu)化
文章目錄
- 前言
- 一、初始化虛擬點(diǎn)
- 1.1點(diǎn)結(jié)構(gòu):
- 1.2每個(gè)點(diǎn)有的狀態(tài):
- 1.3生成點(diǎn)結(jié)構(gòu):
- 二、實(shí)例化邊緣碰撞盒
- 2.1計(jì)算生成邊緣碰撞盒
- 三、涂抹部分
- 3.1.虛擬點(diǎn)
- 3.2.鼠標(biāo)點(diǎn)
- 3.3.內(nèi)圈
- 3.4.外圈
- 四、關(guān)于優(yōu)化
- 結(jié)語:
前言
老規(guī)矩先上效果圖
繼上一篇涂抹地形文章講解發(fā)出后,有不少網(wǎng)友私信找我要原碼,也有部分網(wǎng)友覺得太復(fù)雜了難以實(shí)現(xiàn)。關(guān)于原碼因?yàn)檫@個(gè)Demo最初始的原碼弄不見了,還有就是代碼本身用在了公司的游戲項(xiàng)目中加了很多項(xiàng)目相關(guān)的邏輯,我不知道能不能分享所以沒有直接公布原碼。關(guān)于太難實(shí)現(xiàn)的問題,如果只是要達(dá)到涂抹地形的話這里我再分享一個(gè)更簡單的方式,非常簡單!
上一篇的地址:
涂抹地形碰撞部分方法一
為什么說簡單呢,因?yàn)橹恍枰玫骄嚯x計(jì)算公式,與圓形碰撞盒:
好了下面開始進(jìn)入正文…
一、初始化虛擬點(diǎn)
初始化的時(shí)候創(chuàng)建檢查點(diǎn),用數(shù)組存起來。
需要注意的是這里的檢查點(diǎn)只是Vector2,不需要實(shí)例化否則會(huì)非常消耗性能。切記切記…
1.1點(diǎn)結(jié)構(gòu):
每個(gè)點(diǎn)用一個(gè)結(jié)構(gòu)存起來,我們需要存下
下面是點(diǎn)數(shù)據(jù)結(jié)構(gòu),分別是記錄:1.點(diǎn)的位置,2.當(dāng)前點(diǎn)的狀態(tài),3.對(duì)應(yīng)的碰撞盒
private class PointData
{public Vector2 pos; //點(diǎn)位置public pointStatic sta; //點(diǎn)狀態(tài)public GameObject col; //點(diǎn)實(shí)例
}
1.2每個(gè)點(diǎn)有的狀態(tài):
1.已經(jīng)廢棄,這個(gè)位置已經(jīng)被完全挖開
2.等待檢測,這個(gè)位置還沒被挖到
3.正在使用:即這個(gè)位置是挖掘的邊緣,有碰撞盒
private enum pointStatic
{die, //已經(jīng)廢棄wait, //等待檢測collid //正在使用
}
1.3生成點(diǎn)結(jié)構(gòu):
int line = (int)(scale.x * 100);
int row = (int)(scale.y * 100);
float distancesX = 1f / line;
float distancesY = 1f / row;
for (int j = 0; j < row; j++)
{for (int k = 0; k < line; k++){Vector2 v2 = new Vector2(distancesX * k - 0.5f, distancesY * j - 0.5f);PointData data = new PointData();data.pos = v2;data.sta = pointStatic.wait;listPoint.Add(data);}
}
不難看出這些結(jié)構(gòu)點(diǎn),除了Vector2以外并沒有實(shí)例化什么內(nèi)容,主要是這里創(chuàng)建了10000個(gè)點(diǎn),這樣可以極大的節(jié)省性能.
其實(shí)就像如圖,創(chuàng)建了100X100個(gè)虛擬點(diǎn):
二、實(shí)例化邊緣碰撞盒
為了一開始還未操作時(shí),物體不會(huì)從方塊邊緣直接穿過去過,我們需要將邊緣的點(diǎn)先實(shí)例化出碰撞盒,效果如圖:
2.1計(jì)算生成邊緣碰撞盒
下面方法計(jì)算出邊緣位置,并生成一邊緣一圈碰撞盒,并將點(diǎn)記錄到上面的數(shù)組中,這樣后面涂抹的時(shí)候才可以將碰撞盒去掉.
計(jì)算邊緣位置并生成的代碼:
distancesX *= 3;
distancesY *= 3;
for (float x = -0.5f; x <= 0.5; x += distancesX)
{CreateBianKuan(new Vector3(x, -0.5f, 0));CreateBianKuan(new Vector3(x, 0.5f, 0));CreateBianKuan(new Vector3(-0.5f, x, 0));CreateBianKuan(new Vector3(0.5f, x, 0));
}
下面是具體生成的代碼:
public void CreateBianKuan(Vector3 v3)
{Object obj = Resources.Load("MousePoint3");GameObject go = Instantiate(obj, Vector2.zero, Quaternion.Euler(Vector3.zero), target.transform) as GameObject;go.transform.localPosition = v3;go.transform.localScale = new Vector3(ColliderSize / scale.x, ColliderSize / scale.y, ColliderSize);PointData data = new PointData();data.pos = new Vector2(v3.x, v3.y);data.sta = pointStatic.collid;data.col = go;listPoint.Add(data);
}
"MousePoint3"其實(shí)就是帶碰撞盒的圈
三、涂抹部分
前面鋪墊了那么多,終于到核心的涂抹部分了
如圖:
3.1.虛擬點(diǎn)
圖中密密麻麻的是我們未創(chuàng)建碰撞盒的虛擬點(diǎn),
3.2.鼠標(biāo)點(diǎn)
黑色圈是鼠標(biāo)點(diǎn)擊的位置
3.3.內(nèi)圈
紅色為內(nèi)圈,是我們需要挖掘的位置,此圈內(nèi)的點(diǎn)則:
1):如狀態(tài)為dit廢棄則不做處理,
2):如狀態(tài)為collid(有碰撞盒),即有碰撞盒則,銷毀碰撞盒并改為die(廢棄)
3):如為wait(等待處理),則狀態(tài)改為die(廢棄)
3.4.外圈
藍(lán)圈略大于紅圈,此范圍是我們挖掘邊緣的位置,則紅圈以外藍(lán)圈以內(nèi)的點(diǎn)則:
1):狀態(tài)為dit廢棄則不做處理,
2):狀態(tài)為wait(等待處理)則創(chuàng)建碰撞盒,并改為collid(有碰撞盒)
3):狀態(tài)為collid則不做處理
具體代碼如下,大家參考一下:
public void WaDong()
{//創(chuàng)建一條射線一攝像機(jī)為原點(diǎn)Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);RaycastHit hit;//射線碰撞到游戲地形時(shí)if (Physics.Raycast(ray, out hit)){//從世界坐標(biāo)轉(zhuǎn)為局部坐標(biāo)Vector2 localCenter = target.transform.InverseTransformPoint(hit.point);for (int i = 0; i < listPoint.Count; i++){Vector2 centerPos = listPoint[i].pos - localCenter;centerPos.x *= scale.x;centerPos.y *= scale.y;float dis = Vector2.Distance(centerPos, Vector2.zero);if (dis < Circle1Range1 && listPoint[i].sta != pointStatic.die){listPoint[i].sta = pointStatic.die;if (listPoint[i].col != null){GameObject.Destroy(listPoint[i].col);}}else if (dis >= Circle1Range1 && dis < Circle1Range2 && listPoint[i].sta == pointStatic.wait){listPoint[i].sta = pointStatic.collid;Object obj = Resources.Load("MousePoint3");GameObject go = Instantiate(obj, Vector2.zero, Quaternion.Euler(Vector3.zero), target.transform) as GameObject;go.transform.localPosition = listPoint[i].pos;go.transform.localScale = new Vector3(ColliderSize / scale.x, ColliderSize / scale.y, ColliderSize);listPoint[i].col = go;}}}
}
四、關(guān)于優(yōu)化
關(guān)于優(yōu)化可以從幾個(gè)方面著手,因?yàn)榕鲎埠械臄?shù)量比較多,而且創(chuàng)建銷毀比較頻繁.這一部分可以考慮對(duì)象池.
另一方面是銷毀的點(diǎn)其實(shí)不太需要再次進(jìn)行計(jì)算,因?yàn)榭梢钥紤]將廢棄點(diǎn)的點(diǎn)移出表外.
進(jìn)一步的優(yōu)化留給大家自己思考咯…
結(jié)語:
這篇文章主要和大家分享一下實(shí)現(xiàn)的思路,說起來也簡單.一開始創(chuàng)建一堆虛擬點(diǎn)等著檢查.以點(diǎn)擊位置為圓心進(jìn)行距離計(jì)算.
小圈內(nèi)為涂抹掉的位置,大圈內(nèi)為邊緣位置判斷是否增刪碰撞點(diǎn).
希望對(duì)大家有幫助.如果可以幫忙點(diǎn)個(gè)贊,謝謝.