第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > Unity 小游戏:3D射箭

Unity 小游戏:3D射箭

时间:2021-02-19 08:43:00

相关推荐

Unity 小游戏:3D射箭

Unity 小游戏:3D射箭

前两周因为实训太忙,再加上自己对老师所讲的设计模式并不是很理解,所以就没有写博客。这次博客是记录3D射箭游戏的实现过程。

Unity 小游戏3D射箭准备资源布置场景编辑脚本

1. 准备资源

我是在网上找的弓与箭的资源,至于靶子,创建五个不同大小的同心圆柱体,如图所示,

需要注意的是,五个圆柱体并不在同一个平面上,这样才能够看清每一环的颜色,并且在检测碰撞时不会出现各种问题。

另外,如果靶子放得离相机太近,就没有射箭的感觉了;离相机太远,好像又看不清靶子了,然后我试着把靶子MaterialShader改为 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); //记录分数}}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。