【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇1(附项目源码)

news2024/11/25 3:00:22

文章目录

  • 本节最终效果
  • 前言
  • 搭建环境
  • 玩家移动控制
  • 摄像机跟随和视角
  • 人物奔跑
  • 实现跳跃
  • 斜坡顿挫感
  • 人物卡墙问题
  • 源码
  • 完结

本节最终效果

在这里插入图片描述

前言

生存和射击游戏一直是我的最爱,说起3D最普遍的应该就是射击系统了,你可以在任何情况下加入射击功能,所以我写下了这篇FPS开发记录。希望对你有帮助。

在这个项目中,你将学习如何设计和实现射击系统、武器系统、玩家控制、场景设计等方面的内容。通过这个项目,你将深入了解游戏开发中的许多核心概念和技术,并且在实践中不断提升自己。

本项目将带你从零开始逐步实现一个完整的第一人称射击游戏,并且会逐步引入一些高级功能,如特效、声音等。无论你是新手还是有经验的开发者,这个项目都将为你提供有价值的经验和知识,帮助你迈出游戏开发的第一步或者进一步提升技能。

在这个系列中,我们将探索如何创建一个引人入胜的游戏体验,同时注重代码的模块化和可扩展性。我将引导你逐步完成每个环节,同时提供必要的代码示例和解释,以便让你更好地理解游戏开发的方方面面。

无论你是想要探索游戏开发的奥秘,还是寻求提升自己的技能,这个项目都将是一个绝佳的起点。让我们一起开始这个激动人心的游戏开发之旅吧!

注意,本篇只是基础篇,所以我都会选择使用最简单的方式实现。基础篇不会有太多复杂的内容,后续看情况我会考虑出更加复杂全面的第一人称或者第三人称射击游戏,甚至多人联机功能,可以期待一下。

本节就先实现基本的第一人称角色控制。

搭建环境

为了让场景更生动,我选择第一件事是搭建一个好看的环境

这里我找了个地图素材,你也可以选择用自己喜欢的:
https://sketchfab.com/3d-models/de-dust2-cs-map-056008d59eb849a29c0ab6884c0c3d87
在这里插入图片描述
效果
在这里插入图片描述

玩家移动控制

这里我选择使用Character Controller控制玩家移动,方便快捷。
Character Controller介绍:https://docs.unity.cn/cn/2021.3/Manual/class-CharacterController.html

其实实现玩家的控制方法有很多,想了解更多的可以看我之前的介绍:
零基础带你从小白到超神16——四种方法控制人物移动之角色控制器

我们新增一个胶囊体,指代玩家,在玩家新增Character Controller组件,先保持默认参数配置即可,后面有需要我们再来调
在这里插入图片描述
新增PlayerController

private CharacterController characterController; // 角色控制器
public float speed;
public Vector3 moveDirection; // 移动方向

private void Start()
{
    characterController = GetComponent<CharacterController>();
}

private void Update()
{
	Move();
}

// 移动
public void Move()
{
    float h = Input.GetAxis("Horizontal"); // 获取水平输入
    float v = Input.GetAxis("Vertical"); // 获取垂直输入
    isRun = Input.GetKey(KeyCode.LeftShift);
    speed = isRun ? runSpeed : walkSpeed;

    moveDirection = transform.right * h + transform.forward * v; // 计算移动方向
    moveDirection = moveDirection.normalized; // 归一化移动方向,避免斜向移动速度过快

    characterController.Move(moveDirection * speed * Time.deltaTime); // 移动角色控制器
}

效果
在这里插入图片描述

摄像机跟随和视角

拖入摄像机为玩家的子集即可
在这里插入图片描述
控制摄像机视角,我们可以通过控制摄像机x轴实现人物上下看,玩家旋转左右看
在这里插入图片描述
新增MouseLook,挂载在摄像机,控制摄像机的旋转

public class MouseLook : MonoBehaviour
{
    // 鼠标灵敏度
    public float mouseSensitivity = 1000f;

    // 玩家的身体Transform组件,用于旋转
    public Transform playerBody;

    // x轴的旋转角度
    float xRotation = 0f;

    // Update在每一帧调用
    void Update()
    {
        // 执行自由视角查看功能
        FreeLook();
    }

