射箭游戏

游戏视频<https://www.bilibili.com/video/av71160101/>
游戏工程文件https://github.com/JennySRH/3DGame/tree/master/ShootTarget
上下左右控制箭移动,空格键发射

靶对象

靶对象共有5环,由5个圆柱体组成,射中最中心的环得分5,射中最外层环得分为1。每个圆柱体都添加了mesh collider,勾选Convex,并且勾选了is Trigger作为触发器。



对于靶对象而言,它需要完成两种行为:

  1. 作为触发器,感知是否有箭射中其中的某一环。
  2. 作为model,包含每一环的分数。

Target上将挂载两个脚本,一个是TargetData,挂载到每一个环上,用来得到该环的分数;另一个是TargetTrigger,用来检测哪一个环被触发。

/* TargetData.cs */
public class TargetData : MonoBehaviour
{// 挂载到Target上的每一环,用来返回该环对应的分数。public int GetScore(){string name = this.gameObject.name;int score = 6 - (name[0] - '0');return score;}
}
/*TargetTrigger.cs*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class TargetTrigger : MonoBehaviour
{// 当有箭射中某一环后触发void OnTriggerEnter(Collider arrow_head){//得到箭身Transform arrow = arrow_head.gameObject.transform.parent;if (arrow == null){return;}if (arrow.tag == "Arrow"){arrow_head.gameObject.SetActive(false);//箭身速度为0arrow.GetComponent<Rigidbody>().velocity = new Vector3(0, 0, 0);arrow.GetComponent<Rigidbody>().isKinematic = true;arrow.tag = "Hit";// 分数控制器int score = this.gameObject.gameObject.GetComponent<TargetData>().GetScore();Singleton<ScoreController>.Instance.AddScore(score);//Debug.Log(score);}}}

然后将所有的圆柱体放到一个空物体上,做成预制。

每一个箭由headbody组成,head装有collider

箭挂载了JoyStick可以通过上下左右来控制方向,如果按下空格键将添加刚体Rigidbody,然后交由相应的动作控制器进行控制。

/*JoyStick.cs*/using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class JoyStick : MonoBehaviour
{public float speedX = 1.0F;public float speedY = 1.0F;bool flag = true;// Update is called once per framevoid Update(){// 只有在射出前能移动if(flag){float translationY = Input.GetAxis("Vertical") * speedY;float translationX = Input.GetAxis("Horizontal") * speedX;translationY *= Time.deltaTime;translationX *= Time.deltaTime;// 限制移动的范围if (transform.position.x - translationX < 1.5 && transform.position.x - translationX > -1.5&& transform.position.y + translationY > -0.8 && transform.position.y + translationY < 0.8){transform.position = transform.position + new Vector3(-translationX, translationY, 0);}if (Input.GetButton("Jump")){// 如果空格下,则给箭增加刚体,使其能够进行物理学的运动this.gameObject.AddComponent<Rigidbody>();this.gameObject.GetComponent<Rigidbody>().useGravity = false;flag = false;}}}
}

风是由一系列透明的触发器组成的。

触发器们挂载了WindTrigger用来检测是否有箭头触发,然后交由相应的动作控制器控制。

