Unity3d:在屏幕邊緣顯示其他玩家/敵人/物體的方位

系列傳送門

IOS:
IOS:使用shell命令打包并上傳Itunes
Unity3d:
Unity3d:Canvas適配屏幕分辨率與錨點(Anchors與Pivot)
Unity3d:在屏幕邊緣顯示其他玩家方位
Unity3d:命令行打包Android
Unity3d:命令行編譯IOS
Unity3d:使用Jenkins自動編譯打包IOS(只能打包Development)
Unity3d:使用Jenkins自動編譯打包IOS(打包Ad-hoc,上傳itunes)

最近需要我完成一個小功能:當(dāng)有玩家在屏幕外時,就在屏幕邊緣顯示該玩家所在的方位。
特此記下解決方法浴骂,予以大家借鑒她君。
感謝幫助過的朋友們??扶檐。

1壹士、先復(fù)習(xí)點數(shù)學(xué)小知識

1.1、已知兩個點:P1(x1, y1)雳窟、P2(x2, y2)孽水,在直線方程為:a * x + b = y 的直線上票腰,求a,b

解:
由 :a * x1 + b=y1女气,a * x2 + b=y2
=> a * x2 + y1 - a * x1 = y2
=> a = (y2 - y1) / (x2 - x1)
把a代入: a * x1 + b = y1
=> (y2 - y1) / (x2 - x1) * x1 + b=y1
=> b = y1 - (y2 - y1) / (x2 - x1) * x1
 最終:
a = (y2 - y1) / (x2 - x1)
b = y1 - (y2 - y1) / (x2 - x1) * x1

需要注意兩個點x坐標(biāo)相等的情況:
如果兩個點x坐標(biāo)相等杏慰,則該直線與y軸平行;
如果兩個點y坐標(biāo)相等炼鞠,則該直線與x軸平行逃默;
如果兩個點x,y坐標(biāo)都相等,則不是線簇搅,是同一個點。

1.2软吐、已知兩條直線的方程:a1 * x + b1 = y 和 a2 * x + b2 = y瘩将,求這兩條直線的交點

解:
由 :a1 * x + b1=y,a2 * x + b2=y
=> a1 * x + b1 = a2 * x + b2
=> x = (b2 - b1) / (a2 - a1)
把x代入: a1 * x + b1=y
=> y = a1 * (b2 - b1) / (a2 - a1) + b1
 最終:
x = (b2 - b1) / (a2 - a1)
y = a1 * (b2 - b1) / (a2 - a1) + b1

需要注意a1和a2相等的情況:
如果a1和a2相等凹耙,b1和b2不相等姿现,則兩條直線平行,無交點肖抱;
如果a1和a2相等备典,b1和b2相等,則兩條直線是同一條線意述,無交點提佣;
如果a1和a2不相等,b1和b2相等荤崇,則兩條直線不平行拌屏,有交點,相交于y軸b1點或b2點术荤;
如果a1和a2不相等倚喂,b1和b2不相等,則兩條直線不平行瓣戚,有交點端圈。

1.3焦读、已知線段1和線段2的端點,求這兩條線段的交點

注意是線段舱权,不是直線矗晃。
通過(1)求得端點所在的直線的方程;
通過(2)求得這兩條直線的交點刑巧。

這里需要判斷下交點是落在線段內(nèi)喧兄,還是線段外(虛交點):
如果交點x坐標(biāo)小于線段1的左側(cè)端點的x坐標(biāo),或者交點x坐標(biāo)大于線段1的右側(cè)端點的x坐標(biāo)啊楚,則該交點落在線段1外吠冤,即線段的延長線上,是個虛交點恭理。
反之拯辙,是線段1的正常交點。

2颜价、再學(xué)習(xí)點Unity小知識

傳送門

Unity3d:Canvas適配屏幕分辨率與錨點(Anchors與Pivot)

3涯保、進(jìn)入正題

場景準(zhǔn)備:當(dāng)前玩家(我)是playerA;另一個玩家是playerB周伦。
方位指示器的UI我們放在Root Canvas下夕春。
Root Canvas的CanvasScaler組件配置如下:

  • UI Scale Mode:Scale With Screen Size
  • Reference Resolution:X 1080 ,Y 1920
  • Screen Match Mode:Expand

3.1专挪、理清思路

首先及志,playerA是一定在屏幕內(nèi)的,這里需要判斷playerB是不是在屏幕內(nèi)寨腔。
如果playerB是在屏幕內(nèi)速侈,則無需后面的處理。
如果playerB是在屏幕外迫卢,讓我們繼續(xù)倚搬。

然后,把playerA和playerB的世界坐標(biāo)轉(zhuǎn)換成屏幕坐標(biāo)系里的坐標(biāo)乾蛤,分別記作A和B每界。
注意:這里有個容易鉆進(jìn)去的誤區(qū),就是很容易想到去計算方向向量幻捏,即(BA)盆犁。計算完之后又會自然而然的想著用這個向量去處理上面的問題,最后會發(fā)現(xiàn)篡九,自己已經(jīng)進(jìn)入了一個深坑里谐岁,深深的把自己的思維給圈住了,即使偶爾換個方向思考,比如求交點的方式伊佃,還是容易被這個向量給迷惑窜司,總想著去用這個向量去解決,盡管這個向量在這個方式里沒啥卵用航揉。

這時塞祈,因為A點在屏幕內(nèi),B點在屏幕外帅涂,所以線段AB一定與屏幕的某一個邊框有一個交點(實交點议薪,非虛交點)。
這個交點的位置就是我們需要放置方位指示器UI的位置了媳友。
:實交點斯议,即交點位于線段上;虛交點醇锚,即交點位于線段的延長線上哼御。