    // 自由视角查看功能的实现
    void FreeLook()
    {
        // 获取鼠标X轴和Y轴的移动量,乘以灵敏度和时间,得到平滑的移动速率
        float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
        float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;

        // 累计x轴上的旋转量
        xRotation -= mouseY;

        // 应用摄像头的x轴旋转
        transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);

        // 应用玩家身体的y轴旋转
        playerBody.Rotate(Vector3.up * mouseX);
    }
}

效果
在这里插入图片描述
限制相机上下旋转角度

//限制旋转角度在-90到90度之间,防止过度翻转
xRotation = Mathf.Clamp(xRotation, -90f, 90f);

隐藏鼠标光标

void Start()
{
    // 锁定光标到屏幕中心,并隐藏光标
    Cursor.lockState = CursorLockMode.Locked;
}

效果
在这里插入图片描述

人物奔跑

public float walkSpeed = 10f; // 移动速度
public float runSpeed = 15f; // 奔跑速度
public float speed;
public bool isRun;//是否在奔跑

// 移动
public void Move()
{
    //。。。
    
    isRun = Input.GetKey(KeyCode.LeftShift);
    speed = isRun ? runSpeed : walkSpeed;

    //。。。
}

效果
在这里插入图片描述

实现跳跃

前面我们使用move控制角色移动,是不带重力的,所以我们需要实现自己定义重力效果,并进行地面检测,常规的地面检测肯定是在角色脚底生成一个检测区域,但是好在CharacterController 已经为我们提供了地面检测方法.isGrounded,直接调用就行,注意:isGrounded解释是在上一步移动中控制器是否触地,也就是说只有人物调用了Move才会进行地面检测

private bool isGround; // 判断是否在地面上
public float jumpForce = 3f; // 跳跃力度
public Vector3 velocity; // 设置玩家Y轴的一个冲量变化(力)
public float gravity = -50f; // 设置重力
private bool isJump; // 判断是否在跳跃

private void Update()
{
     isGround = characterController.isGrounded; // 判断是否在地面上
     if(!isGround) velocity.y += gravity * Time.deltaTime; // 根据重力计算Y轴的速度变化
     
     Move();
     Jump();
}
    
// 跳跃
public void Jump()
{
    isJump = Input.GetKeyDown(KeyCode.Space); // 检测是否按下跳跃键

    if (isJump && isGround)
    {
        velocity.y = Mathf.Sqrt(jumpForce * -2f * gravity); // 根据跳跃力度和重力计算跳跃速度
    }
    characterController.Move(velocity * Time.deltaTime);
}

效果
在这里插入图片描述

斜坡顿挫感

你的人物在下斜坡时可能会出现一个问题,人物下坡出现抖动(当然我这里没有出现,但是我这里也顺带说一下),具体的处理思路就是当我们判断在斜面时,给人物一个向下的压力,让人物没那么容易离地,而判断在斜面的方法就从人物向下打一条射线,判断射线和地面的法线如果非90度就是在斜面了

[SerializeField] private float slopeForce = 6.0f;//走斜坡时施加的力度
 [SerializeField] private float slopeForceRayLength = 2.0f;//斜坡射线长度(自定义量)
 
private void Update()
{
    //如果处于斜坡移动
     if (OnSlope())
     {
         //向下增加力
         moveDirection.y = characterController.height / 2 * slopeForceRayLength; 
         characterController.Move(Vector3.down * characterController.height / 2 * slopeForce * Time.deltaTime);
     }
}

//判断是否在斜面
public bool OnSlope()
{
	// 如果正在跳跃,则不考虑斜坡
    if (isJump) return false;

    RaycastHit hit;
    Debug.DrawRay(transform.position, Vector3.down * characterController.height / 2 * slopeForceRayLength, Color.red);
    // 向下打出射线(检测是否在斜坡上)
    if (Physics.Raycast(transform.position, Vector3.down, out hit, characterController.height / 2 * slopeForceRayLength))
    {
        // 如果接触到的点的法线,不在(0,1,0)的方向上,那么人物就在斜坡上
        if (hit.normal != Vector3.up)
            return true;
    }
    return false;
}

效果
在这里插入图片描述

人物卡墙问题

