简单的(第一人称射击)FPS游戏
2017-07-07 20:30
281 查看
本篇文章基于上一篇文章: 使用unity3d搭建简单的场景以及第一人称角色的控制
1、给角色添加射击功能
通过射线射击,新建RayShooter.cs脚本,将该脚本添加到角色所包含的摄像机对象上,编辑代码。代码如下:using System.Collections; using System.Collections.Generic; using UnityEngine; public class RayShooter : MonoBehaviour { private Camera _camera; // Use this for initialization void Start () { _camera = GetComponent<Camera>(); //访问相同对象上附加的其他组件 Cursor.lockState = CursorLockMode.Locked; Cursor.visible = false; //隐藏屏幕中心的光标 } void OnGUI() { int size = 12; float posX = _camera.pixelWidth / 2 - size / 4; float posY = _camera.pixelHeight / 2 - size / 2; GUI.Label(new Rect(posX, posY, size, size), "*"); //GUI.Label()在屏幕上显示文本 } // Update is called once per frame void Update () { if (Input.GetMouseButtonDown(0)) //响应鼠标按键 { Vector3 point = new Vector3(_camera.pixelWidth / 2, _camera.pixelHeight / 2, 0); //屏幕中心是宽高的一半 Ray ray = _camera.ScreenPointToRay(point); //使用ScreenPointToRay()在摄像机所在位置创建射线 RaycastHit hit; if(Physics.Raycast(ray, out hit)) //Raycast给引用的变量填充信息 { GameObject hitObject = hit.transform.gameObject; ReactiveTarget target = hitObject.GetComponent<ReactiveTarget>(); if(target != null) { target.ReactToHit(); } else { StartCoroutine(SphereIndicator(hit.point)); //运行协程来响应击中 } } } } private IEnumerator SphereIndicator(Vector3 pos) //协程使用IEnumerator方法 { GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); sphere.transform.position = pos; yield return new WaitForSeconds(1); //yield关键字告诉协程在何处暂停 Destroy(sphere); //移除GameObject并清除它占用的内存 } }
二、响应被击中
创建敌人预设,并新建响应被击中的脚本ReactiveTarget.cs,将改脚本组件添加到预设中,编辑脚本,代码如下:using System.Collections; using System.Collections.Generic; using UnityEngine; public class ReactiveTarget : MonoBehaviour { public void ReactToHit() { WanderingAI behavior = GetComponent<WanderingAI>(); if(behavior != null) //检查角色是否有WanderingAI脚本 { behavior.SetAlive(false); } StartCoroutine(Die()); //通过射击脚本调用的方法 } private IEnumerator Die() { this.transform.Rotate(-75, 0, 0); //推到命中物体,等待1.5秒后摧毁命中物体 yield return new WaitForSeconds(0.5f); Destroy(this.gameObject); //对象能销毁自己,就像一个分开独立的对象 } // Use this for initialization void Start () { } // Update is called once per frame void Update () { } }
三、让敌人走动起来
新建WanderingAI.cs脚本,添加该脚本组件到敌人对象中。代码如下:using System.Collections; using System.Collections.Generic; using UnityEngine; public class WanderingAI : MonoBehaviour { public float speed = 3.0f; //移动速度的值 public float obstacleRange = 5.0f; //对墙壁做出反应的值 private bool _alive; //用于跟踪敌人是否存活 [SerializeField] private GameObject fireballPrefab; private GameObject _fireball; // Use this for initialization void Start () { _alive = true; //初始化值 } // Update is called once per frame void Update () { if (_alive) //只有当角色存活时才移动 { transform.Translate(0, 0, speed * Time.deltaTime); //每帧持续向前移动,不管旋转 Ray ray = new Ray(transform.position, transform.forward); //和角色相同位置的射线,并且方向相同 RaycastHit hit; if (Physics.SphereCast(ray, 0.75f, out hit)) //使用沿着射线的长度发射射线 { GameObject hitObject = hit.transform.gameObject; if(hitObject.GetComponent<PlayerCharacter>()) { if(_fireball == null) { _fireball = Instantiate(fireballPrefab) as GameObject; _fireball.transform.position = transform.TransformPoint(Vector3.forward * 1.5f); _fireball.transform.rotation = transform.rotation; } } else if (hit.distance < obstacleRange) { float angle = Random.Range(-110, 110); //转向一个半随机的新方向 transform.Rotate(0, angle, 0); } } } } public void SetAlive(bool alive) //公有方法允许外部代码影响alive的值 { _alive = alive; } }
四、自动生成敌人
创建一个空对象,新建一个SceneController.cs脚本用于实例化敌人预设,并添加到空对象中。代码如下:using System.Collections; using System.Collections.Generic; using UnityEngine; public class SceneController : MonoBehaviour { [SerializeField] private GameObject enemyPrefab; //序列化变量,用于链接预设对象 private GameObject _enemy; //一个私有变量,跟踪场景中敌人的实例 // Use this for initialization void Start () { } // Update is called once per frame void Update () { if(_enemy == null) //只用当场景中没有敌人时才产生一个新敌人 { _enemy = Instantiate(enemyPrefab) as GameObject; //这个方法复制了预设对象 _enemy.transform.position = new Vector3(0, 1, 1); float angle = Random.Range(0, 360); _enemy.transform.Rotate(0, angle, 0); } } }
五、让敌人主动发起攻击,角色响应攻击
创建制单预设,新建Fireball.cs脚本,用于敌人发起攻击,新建PlayerCharacter.cs脚本,用于角色响应攻击。代码如下:using System.Collections; using System.Collections.Generic; using UnityEngine; a7c9 public class Fireball : MonoBehaviour { public float speed = 10.0f; public int damage = 1; // Use this for initialization void Start () { } // Update is called once per frame void Update () { transform.Translate(0, 0, speed * Time.deltaTime); } void OnTriggerEnter(Collider other) { PlayerCharacter player = other.GetComponent<PlayerCharacter>(); if(player != null) { player.Hurt(damage); } Destroy(this.gameObject); } }
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerCharacter : MonoBehaviour { private int _health; // Use this for initialization void Start () { _health = 5; } public void Hurt(int damage) { _health -= damage; Debug.Log("Health: " + _health); } // Update is called once per frame void Update () { } }
相关文章推荐
- Raycast算法实现简单fps游戏场景,有趣
- J2EE技术简单介绍
- 不使用ATL向导,创建一个简单的ATL对话框程序.
- MySql实现简单的注册登录(易语言)
- PHP面向对象的使用教程 简单数据库连接
- 网页设计之5种简单的XHTML网页表单
- Dephi 程序输入法自动切换最简单最好用的实现方法(被程序员杂志采纳,重新详细整理)
- 一个简单的计数器程序
- 一个简单的投票程序
- 初学者看过来:简单谈谈 C/C++ 递归的思想,实现,以及和循环的关系。
- 教学项目之-通过Python实现简单的计算器
- 简单的留言板,解决了长英文字符的问题哦,不过汉字又出问题了:)希望大家一起来解决
- 邮件客户端程序的简单开发
- 在 VB 中简单使用 HTMLHELP (*.chm) 帮助
- 简单的Winsock例程
- JBuilder下调试java程序最简单的例子
- 用pascal写的最简单的winsock程序
- 一个简单的Proxy代理服务器的源代码!
- 简单模板概念
- 关于fvwm2的简单配置