/*WindTrigger*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class WindTrigger : MonoBehaviour
{void OnTriggerEnter(Collider arrow_head){//得到箭身Transform arrow = arrow_head.gameObject.transform.parent;if (arrow == null){return;}if (arrow.tag == "Arrow"){arrow.GetComponent<CCAction>().Move();}}
}

风力大小和风向由WindController生成,挂载到全局的空物体上,使用单例模式获得。

/*WindController.sc*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class WindController : MonoBehaviour
{private float time = 5;private float strength = 0.5f;private Vector3 direction = new Vector3(0.01f,0,0);// Update is called once per framevoid Update(){if(time > 0){time -= Time.deltaTime;}else{time = 5;strength = UnityEngine.Random.Range(0.5f, 0.7f);direction = new Vector3(UnityEngine.Random.Range(-0.02f, 0.02f), UnityEngine.Random.Range(-0.02f, 0.02f), 0);}}public float GetStrength(){return strength;}public Vector3 GetDirection(){return direction;}
}

场景控制器——FirstSceneController

由于本次作业依旧沿用了之前的MVC框架,所以只展示重要部分代码。

FirstSceneController挂载到空物体上,用来加载第一个场景(一共也只有一个场景)。

/*FirstSceneController.cs*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class FirstSceneController : MonoBehaviour, ISceneController
{// 靶对象public GameObject target;// 箭队列public Queue<GameObject> arrowQueue = new Queue<GameObject>();// 当前正在操控的箭public GameObject arrow;// 风public GameObject wind;public void LoadSource(){// 清除记分Singleton<ScoreController>.Instance.ClearScore();// 靶对象初始化if (target != null){Destroy(target);}target = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>("Prefabs/Target"));if(arrow != null){Singleton<ArrowFactory>.Instance.FreeArrow(arrow);}// 箭队列初始化while (arrowQueue.Count > 0){Singleton<ArrowFactory>.Instance.FreeArrow(arrowQueue.Dequeue());}arrowQueue.Clear();// 初始化一个箭对象arrow = Singleton<ArrowFactory>.Instance.GetArrow();arrowQueue.Enqueue(arrow);}// Start is called before the first frame updatevoid Start(){this.gameObject.AddComponent<ArrowFactory>();this.gameObject.AddComponent<ScoreController>();this.gameObject.AddComponent<IGUI>();this.gameObject.AddComponent<WindController>();wind = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>("Prefabs/Wind"));// 设置第一个场景控制器为当前场景控制器Director.GetInstance().CurrentSceneController = this;Director.GetInstance().CurrentSceneController.LoadSource();}// Update is called once per framevoid Update(){if(arrow.tag == "WaveEnd"){arrow = Singleton<ArrowFactory>.Instance.GetArrow();arrowQueue.Enqueue(arrow);}}
}

运动学控制器——CCAction (颤抖效果)

CCAction挂载到每个Arrow上,用来负责Arrow射中靶对象后的抖动效果以及遇到风之后产生的偏移效果。

/*CCAction.cs*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class CCAction : MonoBehaviour, IAction
{private float time = 1;float radian = 0;float radius = 0.01f; Vector3 initPosition;public void Move(){Move(Singleton<WindController>.Instance.GetDirection(), Singleton<WindController>.Instance.GetStrength());}public void Move(Vector3 direction, float strength){this.transform.position += direction * strength;}// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){if(time > 0){if (this.gameObject.tag == "Hit"){time -= Time.deltaTime;// 弧度每次增加radian += 0.05f;// 颤抖float dy = Mathf.Cos(radian) * radius;transform.position = initPosition + new Vector3(0, dy, 0);}else{initPosition = transform.position;}}if(time <= 0){this.gameObject.tag = "WaveEnd";transform.position = initPosition;}}
}

动力学控制器——PhysicalAction

PhysicalAction也挂载到Arrow对象上,用来控制Arrow发射的运动效果。

/*PhysicalAction.cs*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class PhysicalAction : MonoBehaviour, IAction
{float force = 3;public void Move(){}public void Move(float force){this.force = force;}// Update is called once per framevoid Update(){// 如果没有射中靶对象if(this.gameObject.transform.position.z < -1){this.gameObject.tag = "WaveEnd";}}void FixedUpdate(){// 如果射中了靶对象if (this.gameObject.GetComponent<Rigidbody>() != null){this.gameObject.GetComponent<Rigidbody>().AddForce(new Vector3(0, 0, -1) * force);}}}

记分器——ScoreController

ScoreController也是使用单例模式,作为全局唯一来记录分数。

![demo](../ShootTarget/demo.gifusing System.Collections;
using System.Collections.Generic;
using UnityEngine;public class ScoreController : MonoBehaviour
{private int score;public void ClearScore(){score = 0;}public void AddScore(int score){this.score += score;}public int GetScore(){return this.score;}}

效果展示

改进打飞碟游戏

增加一个运动的接口类ActionManager,物理运动PhysicalAction和运动学变换CCAction都将实现该接口。

public interface IActionManager
{void Move(Vector3 direction, float speed);
}

CCAction

public class CCAction : MonoBehaviour, IActionManager
{public Vector3 direction;public float speed;public void Move(Vector3 direction,float speed){this.direction = direction;this.speed = speed;}// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){this.gameObject.transform.position += speed * direction * Time.deltaTime;}
}

对于PhysicalManager而言,Move函数是与其功能不匹配的,但是我们又不想丢弃这个CCActionActionManager,所以我们可以通过adapter模式,进行适配。

PhysicalManager

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class PhysicalManager : MonoBehaviour, IActionManager
{public float speed;public void Move(float speed){this.speed = speed;}public void Move(Vector3 direction, float speed){Move(speed);}void FixedUpdate(){Rigidbody rigid = this.gameObject.GetComponent<Rigidbody>();if(rigid){//Debug.Log(speed);rigid.AddForce(Vector3.down * speed);} }// Start is called before the first frame updatevoid Start(){this.gameObject.GetComponent<Rigidbody>().useGravity = false;}}

Unity学习——射箭游戏相关推荐

  1. Unity3D学习——射箭游戏(工厂模式)

    成品展示 每两秒会获得一个稳定风速,玩家可以把握住这个瞬间射箭,击中不同环得分不同,不击中不扣分,60s内够100分则获胜 游戏制作 脚本挂载与预制 箭靶子预制 在一个空对象上挂载五个扁平同心圆柱,设 ...

  2. Unity学习之游戏初步策划

    欢迎大家来到我的博客http://unity.gopedu.com/home.php?mod=space&uid=3352&do=blog&view=me&from=s ...

  3. 面向完全初学者的Unity和C#游戏开发学习教程

    了解如何通过使用Unity游戏引擎和C#制作BomberMan风格的3D游戏来制作您的第一款视频游戏 你会学到: 使用Unity 2021学习3D游戏开发 通过制作你的第一个3D游戏来学习C#编程语言 ...

  4. C#和Unity编码和游戏开发学习教程

    MP4 |视频:h264,1280×720 |音频:AAC,44.1 KHz,2 Ch 语言:英语+中英文字幕(根据原英文字幕机译更准确) |时长:110节课(26小时25分钟)|大小解压后:18.6 ...

  5. Unity优化手机游戏学习教程

    流派:电子学习| MP4 |视频:h264,1280×720 |音频:AAC,48.0 KHz 语言:英语+中英文字幕(根据原英文字幕机译更准确)|大小解压后:3.69 GB |时长:6h 44m 创 ...

  6. Unity学习笔记1 简易2D横版RPG游戏制作(一)

    这个教程是参考一个YouTube上面的教程做的,原作者的教程做得比较简单,我先参考着做一遍,毕竟我也只是个初学者,还没办法完全自制哈哈.不过我之前也看过一个2D平台游戏的系列教程了,以后会整合起来,做 ...

  7. [Unity 学习] Unity 入门学习及第一个游戏

    [Unity 学习] Unity 入门学习及第一个游戏 跟着教程做的一个小游戏,基本上说就算我这样的零基础,两个小时就能实现. 主要就是熟悉一下 C#和 Unity,做一个能跑的东西. 简单的 Dem ...

  8. 【贪玩巴斯】Unity3D初学圣经(一)——学习要求 Unity简单介绍 游戏引擎介绍 课程体系介绍 「1-1 到 1-4 」—— 2021年12月9日

    Unity3D初学圣经 一 --学习要求 & Unity简单介绍 & 游戏引擎介绍 & 课程体系介绍 本文对应视频P1 1-1 到P2 1-4 1.学习要求 2.Unity简单 ...

  9. Unity学习笔记—二次元日系游戏制作(实践篇-游戏初始化场景制作)

    原教程:siki:二次元日系游戏制作工具 - live2dSDK入门教程 http://www.sikiedu.com/my/course/282 (上)Unity学习笔记-二次元日系游戏制作(理论篇 ...

最新文章

  1. 物联网安全:LED灯中存在多个安全漏洞
  2. com学习笔记(6)类厂
  3. WPF MvvmLight简单实例(1) 页面导航
  4. 10亿美元卖身!腾讯IDG投资的无人车独角兽Zoox,被曝归入贝佐斯麾下
  5. golang install/build 生成的文件命名和路径
  6. linux下svn重新定位的方法
  7. 如何利用多核CPU提高虚拟现实性能?
  8. Java并发-Fork/Join框架
  9. block的用法以及block和delegate的比较(转发)
  10. Class Imbalance Problem
  11. error while loading shared libraries: xxx.so.x 错误的原因和解决办法
  12. tf.reshape()
  13. Chrome浏览其中,关闭窗口js无效.(window.close())
  14. spark配置IntelliJ开发环境详解
  15. Winform微信扫码支付
  16. HTML5前端基础知识
  17. 计算机网络和internet选项,详细教你电脑ie的internet选项在哪
  18. VC++ 在任务栏图标上显示进度条效果
  19. 淘宝如何做到懂你的推荐的?揭秘千人千面个性化推荐原理!
  20. firefly的RK3399AIOC开发板+海康工业相机抓图预览

热门文章

  1. 理光复印机扫描到windows共享文件夹操作步骤
  2. [BUAA OO Unit 3 HW12] 第三单元总结
  3. LeetCode短视频 | 最长有效括号使用栈很容易解决,但偏用动态规划
  4. 【LaTex】beamer中插入GIF动画
  5. python切片-截取-逆序截取
  6. 【PTA-A】1091 Acute Stroke (30 分)(BFS、队列)
  7. 【Linux】U盘安装Ubuntu 18.04之启动盘制作工具选择
  8. 鸿蒙充值卡是不是真的,手机充值卡怎么变现
  9. mysql UNION ALL查询分页
  10. 设置Windows 7锁屏背景图片