如果不做任何处理,碰撞器之间是存在摩擦力的,当你的人物靠近墙面移动是,会发现人物很难移动或者被卡住,我们需要新增一个物理材质,将摩檫力设置为0
在这里插入图片描述
在这里插入图片描述
然后赋值给玩家
在这里插入图片描述

源码

源码在最后一节

完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,以便我第一时间收到反馈,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇,https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,出于兴趣爱好,于是最近才开始自习unity。如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我可能也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1288871.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LoadRunner12.55的简介与安装

提示&#xff1a;https://mp.weixin.qq.com/s/iK-fh0VP7v8mNSDNxjkBow 文章目录 LoadRunner的简介与安装loadrunner概述loadrunner的下载与安装 LoadRunner的使用启用VuGen LoadRunner的简介与安装 LoadRunner官网&#xff1a;https://www.microfocus.com/zh-cn/products/load…

Vue学习计划-Vue2--Vue组件(一)认识组件

1.0 引入组件 传统方式编写应用 使用组件方式编写应用 1.1 模块 理解&#xff1a;向外提供特定的js程序&#xff0c;一般就是一个js文件为什么&#xff1a;js文件很多很复杂作用&#xff1a;复用js,简化js的编写&#xff0c;提高js运行效率 1.2 组件认识 理解&#xff1a; …

ElementPlus table 中嵌套 input 输入框

文章目录 需求分析 需求 vue3 项目中 使用UI组件库 ElementPlus 时&#xff0c;table 中嵌入 input输入框 分析 <template><div class"p-10"><el-table :data"tableData" border><el-table-column prop"date" label&qu…

docker镜像与容器的基本操作,容器打包以及镜像迁移

docker镜像拉取---docker pull docker pull image_name[:tag] 这是直接拉取官方镜像 image_name: 镜像的名称&#xff0c;例如 ubuntu, nginx, mysql 等。tag: 镜像的标签&#xff0c;表示版本或者特定的标识。如果未指定标签&#xff0c;默认为 latest。 例如&#xff0c;…

计算机速成课Crash Course - 08. 指令和程序

今天开始计算机速成课Crash Course的系列讲解。 更多技术文章&#xff0c;全网首发公众号 “摸鱼IT” 锁定 -上午11点 - &#xff0c;感谢大家关注、转发、点赞&#xff01; 计算机速成课Crash Course - 08. 指令和程序 08. 指令和程序 上集我们把 ALU, 控制单元, RAM, 时钟…

无需公网IP实现公网远程访问本地WebDAV服务

windows搭建WebDAV服务&#xff0c;并内网穿透公网访问【无公网IP】 文章目录 windows搭建WebDAV服务&#xff0c;并内网穿透公网访问【无公网IP】1. 安装IIS必要WebDav组件2. 客户端测试3. cpolar内网穿透3.1 打开Web-UI管理界面3.2 创建隧道3.3 查看在线隧道列表3.4 浏览器访…

威胁态势 | 0day占比超85%!两大勒索家族“均分天下”

近日&#xff0c;亚信安全正式发布《亚信安全2023年11月威胁态势报告》&#xff08;以下简称“报告”&#xff09;&#xff0c;报告显示&#xff0c;11月份新增安全漏洞778个&#xff0c; APT组织在国内外活动仍然呈上升趋势&#xff0c;多个国家政府、企业和科研单位遭受攻击&…

Linux之进程(一)

目录 一、概念 1、基本概念 2、描述进程的PCB 3、task_struct 二、查看进程 三、获取进程的PID和PPID 通过系统调用获取进程的PID和PPID 四、通过系统调用创建进程 1、fork函数创建子进程 2、用if进行分流 五、进程状态 1、操作系统进程状态 1、新建 2、运行 3、…

Java利用UDP实现简单的双人聊天

一、创建新项目 首先创建一个新的项目&#xff0c;并命名。 二、实现代码 import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.net.*; import java.io.IOException; import java.lang.String;public class liaotian extends JFrame{private stat…

expdp单独导出导入dblink

文章目录 前言一、实现步骤获取ddl方式&#xff08;不可行&#xff09;expdp单独导出dblink 二、impdp单独导入dblink 前言 在实际工作中可能会遇到测试或者迁移工作&#xff0c;对于数据库建立较多的dblink应用重新建立dblink工作量较大&#xff0c;此时可以通过逻辑导出导入…

