这篇文章主要为大家详细介绍了Unity实现3D射箭小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
Unity 小游戏:3D射箭,供大家参考,具体内容如下
前两周因为实训太忙,再加上自己对老师所讲的设计模式并不是很理解,所以就没有写博客。这次博客是记录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 为 0
power = 0;
}
//拉弓,从power为0到power为3000
public 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 initialization
void 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射箭小游戏
基础教程推荐
- winform把Office转成PDF文件 2023-06-14
- C# 调用WebService的方法 2023-03-09
- 一个读写csv文件的C#类 2022-11-06
- linux – 如何在Debian Jessie中安装dotnet core sdk 2023-09-26
- C#类和结构详解 2023-05-30
- C#控制台实现飞行棋小游戏 2023-04-22
- ZooKeeper的安装及部署教程 2023-01-22
- C# windows语音识别与朗读实例 2023-04-27
- unity实现动态排行榜 2023-04-27
- C# List实现行转列的通用方案 2022-11-02