Unity C# 2D弓箭效果_射箭(二)
- 此篇效果* * * * *
- 大概了解重點後,接下來進入完整教學 -
一、為了要讓玩家可以朝自己所想要的角度發射弓箭,所以我們對上一個章節"Pull String"程式碼做一點修改
1.我們在程式碼 「// 計算拉動的幅度」 區塊的下面新增兩行程式碼
//讓弓身隨滑鼠旋轉
float angleZ = Mathf.Atan2(mousePos.y, mousePos.x) * Mathf.Rad2Deg;
transform.eulerAngles = new Vector3(0, 0, angleZ);
2.為了要讓我們的弓弦可以跟著弓身旋轉,我們將Bow底下的 String物件的" Use World Space "取消勾選
3.接下來我們試著透過滑鼠旋轉弓箭,測試正常
二、旋轉弓身的功能完成之後,接著我們要做的是新增一隻箭矢在我們的弓身上
1.我們在Bow物件上新增一個 Sprite 叫做 Arrow,並設定一張箭矢圖片給Arrow(請使用自己的圖片資源0.0)
2.再來我們要修改一下程式碼"Pull String"中新增一個物件Arrow來帶入弓箭物件
//新增箭矢
public GameObject Arrow;
3. 繼續新增一個 folat參數 "arrowStartX"
public float arrowStartX;
3. 在"Start"中抓取箭矢起始位置
//存取弓箭起始X座標(用來計算弓箭被向後拉的距離)
arrowStartX = Arrow.transform.position.x;
4.在圖片位置補充下列程式碼,用來拉動弓箭的語法
//將箭矢向後拉動
Vector3 arrowPosition = Arrow.transform.localPosition;
arrowPosition.x = (arrowStartX - length);
Arrow.transform.localPosition = arrowPosition;
4.新增完畢後,我們就可以向後拖曳我們的箭矢囉!
三、既然已經完成箭矢拖曳了,那我們就只剩下射出箭矢了!一樣透過程式碼的修改就可以做到射箭效果
1.接下來我們新增一個叫做ShootArrow的函式,當這個函式被呼叫後,就會射出箭矢
//射箭函式
private void ShootArrow()
{
if (Arrow.GetComponent<Rigidbody>() == null)
{
// 給箭矢Rigidbod以便施加衝力
Arrow.AddComponent<Rigidbody>();
// 給箭矢朝旋轉角度施加衝力
Arrow.GetComponent<Rigidbody>().AddForce(Quaternion.Euler(new Vector3(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, transform.rotation.eulerAngles.z)) * new Vector3(25f * length, 0, 0), ForceMode.VelocityChange);
}
}
2.接下來我們要在玩家鬆開滑鼠按鈕後執行這個函式,所以我們在Input.GetMouseButtonUp(0)裡補充一行
//射出箭矢
ShootArrow();
3.這樣就大功告成了,下面是完整的程式碼:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PullString : MonoBehaviour {
// 宣告一條射線
private Ray mouseRay1;
//RaycastHit是用來儲存被射線所打到的位置
private RaycastHit rayHit;
//用來接收滑鼠點擊座標的X、Y值
public float posX, posY,length, arrowStartX;
//指向String子物件
public GameObject MyString;
//用來讀取MyString上的LineRender Component
private LineRenderer MyStringLine;
//新增箭矢
public GameObject Arrow;
public void Start()
{
//讀取弓弦的LineRender元件
MyStringLine = MyString.GetComponent<LineRenderer>();
//存取弓箭起始X座標
arrowStartX = Arrow.transform.position.x;
}
void Update()
{
//按住滑鼠左鍵開始進行拉弓功能
if (Input.GetMouseButton(0))
{
//呼叫拉弓功能
GetPos();
}
if (Input.GetMouseButtonUp(0))
{
//射出箭矢
ShootArrow();
//弓弦回彈
length = 0;
StringNodeChange();
}
}
//拉弓功能
private void GetPos()
{
// 設定射線的行徑方向(螢幕-滑鼠點擊位置)
mouseRay1 = Camera.main.ScreenPointToRay(Input.mousePosition);
//如果射線以MouseRay1方向前進(螢幕到滑鼠點擊座標),有打到colliedr就會執行大括弧裡的程式碼
if (Physics.Raycast(mouseRay1, out rayHit, 1000f))
{
//儲存滑鼠所點擊的座標
posX = rayHit.point.x;
posY = rayHit.point.y;
// 計算拉動的幅度
Vector2 mousePos = new Vector2(transform.position.x - posX, transform.position.y - posY);
length = mousePos.magnitude / 3f;
//讓弓身隨滑鼠旋轉
float angleZ = Mathf.Atan2(mousePos.y, mousePos.x) * Mathf.Rad2Deg;
transform.eulerAngles = new Vector3(0, 0, angleZ);
//拉動的幅度只會介於0與1之間
length = Mathf.Clamp(length, 0, 1);
//將箭矢向後拉動
Vector3 arrowPosition = Arrow.transform.localPosition;
arrowPosition.x = (arrowStartX - length);
Arrow.transform.localPosition = arrowPosition;
//呼叫弓弦變形功能
StringNodeChange();
}
}
//射箭函式
private void ShootArrow()
{
if (Arrow.GetComponent<Rigidbody>() == null)
{
Arrow.AddComponent<Rigidbody>();
// Arrow.transform.parent = gameManager.transform;
Arrow.GetComponent<Rigidbody>().AddForce(Quaternion.Euler(new Vector3(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, transform.rotation.eulerAngles.z)) * new Vector3(25f * length, 0, 0), ForceMode.VelocityChange);
}
}
//弓弦依照拖曳幅度length變形
private void StringNodeChange()
{
//改變LineRender中第2個點的座標藉此達到拉弓效果
MyStringLine.SetPosition(1, new Vector3(-0.4f+(length*-1),0,0));
}
}
四、接下來我們回到Unity編輯器中,將Arrow物件拖曳至Bow上"PullString"上的空欄位Arrow,按下執行就可以得到下面的效果!
五、不過現在還有美中不足的地方,那就是射出的箭矢,箭頭並不會隨著移動軌跡旋轉,為了解決這個問題我們還要再新增一段程式碼
1.新增一段名為"Arrow Rotate"的程式碼並新增下列內容:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ArrowRotate : MonoBehaviour {
void Update () {
if (transform.GetComponent<Rigidbody>() != null)
{
// 如果箭矢正再飛行
if (GetComponent<Rigidbody>().velocity != Vector3.zero)
{
// 取得箭矢作用向量
Vector3 vel = GetComponent<Rigidbody>().velocity;
// 計算向量角度
float angleZ = Mathf.Atan2(vel.y, vel.x) * Mathf.Rad2Deg;
float angleY = Mathf.Atan2(vel.z, vel.x) * Mathf.Rad2Deg;
// 改變箭矢角度
transform.eulerAngles = new Vector3(0, -angleY, angleZ);
}
}
}
}
2.接下來將"ArrowRotate"拖曳到Arrow物件上,大功告成!!!
五、到這一步射箭功能就製作完成囉!讓我們欣賞一下簡易2D射箭功能的效果吧!
六、最後我們加一點特效讓我們的射箭功能更有質感吧!
1.在Arrow物件身上新增一個空物件叫做"Tail",並設定其座標為(X=-1.2 , Y=0 , Z=0《設定在箭矢尾端》)
2.在Tail身上新增一個"Trail Render" Component
3.在"Trail Render"設定好Material(自行設定),將width設定為0.1,Time設定為1(Material 為拖曳光的材質,width則為拖曳光的寬度,Time則是拖曳光存在的持續時間)
4.設定完成後開發者可以自行調整顏色
5.調整完畢後就大功告成啦!!
-------------------------------------------------------------------------------------------------------------------------------------
我們有粉絲專頁囉!!!
如果怕有問題連絡不到我們,歡迎隨時私訊FB粉專哦!!!
https://www.facebook.com/Straying2018/
● 如果這篇文章有幫助到您,希望您能留言給予我們鼓勵 !
● 對於文章有任何的建議,非常歡迎留言告訴我們哦 !!!
● 有任何想知道的功能也歡迎告訴我們,我們會盡快寫成部落格分享給大家!
-Alex-