日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Unity3D学习之射箭小游戏

發(fā)布時間:2023/12/20 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Unity3D学习之射箭小游戏 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、了解基礎(chǔ)知識

  對于射箭小游戲來說,新增加了物理引擎的運用。物理引擎主要包括三個方面:Rigidbody、Collide、PhysicMaterial。其中,Collider是最基本的觸發(fā)物理的條件,例如碰撞檢測。基本上,沒有Collider物理系統(tǒng)基本沒有意義(除了重力);Rigidbody是物體的基本物理屬性設(shè)置,當(dāng)檢測碰撞完之后,就要計算物理效果,而Rigidbody就是提供計算基本參數(shù)的組件;PhysicMaterial則是附加的基本物理參數(shù),是一個物理材質(zhì),UNITY3D有自帶默認(rèn)的物理材質(zhì)的系數(shù)(在Edit/Project Settings/Physic下設(shè)置),它參與碰撞的計算例如反彈效果摩擦效果等。當(dāng)然,我們這個游戲用到的只有前兩個。
  要注意:

1.碰撞事件 = 大于等于一個剛體+兩個碰撞器+istrigle為true
2.兩個對象,一個具備剛體屬性+碰撞器,另一個只具備碰撞器,拿前者碰撞后者,is Trigle為true,那么則會發(fā)生碰撞。如果腳本控制的是位移而不是物理加力的方式的話,將穿透過去;直接碰撞,則會被彈開。
3、禁用或者停用Rigidbody組件,兩種方式:

//方法一: Destroy(GameObject.GetComponent<Rigidbody>()); //方法二: GameObject.GetComponent<Rigidbody>().Sleep();

當(dāng)然,第一種方法直接刪除,開銷較大,不推薦。
4.碰撞觸發(fā)事件的用法。is Trigle為true,在對象的腳本里調(diào)用函數(shù):

void OnTriggerEnter(Collider other);

記住,千萬不用弄錯了函數(shù)名稱的大小寫。雖然不會報錯,但是,會失效的。

二、游戲設(shè)計及代碼

  游戲設(shè)計圖:
  
  游戲預(yù)設(shè)及效果:
  
  
  
  具體的參數(shù),可以自己慢慢嘗試調(diào)整,這里就不一一列出了。
  代碼設(shè)計實現(xiàn)
  這部分,首先需要實現(xiàn)的是箭矢的發(fā)射:

