吃雞實戰之破片手榴彈
昨天玩吃雞,在決賽圈的時候扔手雷不小心把女神給炸死了,求生慾望使我下定決心要好好練手雷。
於是今天我花了些許時間寫了一個吃雞中手雷的實現項目,打算好好練習,在這裡也跟大家分享一下,主要是難點在於你是否把高中的物理知識還給老師而已.
項目是在前面的基礎上去拓展開發的,沒有項目的同學可以關注公眾號去拿.
在這裡先實現扔手雷的方法
首先在我們的Player下面創建一個球當作手雷.(別問為什麼不用模型,還不是窮跟沒時間)
然後把位置調好.
接下來給他添加一個剛體.這次手雷的實現我們用Unity的物理引擎來做就可以了.
幾個參數設置好,不然等下跟我們的軌跡會有偏差.
然後幫手雷搞一個腳本. 定義幾個變數.
弄完之後把腳本給他搞上去,把值都賦好,
然後,寫一個扔手雷的方法.
void AntitankGrenadeOut() { line.gameObject.SetActive(false); float _n = velocity / Time.fixedDeltaTime; float _angleY = Mathf.Deg2Rad * -player.localEulerAngles.x; float _angleX = Mathf.Deg2Rad * player.localEulerAngles.y; Vector3 _force = new Vector3(_n * Mathf.Cos(_angleY) * Mathf.Sin(_angleX), _n * Mathf.Sin(_angleY), _n * Mathf.Cos(_angleY) * Mathf.Cos(_angleX)); rig.AddForce(_force); rig.useGravity = true; this.transform.SetParent(null); StartCoroutine(Explosive()); }
Line就是我們的軌跡線的腳本,手雷扔出去的時候就把軌跡線去掉.
然後打開我們的高一物體課本!找到牛頓, 把他的牛頓力學公式抄下來
F*T = MV;
在這裡我們要求出他的F,
M是我們的剛體質量,剛剛設置了1那個,
V是我們的初速度velocity,
T就是我們物理刷新幀速率更新的時間Time.fixedDeltaTime,
由F=MV/T, 套入我們的參數就是得到的就是n了.
然後在去給他做垂直方向跟水平方向上力的分解.
同樣抄他老牛的公式
在這裡的隨手畫一張圖,看得懂最好,看不懂就去老牛的書里找一找吧,嘿嘿嘿.
如圖oc 跟面aob的夾角就是垂直夾角.
V垂直 = _n * Sin(垂直夾角), --在這裡要用到弧度,
V水平= _n * Cos(垂直夾角)
所以用Mathf.Deg2Rad * 夾角,就可以得到了垂直夾角弧度 _angleY;
(因為項目坐標系問題,我這裡的垂直方向是player的x角度,你們就找那個上下動的那個角就可以了)
然後再對我們的水平方向的力進行一個分解.因為我們是三維的.所以就是去水平方向的夾角
然後得到我們的水平夾角_angleX;
圖中AOD就是水平面的夾角.
(講的再簡單粗暴一點就是你那個攝像機,左右轉的角度就是水平夾角,上下晃的就是垂直夾角。)
最後把值套入公式算出力的三個方向的值就可以
Fx = _n * Mathf.Cos(_angleY) * Mathf.Sin(_angleX); //先算出水平面分到了力,再算出水平面上分量x的力.
Fy= _n * Mathf.Cos(_angleY);
Fz = _n * Mathf.Cos(_angleY) * Mathf.Cos(_angleX);
最後把力用一個三維向量_force存起來;
最後用剛體AddForce(_force),這個方法把算出來的力施加在剛體即可.
然後把重力打開.然後把手雷從他老豆身上拿出來, SetParent(null),
因為扔出去的手雷已經不會再跟著人物移動了.
然後打開他的引爆機制,開啟協程Explosive(),協程定義如下
IEnumerator Explosive() { yield return new WaitForSeconds(ExplosiveTime); transform.GetChild(0).gameObject.SetActive(true); yield return new WaitForSeconds(0.7f); transform.gameObject.SetActive(false); }
等待爆炸時間ExplosiveTime一到,把手雷下面的爆炸特效打開即可,特效播完把手雷隱藏起來.
然後接下來就來寫我們的軌跡線,
畢竟軌跡都沒有你扔個鳥哦.
創建一個obj,給他加上LineRenderer這個控制項.
大小跟顏色自己隨緣設置,建議大小弄小一點,不然他又粗又大。
弄完之後創建一個腳本.AntitankGrenade.搞幾個變數,
public Transform player; public Transform antitank; LineRenderer line; public int count; float g; float mVelocity;
Antitank是手雷。
Line是他身上那個線的控制項,
count是線的分段數量,設置越多分得越平滑.
g就是Unity裡面設置的重力,
mVelocity是我們的初速度.
把值賦好.
private void Awake() { line = GetComponent<LineRenderer>(); g = Mathf.Abs(Physics.gravity.y); }
接下來創建一個方法開啟我們的軌跡,
public void CallRendererLine(float _velocity) { mVelocity = _velocity; line.SetVertexCount(count + 1); line.SetPositions(CalculatePostion()); }
line.SetVertexCount()為設置線段數量
line.SetPositions()//為設置線段的位置.
CalculatePostion()為計算線段位置的方法,方法如下
Vector3[] CalculatePostion() { Vector3[] _array = new Vector3[count + 1]; float _radianAngle; _radianAngle = Mathf.Deg2Rad * -player.localEulerAngles.x; for(int i = 0; i <= count; i++) { float _t = (float)i / count; _array[i] = CalulatePoint(_t, _radianAngle); } return _array; }
_radianAngle就是我們剛剛說的夾角.
然後定義一個循環做一個插值效果,把我們的軌跡分為count+1段,然後通過CalulatePoint()方法去求出每段的位置,最後儲存在_array[]裡面返回出去。
CalulatePoint()方法如下
Vector3 CalulatePoint(float _t,float _radianAngle) { float _y = mVelocity * Mathf.Sin(_radianAngle) * _t - 1/2f * g * _t *_t; float _x = mVelocity * Mathf.Cos(_radianAngle) * _t * Mathf.Sin(player.localEulerAngles.y * Mathf.Deg2Rad); float _z = mVelocity * Mathf.Cos(_radianAngle) * _t * Mathf.Cos(player.localEulerAngles.y * Mathf.Deg2Rad); return (new Vector3(_x, _y, _z) + antitank.position); }
因為我們的手雷在軌跡上只受到一個重力影響.
所以水平方向是恆力.
求距離公式為 S垂直 = vt - 1/2gt*t;
S水平 =Vt,.
最後把這條軌跡加上手雷的坐標移到我們的手雷上面即可.
邏輯就是這樣了,
最後可以創建多一個物理材質,給我們的手雷,設置摩擦係數跟彈力係數,然它更加物理化一些。
最後回到我們第一個腳本.在Update()裡面監聽調用即可,
void Update () { if (Input.GetMouseButton(0)) { line.CallRendererLine(velocity); } if (Input.GetMouseButtonUp(0)) { AntitankGrenadeOut(); } }
最終的實現效果:
製作不易,如果覺得喜歡的話,給個讚唄~
關注公眾號:[代碼律動ColdingWave] 可獲得更多項目資源與視頻教學.
回復」手雷」即可獲取本次項目代碼。
回復」吃雞」可獲取前置項目,
回復」搖桿」可獲得搖桿項目
回復」倍鏡」可獲取之前倍鏡文章.
推薦閱讀:
※win10開機一直轉圈圈怎麼回事?
※從0到1學習電腦辦公技能系列教程
※4 · 視頻 |美拍,快手……為什麼說短視頻平台成了網紅經濟的造星工廠
※Scratch——讓編程像說母語一樣簡單
※如何在影視後期行業找一份體面的工作