3.2、著手解決

屏幕有4個邊框焊唬,所以我們要先找出這四個邊框線段各自擁有的端點坐標(biāo)恋昼。

這里需要注意,A和B兩個點是在屏幕坐標(biāo)系上赶促,線段AB與屏幕邊框的交點也是位于屏幕坐標(biāo)系上液肌。
而方位指示器UI是放在Canvas上的,位于Canvas坐標(biāo)系內(nèi)鸥滨。
所以在計算之前要先做坐標(biāo)系轉(zhuǎn)換矩屁。

這里有兩個轉(zhuǎn)換方式:

  • 方式1:把A和B兩個點轉(zhuǎn)換到Canvas的坐標(biāo)系內(nèi),用轉(zhuǎn)換之后的線段AB計算出與Canvas的四個邊框相交的交點爵赵。
  • 方式2:先在屏幕坐標(biāo)系上,計算出線段AB與屏幕的四個邊框相交的交點泊脐,然后把交點轉(zhuǎn)換到Canvas的坐標(biāo)系內(nèi)空幻。

注意:后面用到的知識在文章Unity3d:Canvas適配屏幕分辨率與錨點(Anchors與Pivot)中有詳細(xì)說明,遇到問題可自行查閱容客。

3.2.1秕铛、按方式1解決

先把A點和B點轉(zhuǎn)換到Canvas的坐標(biāo)系內(nèi):
cA = (A.x * Canvas.Width / Screen.Width, A.y * Canvas.Height / Screen.Height)
cB = (B.x * Canvas.Width / Screen.Width, B.y * Canvas.Height / Screen.Height)

再找出Canvas的四個邊框線段對應(yīng)的端點(左下角是原點):
左側(cè)邊框端點:lbP(0, 0) 、ltP(0, Canvas.Height) 缩挑;
底部邊框端點:lbP(0, 0) 但两、rbP(Canvas.Width, 0) ;
右側(cè)邊框端點:rbP(Canvas.Width, 0) 供置、rtP(Canvas.Width, Canvas.Height) 谨湘;
頂部邊框端點:ltP(0, Canvas.Height) 、rtP(Canvas.Width, Canvas.Height) ;

有了線段cAcB和Canvas的四個邊框線段紧阔,根據(jù)上面的數(shù)學(xué)知識坊罢,可以輕松求得線段cAcB與Canvas某一個邊框的交點,我們記作點P擅耽。此時點P位于Canvas的坐標(biāo)系內(nèi)活孩。
最后把方位指示器UI在P點顯示出來即可。在文章Unity3d:Canvas適配屏幕分辨率與錨點(Anchors與Pivot)的最后有相關(guān)知識乖仇,請自行查閱_憾儒。

3.2.2、按方式2解決

現(xiàn)在線段AB的兩個端點有了(即A乃沙、B點)起趾,下面再找出屏幕的四個邊框線段對應(yīng)的端點(左下角是原點):
左側(cè)邊框端點:lbP(0, 0) 、ltP(0, Screen.Height) 崔涂;
底部邊框端點:lbP(0, 0) 阳掐、rbP(Screen.Width, 0) ;
右側(cè)邊框端點:rbP(Screen.Width, 0) 冷蚂、rtP(Screen.Width, Screen.Height) 缭保;
頂部邊框端點:ltP(0, Screen.Height) 、rtP(Screen.Width, Screen.Height) 蝙茶;

有了線段AB和屏幕的四個邊框線段艺骂,根據(jù)上面的數(shù)學(xué)知識,可以輕松求得線段AB與屏幕某一個邊框的交點隆夯,我們記作點P钳恕。此時點P位于屏幕的坐標(biāo)系內(nèi)。

然后把交點P轉(zhuǎn)換到Canvas的坐標(biāo)系內(nèi):
cP = (P.x * Canvas.Width / Screen.Width, P.y * Canvas.Height / Screen.Height)
最后把方位指示器UI在cP點顯示出來即可蹄衷。在文章Unity3d:Canvas適配屏幕分辨率與錨點(Anchors與Pivot)的最后有相關(guān)知識忧额,請自行查閱_

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末愧口,一起剝皮案震驚了整個濱河市睦番,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌耍属,老刑警劉巖托嚣,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異厚骗,居然都是意外死亡示启,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進(jìn)店門领舰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來夫嗓,“玉大人迟螺,你說我怎么就攤上這事∑≡拢” “怎么了煮仇?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長谎仲。 經(jīng)常有香客問我浙垫,道長,這世上最難降的妖魔是什么郑诺? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任夹姥,我火速辦了婚禮,結(jié)果婚禮上辙诞,老公的妹妹穿的比我還像新娘辙售。我一直安慰自己,他們只是感情好飞涂,可當(dāng)我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布旦部。 她就那樣靜靜地躺著,像睡著了一般较店。 火紅的嫁衣襯著肌膚如雪士八。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天梁呈,我揣著相機與錄音婚度,去河邊找鬼。 笑死官卡,一個胖子當(dāng)著我的面吹牛蝗茁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播寻咒,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼哮翘,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了毛秘?” 一聲冷哼從身側(cè)響起忍坷,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎熔脂,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體柑肴,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡霞揉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了晰骑。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片适秩。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡绊序,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出秽荞,到底是詐尸還是另有隱情骤公,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布扬跋,位于F島的核電站阶捆,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏钦听。R本人自食惡果不足惜洒试,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望朴上。 院中可真熱鬧垒棋,春花似錦、人聲如沸痪宰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽衣撬。三九已至乖订,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間淮韭,已是汗流浹背垢粮。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留靠粪,地道東北人蜡吧。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像占键,于是被迫代替她去往敵國和親昔善。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,611評論 2 353