public void shoot(GameObject arrow, Vector3 dir){arrow.transform.up = dir;//弓箭的朝向//Debug.Log("arrow_shoot");arrow.GetComponent<Rigidbody>().velocity = dir * speed;//設(shè)置箭矢速度//Debug.Log(arrow.GetComponent<Rigidbody>().velocity);force = Random.Range(-80f, 80f);//獲取隨機風(fēng)力Wind(arrow);//添加風(fēng)效果scene.setForce(force);//設(shè)置風(fēng)力if(force < 0){scene.setDirection(Direction.Left);//設(shè)置風(fēng)向}else if(force > 0){scene.setDirection(Direction.Right);}else{scene.setDirection(Direction.Nowind);}}private void Wind(GameObject arrow){Debug.Log("AddForce");arrow.GetComponent<Rigidbody>().AddForce(new Vector3(force, 0, 0), ForceMode.Force);//對箭矢施加恒定風(fēng)力}

  其中,朝向通過鼠標(biāo)點擊屏幕,獲取射線的方向以作為弓箭方向:

if(Input.GetMouseButtonDown(0)) {Ray mouseRay = camera.ScreenPointToRay(Input.mousePosition);//獲取射線,以射線方向作為箭矢方向scene.shootArrow(mouseRay.direction);//點擊發(fā)射箭矢 }

  接著,需要實現(xiàn)弓箭插在箭靶上,并且再一段時間時間后回收箭靶:
  

void OnTriggerEnter(Collider other)//觸發(fā)時間,取消箭矢剛體屬性 {if (bartNum == " "){bartNum = other.gameObject.name;GetComponent<Rigidbody>().Sleep();foreach (CapsuleCollider i in comp){i.enabled = false;}//使得箭矢不會觸發(fā)靶子上的箭GetComponent<MeshCollider>().isTrigger = false;judge.countPoint(bartNum);//記錄分?jǐn)?shù)} }//********************************void Update(){time += Time.deltaTime;if(time >= LIMITTIME){this.gameObject.SetActive(false);time = 0;bartNum = " ";}}

以上基本都實現(xiàn)了,那么射箭小游戲也就完成了。
另外,注意一下,下面語句中的name指的是什么:

bartNum = other.gameObject.name;

附上完整代碼:
Singleton.cs

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Singleton<T> : MonoBehaviour where T : MonoBehaviour {protected static T instance;public static T Instance{get{if (instance == null){instance = (T)FindObjectOfType(typeof(T));if (instance == null){Debug.LogError("An instance of" + typeof(T) +"is need in the scene, but there is none.");}}return instance;}} }

UserInterface.cs

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;public class UserInterface : MonoBehaviour {private IQuery query;private SceneController scene;public Camera camera;public Text Score;public Text WindForce;public Text WindDirection;void Start(){query = Singleton<SceneController>.Instance as IQuery;scene = Singleton<SceneController>.Instance;}void Update(){Score.text = "Score : " + query.getPoint();//顯示分?jǐn)?shù)WindForce.text = "Wind Force : " + query.getWindForce();//顯示風(fēng)力Direction dir = query.getWindDirection();//顯示風(fēng)向if(dir == Direction.Left){WindDirection.text = "Wind Direction : left";}else if(dir == Direction.Right){WindDirection.text = "Wind Direction : right";}else if(dir == Direction.Nowind){WindDirection.text = "Wind Direction : No wind";}if (Input.GetMouseButtonDown(0)){Ray mouseRay = camera.ScreenPointToRay(Input.mousePosition);//獲取射線,以射線方向作為箭矢方向scene.shootArrow(mouseRay.direction);//點擊發(fā)射箭矢}} }

SceneController.cs

using System.Collections; using System.Collections.Generic; using UnityEngine;/*** 用戶查詢接口* 查詢分?jǐn)?shù)* 查詢風(fēng)力* 查詢風(fēng)向* */ public interface IQuery {int getPoint();float getWindForce();Direction getWindDirection(); }public enum Direction { Left, Right, Nowind }; public class SceneController : MonoBehaviour, IQuery{//獲取單實例private ActionManager actionManager;//動作管理員private ArrowFactory arrowFactory;//弓箭管理工廠public int point;//分?jǐn)?shù)public float force;//風(fēng)力public Direction dir;//風(fēng)向private GameObject arrow;private GameObject bart;void Awake(){Director director = Director.getInstance();director.setFPS(60);director.scene = this;actionManager = Singleton<ActionManager>.Instance;arrowFactory = Singleton<ArrowFactory>.Instance;}//加載場景void Start(){loadScene();}//*******************類中其他函數(shù)*******************//實現(xiàn)射箭的動作public void shootArrow(Vector3 dir){arrow = arrowFactory.getArrow(); //獲得箭矢float x = Random.Range(-1f, 1f);float y = Random.Range(-1f, 1f);arrow.transform.position = new Vector3(x, y, 0); //設(shè)置箭矢初始位置 actionManager.shoot(arrow, dir);//調(diào)用ActionManager實現(xiàn)動作細(xì)節(jié)}//設(shè)置分?jǐn)?shù)public void setPoint(int _point){point = _point;}//設(shè)置風(fēng)力public void setForce(float _force){force = _force;}//設(shè)置風(fēng)向public void setDirection(Direction _dir){dir = _dir;}//*****************實現(xiàn)接口**************************//獲取分?jǐn)?shù)public int getPoint(){return point;}//獲取風(fēng)力public float getWindForce(){return force;}//獲取風(fēng)向public Direction getWindDirection(){return dir;}//*****************輔助函數(shù)**************************//加載箭靶void loadScene(){bart = Instantiate(Resources.Load("Gameobject/Gameobject")) as GameObject;} }

ArrowFactory.cs

using System.Collections; using System.Collections.Generic; using UnityEngine;public class ArrowFactory : MonoBehaviour {private List<GameObject> usedArrow; //儲存使用中的箭矢 private List<GameObject> freeArrow; //儲存空閑箭矢 private GameObject arrowPrefab;void Awake(){//arrowPrefab = Instantiate(Resources.Load("Arrows/Arrows")) as GameObject;//arrowPrefab.SetActive(false);freeArrow = new List<GameObject>();usedArrow = new List<GameObject>();//Debug.Log("ArrowFactory");}public GameObject getArrow(){GameObject obj;if (freeArrow.Count == 0)//如果無可使用弓箭,實例化一個{obj = GameObject.Instantiate(Resources.Load("Arrows/Arrows")) as GameObject;obj.SetActive(true);}else//否則,復(fù)用。且添加剛體屬性{obj = freeArrow[0];obj.SetActive(true);if (obj.GetComponent<Rigidbody>() == null)obj.AddComponent<Rigidbody>();Component[] comp = obj.GetComponentsInChildren<CapsuleCollider>();foreach (CapsuleCollider i in comp){i.enabled = true;}obj.GetComponent<MeshCollider>().isTrigger = true;freeArrow.RemoveAt(0);//空閑箭矢中有箭矢,初始化相關(guān)屬性,加入使用 }usedArrow.Add(obj);return obj;}private void FreeArrow(){for (int i = 0; i < usedArrow.Count; i++){GameObject temp = usedArrow[i];if (!temp.activeInHierarchy){usedArrow.RemoveAt(i);freeArrow.Add(temp);}}}void Update(){FreeArrow();} }

Judge.cs

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Judge : MonoBehaviour {private SceneController scene;void Awake(){scene = Singleton<SceneController>.Instance;}//判斷射中的靶并賦予相應(yīng)的分?jǐn)?shù)public void countPoint(string type){if(type == "Cylinder1"){scene.setPoint(scene.getPoint() + 10);}else if(type == "Cylinder2"){scene.setPoint(scene.getPoint() + 8);}else if(type == "Cylinder3"){scene.setPoint(scene.getPoint() + 6);}else if(type == "Cylinder4"){scene.setPoint(scene.getPoint() + 4);}else if(type == "Cylinder5"){scene.setPoint(scene.getPoint() + 2);}} }

ActionManager.cs

using System.Collections; using System.Collections.Generic; using UnityEngine;public class ActionManager : MonoBehaviour {private float speed = 30f;//箭矢的初速度private float force = 0f;//風(fēng)力初始值private SceneController scene;void Awake(){scene = Singleton<SceneController>.Instance;}public void shoot(GameObject arrow, Vector3 dir){arrow.transform.up = dir;//弓箭的朝向//Debug.Log("arrow_shoot");arrow.GetComponent<Rigidbody>().velocity = dir * speed;//設(shè)置箭矢速度//Debug.Log(arrow.GetComponent<Rigidbody>().velocity);force = Random.Range(-80f, 80f);//獲取隨機風(fēng)力Wind(arrow);//添加風(fēng)效果scene.setForce(force);//設(shè)置風(fēng)力if(force < 0){scene.setDirection(Direction.Left);//設(shè)置風(fēng)向}else if(force > 0){scene.setDirection(Direction.Right);}else{scene.setDirection(Direction.Nowind);}}private void Wind(GameObject arrow){Debug.Log("AddForce");arrow.GetComponent<Rigidbody>().AddForce(new Vector3(force, 0, 0), ForceMode.Force);//對箭矢施加恒定風(fēng)力} }

Director.cs

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Director : System.Object {private static Director _instance;public SceneController scene { get; set; }public static Director getInstance(){if(_instance == null){_instance = new Director();}return _instance;}public int getFPS(){return Application.targetFrameRate;}public void setFPS(int fps){Application.targetFrameRate = fps;} }

ArrowScipt.cs

using System.Collections; using System.Collections.Generic; using UnityEngine;public class ArrowScipt : MonoBehaviour {private string bartNum;private Judge judge;private float time;//計時器private static float LIMITTIME = 4;void OnTriggerEnter(Collider other)//觸發(fā)時間,取消箭矢剛體屬性{if (bartNum == " "){bartNum = other.gameObject.name;//Destroy(GetComponent<Rigidbody>());//使得箭矢停留在靶子上GetComponent<Rigidbody>().Sleep();/*Component[] comp = GetComponentsInChildren<CapsuleCollider>();foreach (CapsuleCollider i in comp){i.enabled = false;}*///使得箭矢不會觸發(fā)靶子上的箭GetComponent<MeshCollider>().isTrigger = false;judge.countPoint(bartNum);//記錄分?jǐn)?shù)}}void Awake(){time = 0;bartNum = " ";judge = Singleton<Judge>.Instance;}void Update(){time += Time.deltaTime;if(time >= LIMITTIME){this.gameObject.SetActive(false);time = 0;bartNum = " ";}} }

  學(xué)習(xí)了這么久,終于有空來寫篇博客,記錄下自己的學(xué)習(xí)過程,感覺也蠻開心的。

總結(jié)

以上是生活随笔為你收集整理的Unity3D学习之射箭小游戏的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。