Unity学习入门实例——第一人称射击游戏控制器

Python制作自己的第一人称射击游戏 作为一杆老枪,我觉得我必须站出来了,现在世风日下,于是我开始用Python自己制作一个射击游戏。 阅读详情

前言

同笔者之前发布的文章一样,此文章案例是笔者在阅读《Unity3D 脚本编程和游戏开发》中,跟随书籍进行的实例练习。
此案例虽然代码简单,但是需要读者初步了解3D游戏中的数学知识(包括但不限于向量、四元数)

案例对应下载链接: 点击下载

效果展示

请添加图片描述

功能实现

第一人称射击游戏角色控制器的实现主要有两个功能:

  • 角色移动控制
  • 鼠标控制角色旋转

当然其中还包括玩家物体的创建,我们可以随意创建玩家物体,只要保证将Main Camera物体作为玩家的子物体即可。

在效果中视角右下方的“枪”是几个简单几何图形拼凑的,读者可以自行拼凑,只需要将物体放置在玩家的子物体中即可。

角色移动控制

我们实现的思路为:获取角色面朝方向(transform.forward)和角色的右边方向(transform.right),获取玩家的输入,将玩家的输入与角色的方向“结合”(相乘)获取到角色的移动向量。之后控制角色向移动方向移动即可。

代码:

    private void Move()
    {
        //获取玩家输入
        float horizontalInput = Input.GetAxisRaw("Horizontal");
        float verticcalInput = Input.GetAxisRaw("Vertical");
        
        //获取角色正前方向以及右方向
        Vector3 forwardVec = new Vector3(transform.forward.x, 0, transform.forward.z);
        Vector3 rightVec = transform.right;
        
        //计算得出移动方向
        Vector3 moveDirection = verticcalInput * forwardVec + horizontalInput * rightVec;
        //将移动方向归一化
        moveDirection = moveDirection.normalized;
	//将角色向目标方向移动
        transform.position += moveDirection * moveSpeed * Time.deltaTime;

    }

鼠标控制视角

在完成这个功能之前,我们需要明白第一人称视角下的角色在沿X轴旋转和沿Y轴旋转时旋转的坐标轴的不同:当玩家视角水平旋转时(沿Y轴旋转),玩家视角应当沿世界坐标轴的Y轴旋转;当玩家视角垂直旋转时(沿X轴旋转),玩家视角应当沿本地坐标轴旋转。

那么知道这些我们只需要实现以下几个步骤就可以很简单的实现视角旋转的功能:

  1. 获取鼠标的X、Y轴输入
  2. 根据鼠标的X、Y输入获取对应沿Y轴、沿X轴的旋转角度(X轴输入对应沿Y轴旋转,Y轴输入对应沿X轴旋转)
  3. 沿Y轴旋转使用世界坐标系旋转,沿X轴旋转使用本地坐标系旋转

对应代码:

    private void MouseLook()
    {
        //1.获取X、Y输入
        float mouseX = Input.GetAxis("Mouse X");
        float mouseY = -Input.GetAxis("Mouse Y");
        
        //2.根据鼠标的X、Y输入获取对应沿Y轴、沿X轴的旋转角度(X轴输入对应沿Y轴旋转,Y轴输入对应沿X轴旋转)
        Quaternion quaternionX = Quaternion.Euler(0, mouseX, 0);
        Quaternion quaternionY = Quaternion.Euler(mouseY, 0, 0);

        //3.沿Y轴旋转使用世界坐标系旋转,沿X轴旋转使用本地坐标系旋转
        transform.rotation = quaternionX * transform.rotation;
        transform.rotation =  transform.rotation * quaternionY;

    }

