Unity 小游戏:3D射箭
Unity 小游戲:3D射箭
前兩周因為實訓太忙,再加上自己對老師所講的設計模式并不是很理解,所以就沒有寫博客。這次博客是記錄3D射箭游戲的實現過程。
- Unity 小游戲3D射箭- 準備資源
- 布置場景
- 編輯腳本
 
1. 準備資源
我是在網上找的弓與箭的資源,至于靶子,創建五個不同大小的同心圓柱體,如圖所示,  
 需要注意的是,五個圓柱體并不在同一個平面上,這樣才能夠看清每一環的顏色,并且在檢測碰撞時不會出現各種問題。
另外,如果靶子放得離相機太近,就沒有射箭的感覺了;離相機太遠,好像又看不清靶子了,然后我試著把靶子Material的Shader改為 Sprites/Default ,這樣靶子離相機遠一點也能看得很清晰。
2. 布置場景
把弓箭作為Main Camera的子物體,這樣我們可以在用鼠標控制鏡頭移動時,使弓箭一直指向屏幕中心,以達到第一人稱控制器的效果。 
  
 在此項目中,沒有選擇使用GUI來做UI界面,而是創建了一個Canvas,在這里面添加了一個Image用來顯示弓箭的準心,以及四個Text來顯示得分、風向、風力、提示等。 
 
3. 編輯腳本
游戲采用MVC架構,大部分功能是自己實現的,也有一小些函數是借鑒大神的。整體上感覺有很多缺陷,但是又不知道怎么修改才好,我也很無奈啊!°(°ˊДˋ°) °
下面是我的UML圖: 
 
