Unity3D学习之射箭小游戏
一、了解基礎(chǔ)知識
對于射箭小游戲來說,新增加了物理引擎的運(yùn)用。物理引擎主要包括三個方面: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組件,兩種方式:
當(dāng)然,第一種方法直接刪除,開銷較大,不推薦。
4.碰撞觸發(fā)事件的用法。is Trigle為true,在對象的腳本里調(diào)用函數(shù):
記住,千萬不用弄錯了函數(shù)名稱的大小寫。雖然不會報錯,但是,會失效的。
二、游戲設(shè)計及代碼
游戲設(shè)計圖:
游戲預(yù)設(shè)及效果:
具體的參數(shù),可以自己慢慢嘗試調(diào)整,這里就不一一列出了。
代碼設(shè)計實(shí)現(xiàn)
這部分,首先需要實(shí)現(xiàn)的是箭矢的發(fā)射:
其中,朝向通過鼠標(biāo)點(diǎn)擊屏幕,獲取射線的方向以作為弓箭方向:
if(Input.GetMouseButtonDown(0)) {Ray mouseRay = camera.ScreenPointToRay(Input.mousePosition);//獲取射線,以射線方向作為箭矢方向scene.shootArrow(mouseRay.direction);//點(diǎn)擊發(fā)射箭矢 } 接著,需要實(shí)現(xiàn)弓箭插在箭靶上,并且再一段時間時間后回收箭靶:
以上基本都實(shí)現(xiàn)了,那么射箭小游戲也就完成了。
另外,注意一下,下面語句中的name指的是什么:
附上完整代碼:
Singleton.cs
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);//點(diǎn)擊發(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{//獲取單實(shí)例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ù)*******************//實(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實(shí)現(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;}//*****************實(shí)現(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)//如果無可使用弓箭,實(shí)例化一個{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);//獲取隨機(jī)風(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)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微服务网关之Springcloud Ga
- 下一篇: CSC停止问题的解决