但是,当我们使用这个方法进行视角移动时,会发现:有时当我们的视角向上移动到90°以上时,视角会“倒过去”,所以我们就需要限制视角的移动角度:

    private void MouseLook()
    {
        float mouseX = Input.GetAxis("Mouse X");
        float mouseY = -Input.GetAxis("Mouse Y");
        //鼠标X轴的移动表示鼠标沿Y轴旋转
        Quaternion quaternionX = Quaternion.Euler(0, mouseX, 0);
        //鼠标Y轴的移动表示鼠标沿X轴旋转
        Quaternion quaternionY = Quaternion.Euler(mouseY, 0, 0);

        //镜头水平旋转时,沿世界坐标系旋转
        transform.rotation = quaternionX * transform.rotation;
        //镜头垂直旋转,沿本地坐标轴旋转
        transform.rotation =  transform.rotation * quaternionY;

        //限制俯仰角度
        float angle = transform.eulerAngles.x;
        //使用欧拉角时,防止出现-1°到359°混乱的情况
        if(angle > 180)
        {
            angle -= 360;
        }
        if(angle < -180)
        {
            angle += 360;
        }
        //限制抬头、低头角度
        if(angle > 80)
        {
            transform.eulerAngles = new Vector3(80, transform.eulerAngles.y, 0);
        }
        if(angle < -80)
        {
            transform.eulerAngles = new Vector3(-80, transform.eulerAngles.y, 0);
        }
    }

完整代码

在完整代码中,笔者加了一个控制手电筒开关的小功能,原理非常简单:在玩家物体下创建一个挂载有Spot Light组件的物体,在开始时获取物体,当输入F时将物体激活/关闭。

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FPSPlayerController : MonoBehaviour
{

    public float moveSpeed = 50f;

    public  Light flashLight;

    // Start is called before the first frame update
    void Start()
    {
        //隐藏鼠标
        Cursor.visible = false;
        //锁定鼠标指针到屏幕中央
        Cursor.lockState = CursorLockMode.Locked;

        if(flashLight == null)
        {
            flashLight = GetComponentInChildren<Light>();
        }
    }

    // Update is called once per frame
    void Update()
    {
        Move();
        MouseLook();
	//控制手电筒开关
        if (Input.GetKeyDown(KeyCode.F))
        {
            flashLight.enabled = !flashLight.enabled;
        }
    }

    private void MouseLook()
    {
        float mouseX = Input.GetAxis("Mouse X");
        float mouseY = -Input.GetAxis("Mouse Y");
        //鼠标X轴的移动表示鼠标沿Y轴旋转
        Quaternion quaternionX = Quaternion.Euler(0, mouseX, 0);
        //鼠标Y轴的移动表示鼠标沿X轴旋转
        Quaternion quaternionY = Quaternion.Euler(mouseY, 0, 0);

        //镜头水平旋转时,沿世界坐标系旋转
        transform.rotation = quaternionX * transform.rotation;
        //镜头垂直旋转,沿本地坐标轴旋转
        transform.rotation =  transform.rotation * quaternionY;

        //限制俯仰角度
        float angle = transform.eulerAngles.x;
        //使用欧拉角时,防止出现-1°到359°混乱的情况
        if(angle > 180)
        {
            angle -= 360;
        }
        if(angle < -180)
        {
            angle += 360;
        }

        //限制抬头、低头角度
        if(angle > 80)
        {
            transform.eulerAngles = new Vector3(80, transform.eulerAngles.y, 0);
        }
        if(angle < -80)
        {
            transform.eulerAngles = new Vector3(-80, transform.eulerAngles.y, 0);
        }
    }

    private void Move()
    {
        float horizontalInput = Input.GetAxisRaw("Horizontal");
        float verticcalInput = Input.GetAxisRaw("Vertical");
        //Y轴为0,确保移动方向都在水平上
        Vector3 forwardVec = new Vector3(transform.forward.x, 0, transform.forward.z);

        //角色右方向与抬头无关,可以直接调用
        Vector3 rightVec = transform.right;
        //获取移动方向
        Vector3 moveDirection = verticcalInput * forwardVec + horizontalInput * rightVec;
        moveDirection = moveDirection.normalized;

        transform.position += moveDirection * moveSpeed * Time.deltaTime;

    }
}