以下是完整代碼:
SSDirector.cs
using System.Collections; using System.Collections.Generic; using UnityEngine;public class SSDirector : System.Object {private static SSDirector _instance;public ISceneCotroller currentScenceCotroller {get;set;}public bool running {get;set;}public static SSDirector getInstance() {if (_instance == null) {_instance = new SSDirector ();}return _instance;} }ISceneCotroller.cs
using System.Collections; using System.Collections.Generic; using UnityEngine;public interface ISceneCotroller {void LoadResources (); }IUserAction.cs
using System.Collections; using System.Collections.Generic; using UnityEngine;public interface IUserAction {string getMyScore ();float getWind ();void Openbow ();void Draw ();void Shoot (); }ActionManager.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ActionManager : MonoBehaviour {private float Force = 0f;private int maxPower = 2500;private float power;public Transform arrowSpawn;public Transform myArrow;public Transform bow;//播放拉弓動畫public void Openbow () {bow.GetComponent<Animation>().Play("Draw");bow.GetComponent<Animation>()["Draw"].speed = 1;bow.GetComponent<Animation>()["Draw"].wrapMode = WrapMode.Once;arrowSpawn.GetComponent<MeshRenderer>().enabled = true;//重置 power 為 0power = 0;}//拉弓,從power為0到power為3000public void Draw () {if(power < maxPower) {power += maxPower * Time.deltaTime;}}//射箭public void Shoot () {float percent = bow.GetComponent<Animation>()["Draw"].time / bow.GetComponent<Animation>()["Draw"].length;float shootTime = 1 * percent;bow.GetComponent<Animation>().Play("Shoot");bow.GetComponent<Animation>()["Shoot"].speed = 1;bow.GetComponent<Animation>()["Shoot"].time = shootTime;bow.GetComponent<Animation>()["Shoot"].wrapMode = WrapMode.Once;arrowSpawn.GetComponent<MeshRenderer>().enabled = false;Transform arrow= Instantiate (myArrow, arrowSpawn.transform.position, transform.rotation);arrow.transform.GetComponent<Rigidbody>().AddForce(transform.forward * power);wind (arrow);Force = Random.Range (-100, 100);}//產生風private void wind(Transform arrow) {arrow.transform.GetComponent<Rigidbody> ().AddForce (new Vector3 (Force, 0, 0), ForceMode.Force);}//返回風public float getWindForce() {return Force;} }ScoreRecorder.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ScoreRecorder : MonoBehaviour {private string Score = "0";//判斷得分public void countScore(string type) {Score = type;}//返回分數public string getScore () {return Score;} }FirstScene.cs
using System.Collections; using System.Collections.Generic; using UnityEngine;public class FirstScene : MonoBehaviour, ISceneCotroller, IUserAction {private ActionManager actionManager;private ScoreRecorder scoreRecorder;void Awake () {SSDirector director = SSDirector.getInstance ();director.currentScenceCotroller = this;director.currentScenceCotroller.LoadResources ();actionManager = (ActionManager)FindObjectOfType (typeof(ActionManager));scoreRecorder = (ScoreRecorder)FindObjectOfType (typeof(ScoreRecorder));}//加載預制物體靶子public void LoadResources () {Debug.Log ("loading...\n");GameObject target = Instantiate<GameObject> (Resources.Load<GameObject> ("Prefabs/target"));target.name = "target";}//獲得分數public string getMyScore () {return scoreRecorder.getScore ();}//獲得風向和風力public float getWind () {return actionManager.getWindForce ();}//拉弓public void Openbow () {actionManager.Openbow ();}//蓄力public void Draw () {actionManager.Draw ();}//射箭public void Shoot () {actionManager.Shoot ();} }UserGUI.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;public class UserGUI : MonoBehaviour {private IUserAction userAction;private FirstScene scene;private Quaternion m_CharacterTargetRot;public Text Score;public Text WindDirection;public Text WindForce;// Use this for initializationvoid Start () {userAction = SSDirector.getInstance ().currentScenceCotroller as IUserAction;}void Awake () {m_CharacterTargetRot = transform.localRotation;}void Update () {//鏡頭跟隨鼠標float xRot = Input.GetAxis ("Mouse X") * 3f;float yRot = Input.GetAxis ("Mouse Y") * -3f;m_CharacterTargetRot *= Quaternion.Euler (yRot, xRot, 0f);transform.localRotation = Quaternion.Slerp (transform.localRotation, m_CharacterTargetRot,5f * Time.deltaTime);//按空格鍵使弓箭瞄準靶心if (Input.GetKeyDown (KeyCode.Space)) {m_CharacterTargetRot = Quaternion.Euler (0f, 0f, 0f);transform.localRotation = Quaternion.Slerp (transform.localRotation, m_CharacterTargetRot,5f * Time.deltaTime);}//鼠標左鍵按下,開始拉弓if (Input.GetMouseButtonDown (0)) {userAction.Openbow ();}//鼠標左鍵按住不放,蓄力if (Input.GetMouseButton (0)) {userAction.Draw ();}//鼠標左鍵抬起。射箭if (Input.GetMouseButtonUp (0)) {userAction.Shoot ();}Score.text = "Score : " + userAction.getMyScore (); //顯示上一輪分數float force = userAction.getWind ();if (force < 0) {WindDirection.text = "Wind Direction : <---"; //顯示風向} else if (force > 0) {WindDirection.text = "Wind Direction : --->";} else {WindDirection.text = "Wind Direction : No";}WindForce.text = "Wind Force : " + Mathf.Abs (userAction.getWind ()); //顯示風力} }Arrow.cs
using UnityEngine; using System.Collections;public class Arrow : MonoBehaviour {private RaycastHit hit;void Update (){//檢測在移動的箭if(GetComponent<Rigidbody>().velocity.magnitude > 0.5f) {CheckForHit();} else {enabled = false;}if (transform.position.y < -5) {Destroy (this.gameObject); //將掉出地面以下的箭銷毀}}//檢測是否碰撞void CheckForHit (){float myVelocity = GetComponent<Rigidbody>().velocity.magnitude;float raycastLength = myVelocity * 0.03f;if(Physics.Raycast(transform.position, transform.forward, out hit, raycastLength)) {GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezeAll; //使箭停留在靶子上transform.position = hit.point;transform.parent = hit.transform;enabled = false;} else {Quaternion newRot = transform.rotation;newRot.SetLookRotation(GetComponent<Rigidbody>().velocity);transform.rotation = newRot; //箭沒中靶,則繼續做拋物線運動}} }Target.cs
using System.Collections; using System.Collections.Generic; using UnityEngine;public class Target : MonoBehaviour {private ScoreRecorder scoreRecorder;public string score; //對應靶環的分數public void Start() {scoreRecorder = (ScoreRecorder)FindObjectOfType (typeof(ScoreRecorder));}void OnTriggerEnter(Collider other) {if (other.gameObject.tag == "Arrow") {scoreRecorder.countScore (score); //記錄分數}} }總結
以上是生活随笔為你收集整理的Unity 小游戏:3D射箭的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: java fri星期转_如何在Java中
- 下一篇: python实现Instagram网络爬