邮件协议讲解(SMTP、POP3、IMAP)

邮件收发基本概念 常见邮件协议 发邮件&#xff1a;SMTP&#xff08;加密版本SMTPS&#xff09; 收邮件&#xff1a;IMAP&#xff08;加密版本IMAPS&#xff09;、POP3&#xff08;加密版本POP3S&#xff09; 邮件协议端口号 SMTP&#xff1a; TCP 25 IMAP&#xff1a;…

西门子SMART精彩触摸屏如何在进入某个画面时置位某个BOOL变量?

西门子SMART精彩触摸屏如何在进入某个画面时置位某个BOOL变量&#xff1f; 以下举例进行说明具体的操作&#xff1a; 如下图所示&#xff0c;新建一个项目后&#xff0c;在变量表中添加好自己需要的变量&#xff1b; 添加一个画面&#xff0c;这里以“画面_1”进行举例说明&…

在 Node-RED 中引入 ECharts 实现数据可视化

Node-RED 提供了强大的可视化工具&#xff0c;而通过引入 ECharts 图表库&#xff0c;您可以更直观地呈现和分析数据。在这篇博客中&#xff0c;我们将介绍两种在 Node-RED 中实现数据可视化的方法&#xff1a;一种是引入本地 ECharts 库&#xff0c;另一种是直接使用 CDN&…

美图发布自研视觉大模型4.0,主打AI设计与AI视频【无际Ai分享资讯】

12月5-6日&#xff0c;主题为“未来AI设计”的美图创造力大会在厦门举行。美图公司发布自研AI视觉大模型MiracleVision&#xff08;奇想智能&#xff09;4.0版本&#xff0c;主打AI设计与AI视频。 AI设计方面&#xff0c;新增了矢量图形、文字特效、智能分层、智能排版四大能力…

机器学习实验五:集成学习

系列文章目录 机器学习实验一&#xff1a;线性回归机器学习实验二&#xff1a;决策树模型机器学习实验三&#xff1a;支持向量机模型机器学习实验四&#xff1a;贝叶斯分类器机器学习实验五&#xff1a;集成学习机器学习实验六&#xff1a;聚类 文章目录 系列文章目录一、实验…

windows install git

refer: https://developers.weixin.qq.com/miniprogram/dev/devtools/wechatvcs.html https://blog.csdn.net/weixin_40228200/article/details/128451324 在使用小程序的时候&#xff0c;需要初始化项目&#xff0c;需要注册Git账号 1.在本地确认cmd没有安装Git,进入Git官网…

开放式耳机什么品牌好?南卡、韶音、cleer开放式耳机哪个好?

全球TWS耳机出货量从2016年的918万台增长至2023年第二季度的6816万台。开放式耳机的新赛道在2023年持续发酵&#xff0c;成为市场中的新关注点&#xff0c;各大品牌也在今年争先推出新款开放式耳机&#xff0c;韶音、南卡、Cleer的新产品都在上半年纷纷亮相&#xff0c;开放式耳…

阻碍“元宇宙”游戏行业发展的最大瓶颈是什么?

很显然&#xff0c;我们现在还没看到真正的“元宇宙”产品&#xff0c;在3-5年内也不太可能看到这样的产品。按照米哈游CEO蔡浩宇的说法&#xff0c;2030年希望建成一个“上亿人愿意生活在其中的虚拟世界”&#xff0c;那也是八年以后的事情了。 原因很简单&#xff1a;技术不成…

Java 输入输出流01

1. 什么是 IO Java 中 I/O 操作主要是指使用 Java 进行输入&#xff0c;输出操作. Java 所有的 I/O 机制都是基于数据流进行输入输出&#xff0c;这些数据流表示了字符或者字节数据的流动序列。Java 的 I/O 流提供了读写数据的标准方法。任何 Java 中表示数据源的对象都会提供…

2024年终工作总结汇报,这样来写更科学

时光荏苒&#xff0c;2024年已经悄然而至&#xff0c;伴随而来的是一年一度的终年工作总结&#xff0c;以回首过去的一年的成果与不足。然而&#xff0c;怎样写一份既真实又有说服力的总结汇报成了摆在很多人面前的一道难题。 在为年终总结苦恼时&#xff0c;我突然想到了平时…