Unity3D案例太空射击(Space Shooter)流程介绍与代码分析(中) (上)部分主要介绍了素材的添加以及基本的移动与涉及功能,这部分关注事件的实现(如碰撞检测)。 传送门: 太空射击(Space Shooter)流程介绍与代码分析(上) 太空射击(Space Shooter)流程介绍与代码分析(中) 太空射击(Space Shooter)流程介绍与代码分析(下) 6.边界的设定 在上述过程中,若一直发射子弹,在Hierarchy中会一直出 阅读详情

相关推荐

Unity中FPS类小游戏的简单制作

1.摄像机放Player上,射线机代码 using UnityEngine; using System.Collections; public class Camera : MonoBehaviour { public GameObject player; private Vector3 rot = new Vector3(0, 0, 0); public float

YaoLifeng的博客 4057

Unity3D第一人称射箭游戏作业

负责游戏一开始的初始化,和游戏进行中将信息传递到不同的脚本中,如为视图View传递分数、当前位置等信息。挂载在十字弩物体上,控制十字弩的射击、蓄力等动画呈现,以及控制十字弩可以上下左右移动。-设置静止靶单倍区和运动靶双倍区两个区域可以射击,其他区域没有靶子无法射击得分。-靶子分为白、黑、红自外向里为3、4、5分,集中运动靶分数则翻倍。负责控制游戏的页面提示,向玩家展示游戏的进行状态。-长按空格可以为弓弩蓄力,再次按下空格则发射。-一共有10支箭矢,全部用完则游戏结束。

yueyingq的博客 581

unity游戏开发_stealth秘密潜入

Stealth秘密行动   在这个博客里,我将讲解一个潜入类型的游戏制作方法 1.    首先我们需要导入当前的场景,这里我们需要给场景添加碰撞器,将素材里的env_stealth拖入,加上meshCollieder,添加上env_stealth_collider就可以将预先设置好的碰撞器添加上,再将模型中的汽车拖入,对照碰撞器摆好好汽车即可,   2.    我们给场景添加光源  

文学少年 3127

unity射击小游戏之人物的移动跳跃及视角转动

unity设计中人物移动是最基本的也是必须要掌握的设计:以下我为大家带来基础操作以及代码内容Update()TranslateUpdate()AddForce()Translate。

2301_80653944的博客 1081

11、构建射击生存游戏:Lazer Blast Survival

本博文详细介绍了如何使用Unity开发一款射击生存游戏《Lazer Blast Survival》,涵盖了游戏控制器、玩家设置、敌人AI、波次生成、弹药系统、用户界面、摄像机实现、音效与音乐管理等核心组件的实现细节。通过这些技术细节,开发者可以更好地理解并实现类似的游戏项目。

apple5的专栏 344

【Unity 狙击步枪模型资源】niper SVD 专注于提供逼真且优化良好的狙击枪模型,适用于第一人称射击(FPS)、第三人称射击和军事题材游戏

niper SVD 是一款为 Unity 开发者准备的高质量低多边形狙击步枪模型资源,专注于提供逼真且优化良好的狙击枪模型,适用于第一人称射击(FPS)、第三人称射击和军事题材游戏。该模型基于现实中的 SVD(Dragunov)狙击步枪设计,结合低多边形风格,兼顾视觉效果和性能表现。

2403_88403568的博客 512

unity 写一个角色控制器,鼠标控制屏幕晃动,鼠标控制开枪

using System.Collections; using System.Collections.Generic; using UnityEngine; public class two: MonoBehaviour { public GameObject _prefabBullet; private float _angleSpeed = 120f; void Update() { float eular...

LiPing122335的博客 816

面向网络攻击行为可视化分析系统实现【WebSocket + 可视化】

本系统主要应用于网站运维管理,它解决了网站运维人员排查网络攻击行为复杂且繁琐等问题,提高了运维人员网络安全分析的效率和准确性。

oNew_Lifeo的博客 1620

写一个角色控制器,鼠标控制屏幕晃动,鼠标控制开枪。

public class Player : MonoBehaviour { public GameObject _prefabBullet; private float _angleSpeed = 120f; void Update() { float eularY = Input.GetAxis("Mouse X") * _angleSpeed * Time

fanfan_hongyun的博客 451

QGroundControl或者华科尔地面站安装完打不开问题解决

QGroundControl 华科尔 打不开

wv112406的博客 4895

STM32+OOK通讯(OOK发送+OOK接收)+cubemx配置

关于OOK通信,我的理解就是将要发送的信息转换成高低电平(即0和1),然后接收方通过对01进行解码获得信息。于是我用了非常朴素的字符串转二进制+AM调制来完成通信链。话不多说我们直接开始!!!

qq_73856732的博客 2339

第一人称射击游戏——角色控制与音频播放

第一人称射击游戏——角色控制与音频播放 角色控制器初解: 角色控制器的很多功能刚体没有的,第一个是有爬坡角度的设置就是你控制人物可以爬上多少度的斜坡,我猜测一些游戏(比如刺激战场)角色能在近乎垂直的悬崖底部爬上去可能是因为石头表面的碰撞器是由多个面构成的角色在往上爬的时候通过了某些面的判定进而一步一步的爬上去。第二个是可以设置角色可以上多高的坎,换种说法就是可以上多高的楼梯。第三个就是可以设置一个皮肤的厚度,大概意思就是角色能离一个有碰撞体的物体多近。这些东西刚体都没有如果要实现显然会增加很多工作量。 原文

weixin_43156577的博客 697

ERROR: Ignored the following yanked versions: 0.8.3, 0.10.19.dev18 的解决办法

关于这个问题,博主是在进行项目中的python依赖包安装的时候遇见的,遇到的异常:关于这个问题,是在。

Spring Boot-Common On With You 642

Unity 4.2.2带来iOS游戏控制器支持

Like most mobile games developers, we’ve been closely following what important additions and changes the recently released iOS 7 update has made. One of the biggest and most exciting of Apple’s initia...

culiao6493的博客 190

电子元器件-接口电路篇:RS-232、RS485/422、I2C、SPI、USB、网口

以上规定说明了RS-232C 标准对逻辑电平的定义。对于数据(信息码):逻辑“1”的传输的电平为-3V~-15V,逻辑“0”传输的电平为+3V~+15V;对于控制信号;接通状态(ON)即信号有效的电平为+3V~+15V,断开状态(OFF)即信号无效的电平为-3V~-15V,也就是当传输电平的绝对值大于3V 时,电路可以有效地检查出来;

qq_60226558的博客 887

【100%通过率】华为OD机试真题 Java&Go 实现【微服务的集成测试】【2023 Q1 | 100分】

现在有n个容器服务,服务的启动可能有一定的依赖性(有些服务启动没有依赖),其次服务自身启动加载会消耗些时间。给你一个nxn 的二维矩阵 useTime,其中 useTime=10 表示服务i自身启动加载需要消耗10s,useTimeli[j]=1 表示服务i 启动依赖服务i 启动完成,useTimei[k]=0,表示服务i 启动不依赖服务 k其实 0

MISAYAONE的博客 1万+

Unity 脚本入门教程

原文:Introduction to Unity Scripting 作者:Georgi Ivanov 译者:kmyhy Unity 的许多功能都要通过它的富脚本语言 C# 来体现。你可以用它来处理用户输入,操作场景中的对象,碰撞检测,自动生成新的 GameObject 和在场景中发射定向光以处理游戏逻辑。听起来很可怕,但 Unity 提供了有良好文档的 API,使得这些任务的完成轻而

kmyhy的专栏 5万+

1.4 KFD 设备文件的获取与驱动握手协议

本文分析了OpenClose模块中libhsakmt与KFD内核驱动建立通信的过程。首先通过hsaKmtOpenKFD()函数打开/dev/kfd设备文件,建立用户态与内核态的通信通道。随后通过AMDKFD_IOC_GET_VERSION ioctl命令完成版本握手,确认双方的接口兼容性。KFD驱动采用Major.Minor二级版本号体系,当前主要版本为1,从1.1演进到1.19不断添加新功能。整个过程构成了用户态与内核态之间的"建连协议",是所有后续GPU操作的基础前提。

图形/计算GPU的驱动与虚拟化技术分享园地 600

Unity 第一人称射箭游戏

游戏场景(14分)地形(2分):使用地形组件,上面有山、路、草、树;(可使用第三方资源改造)天空盒(2分):使用天空盒,天空可随 玩家位置 或 时间变化 或 按特定按键切换天空盒;固定靶(2分):使用静态物体,有一个以上固定的靶标;(注:射中后状态不会变化)运动靶(2分):使用动画运动,有一个以上运动靶标,运动轨迹,速度使用动画控制;(注:射中后需要有效果或自然落下)射击位(2分):地图上应标记若干射击位,仅在射击位附近或区域可以拉弓射击,每个位置有 n 次机会;

m0_74106312的博客 960

【Network Management】AUTOSAR局部网络管理从0到1配置实践

AUTOSAR局部网络管理从0到1配置实践

qq_36056498的博客 2914

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

开发一个简单的飞碟射击游戏

在本文中,我们将介绍如何使用Unity和C#开发一个简单的飞碟射击游戏。这个游戏将包含多个回合,每个回合有10次尝试机会,玩家需要在飞碟飞出屏幕前点击它们来得分。游戏界面比较简陋Hierarchy。

weixin_70070804的博客 307

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

unity实战——穿越火线

*@2019072103d * 1.导入所需的资源 链接:https://pan.baidu.com/s/1kLnu28aPiZ7ak6j4rADqsw 提取码:m71u 2.项目开发 2.1标签的封装 创建一个名为Tags的脚本,将项目中所有将要使用的标签以const常量的方式进行分装。 using System.Collections; using System.Collection...

DedicationTechnology 8549

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

UFPS入门: Unity FPS 教程

UFPS入门: Unity FPS 教程 http://blog.youkuaiyun.com/kmyhy/article/details/72846348 UFPS : Ultimate FPS v1.7.3 download:https://item.taobao.com/item.htm?spm=a1z38n.10677092.0.0.11891d...

SilverFoxGame的博客 1315

Unity 2.Space Shooter(碰撞器Collider,WebGL,刚体中属性,(定时)实例化、销毁游戏对象,触碰OnTriggerEnter/Exit,爆炸效果,音频,文字,定时调方法)

目录 项目介绍 WebGL发布 游戏对象设置 灯光、相机 背景 移动游戏对象 Debug 制作子弹 射击动作 清理离开边界的游戏对象 制作危险物 添加爆炸,移动小行星,作为预制件 创建游戏控制器 循环(有间隙时间)创建Spawning waves 添加音频 显示分数 Debug: 结束游戏循环 Shooter: Enemies, More Hazards, S...

越开源越幸运 1万+

Unity-2017.3官方实例教程Space-Shooter(二)

由于初学Unity,写下此文作为笔记,文中难免会有疏漏,不当之处还望指正。 Unity-2017.3官方实例教程Space-Shooter(一) 章节列表: 一、创建小行星Prefab 二、创建敌机和敌机子弹Prefab 三、创建游戏控制器 四、添加音效 五、对象回收 六、创建计分板 一、创建小行星Prefab a、创建一个空对象,重命名为Asteroid_01,在Mod...

weixin_34413357的博客 471

【Unity 控制器插件】Game Kit Controller (GKC) 提供了全面的功能模块,涵盖从角色控制、战斗系统到交互和载具支持的多方面需求

Game Kit Controller (GKC) 是一款功能全面的Unity插件,专为开发者设计,用于快速创建各种类型的游戏控制器和相关功能。无论是第一人称射击(FPS)、第三人称冒险(TPS)、平台跳跃,还是开放世界游戏,GKC都能提供高度模块化的系统和工具,帮助开发者快速搭建游戏的核心机制,同时保持灵活性以适应不同的需求。

2403_88403568的博客 964
上一篇: Unity入门开发实战——俯视角3D射击游戏项目实战
BugMaker2000
博客等级 码龄7年 84粉丝 21原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值