Unity自学之旅04

Unity自学之旅04

  • Unity自学之旅④
    • 📝 跳跃
    • 🐯 攻击
    • 🦄 GUI
      • GUI前置,显示收集物品数量和角色Hp
      • UGUI
      • 游戏暂停和重新开始
  • 🤗 总结归纳

Unity自学之旅④

📝 跳跃

public class PlayerBehaviorRigid : MonoBehaviour
{//...// 跳跃速度public float JumpVelocity = 5f;// 是否跳跃private bool _isJumping;void Start(){// 将当前player的刚体组件获取并设置_rb = GetComponent<Rigidbody>();    }void Update(){//...// 按位或_isJumping |= Input.GetKeyDown(KeyCode.J);}void FixedUpdate(){//...if (_isJumping){// 如果按下J键,瞬间力向上跳跃_rb.AddForce(Vector3.up*JumpVelocity,ForceMode.Impulse);}_isJumping = false;}
}

在这里插入图片描述

在这里插入图片描述

如何解决连续跳跃的问题,保证角色只可以进行一次跳跃。落地之后才可以接着进行跳跃。这个时候,需要使用一个遮罩层来完成。

Player会在场景中的Environment进行跳跃,也就是ground层,只需要计算Player与Ground层之间的距离,达到某个阈值视为触地。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

public class PlayerBehaviorRigid : MonoBehaviour
{// ...// 跳跃速度public float JumpVelocity = 5f;// 是否跳跃private bool _isJumping;// 角色和地面之间的距离 public float DistanceToGround = 0.1f;// Ground Layer 层public LayerMask GroundLayer;// 胶囊碰撞体public CapsuleCollider _col; void Start(){// 将当前player的刚体组件获取并设置_rb = GetComponent<Rigidbody>();// 获取当前角色的胶囊碰撞体_col = GetComponent<CapsuleCollider>();}void Update(){// ...// 按位或_isJumping |= Input.GetKeyDown(KeyCode.J);}void FixedUpdate(){//...if (IsGrounded() && _isJumping){// 如果按下J键,瞬间力向上跳跃_rb.AddForce(Vector3.up*JumpVelocity,ForceMode.Impulse);}_isJumping = false;}// 是否触地private bool IsGrounded(){// 胶囊体的最底部位置 (碰撞器的中心坐标x,z,以及最小y轴坐标)Vector3 capsuleBottom = new Vector3(_col.bounds.center.x,_col.bounds.min.y, _col.bounds.center.z);// 检查胶囊体中心到胶囊体底部之间的区域是否与地面层发生碰撞// 距离如果小于 DistanceToGround 0.1f则视为碰撞触地bool grounded = Physics.CheckCapsule(_col.bounds.center,capsuleBottom,DistanceToGround,GroundLayer,QueryTriggerInteraction.Ignore);return grounded;}
}

🐯 攻击

在这里插入图片描述

在这里插入图片描述

遗漏了一个问题,给子弹添加RigidBody刚体组件

在这里插入图片描述

编写一个射击子弹的逻辑(在此之前,清除掉场景中的Bullet)

在这里插入图片描述

public class PlayerBehaviorRigid : MonoBehaviour
{// ...// 子弹GameObjectpublic GameObject Bullet;// 子弹攻击速度public float BulletSpeed = 100f;// 是否攻击public bool _isShooting;void Start(){// 将当前player的刚体组件获取并设置_rb = GetComponent<Rigidbody>();// 获取当前角色的胶囊碰撞体_col = GetComponent<CapsuleCollider>();}void Update(){//...// 按下空格键 进行射击_isShooting |= Input.GetKeyDown(KeyCode.Space);}void FixedUpdate(){//...if (_isShooting){// 每次空格键按下都会在Player的z轴前一个单位产生一颗子弹GameObject newBullet = Instantiate(Bullet,this.transform.position+new Vector3(0,0,1),this.transform.rotation) as GameObject;Rigidbody BulletRb = newBullet.GetComponent<Rigidbody>();   // 直线射击子弹,子弹速度=player角色的面向方向*子弹速度BulletRb.velocity = this.transform.forward * BulletSpeed;}_isShooting = false;    }
}

在这里插入图片描述

出现的新问题,子弹一直在创建新的对象,我们应该给其加入一个自动销毁策略,如:发射出三秒后销毁。为子弹添加一个脚本,3秒后销毁。

public class BulletBehavior : MonoBehaviour
{public float OnScreenDelay = 3f;void Start(){Destroy(this.gameObject, OnScreenDelay);}}

在这里插入图片描述

🦄 GUI

GUI前置,显示收集物品数量和角色Hp

创建一个管理类脚本,以及一个空对象,将管理类脚本挂载到空对象上。

public class GameBehavior : MonoBehaviour
{private int _itemsCollected = 0;private int _playerHp = 10;public int Items { get { return _itemsCollected; } set { _itemsCollected = value; Debug.LogFormat("收集了:{0}",_itemsCollected);}}public int HP{get { return _playerHp; }set{_playerHp = value;Debug.LogFormat("HP:{0}", _playerHp);}}
}

在这里插入图片描述

修改之前的逻辑,捡到Health_Pickup时给物品收集数量+1,然后运行游戏注意观察日志输出

public class ItemBehavior : MonoBehaviour
{// 获取刚刚的GameManager脚本对象public GameBehavior GameManager;void Start(){GameManager = GameObject.Find("Game_Manager").GetComponent<GameBehavior>();}// 发生碰撞时被调用void OnCollisionEnter(Collision collision){if(collision.gameObject.name == "Player"){// 销毁当前物体Destroy(this.transform.gameObject);Debug.Log("碰撞,销毁");// 发生碰撞时意味着捡到了物品GameManager.Items += 1;}}
}

在这里插入图片描述

UGUI

在这里插入图片描述

在这里插入图片描述

很简单,打开Inspect然后修改文字UI的位置以及字体颜色,运行观察一下效果

在这里插入图片描述

在这里插入图片描述

接着再绘制一个是否获胜的文字UI

在这里插入图片描述

编辑GameManager的脚本GameBehavior,很简单的逻辑,在项目启动时,赋予对应HP,Item初始的文字UI,然后当Item≥4时代表游戏获胜,将Progress设为win.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;public class GameBehavior : MonoBehaviour
{private int _itemsCollected = 0;public int Items { get { return _itemsCollected; } set { _itemsCollected = value;ItemsText.text = "Items Collected:" + Items;Debug.LogFormat("收集了:{0}",_itemsCollected);if(_itemsCollected >= MaxItems){ProgressText.text = "win";}else{ProgressText.text = "Item found,only" + (MaxItems - _itemsCollected) + "more!";}}}private int _playerHp = 10;public int HP{get { return _playerHp; }set{_playerHp = value;HealthText.text = "Player Health:" + HP;Debug.LogFormat("HP:{0}", _playerHp);}}// 游戏中一共存在四个可以收集的Health_pickuppublic int MaxItems = 4;// 三个UI文字public TMP_Text HealthText;public TMP_Text ItemsText;public TMP_Text ProgressText;void Start(){HealthText.text += _playerHp;ItemsText.text += _itemsCollected;}}

在这里插入图片描述

在这里插入图片描述

光是文字的UI看着很low,或者说呈现方式并不是很好,现在改换思路,当游戏获胜时,弹出一个按钮之类的显示获胜。

在这里插入图片描述

绘制好了,然后默认情况下它不应该显示,将InSepct里面的复选框取消勾选,然后修改代码逻辑,当获胜时,显示该UI

在这里插入图片描述

记得在GameManager的脚步中将Button按钮挂载上去

在这里插入图片描述

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.UI;public class GameBehavior : MonoBehaviour
{//...public int Items { get { return _itemsCollected; } set { //...if(_itemsCollected >= MaxItems){//..WinButton.gameObject.SetActive(true);}//...}}//...// 按钮UIpublic Button WinButton;//...
}

在这里插入图片描述

获胜了,但是还没有理想的效果,当获胜时,应该暂停游戏或者出现一个重新开始的功能,最主要的是当获胜时,我们应该停止角色的控制权限,不能再进行移动,跳跃,射击等功能。

游戏暂停和重新开始

游戏暂停:Time.timeScale = 0f; 时间流速设置为0,暂停游戏。当timeScale>=1 时,为正常时间流速。

游戏重新开始:一般通过重新加载第一个场景来完成,即SceneManager.LoadScene(0) .

逻辑是,当获胜时暂停游戏,点击You Win 按钮时,重新开始游戏。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.UI;
using UnityEngine.SceneManagement;public class GameBehavior : MonoBehaviour
{//...public int Items { get { return _itemsCollected; } set { //...if(_itemsCollected >= MaxItems){//...Time.timeScale = 0f;}//...}}//...// 重置场景public void RestartScene(){SceneManager.LoadScene(0);Time.timeScale = 1f;}
}

需要注意的点:在Unity中不可以凭空运行,任何脚本都需要挂个GameObject来完成。

在这里插入图片描述

🤗 总结归纳

本文主要介绍了在 Unity 中实现角色跳跃、攻击以及游戏界面(GUI)相关功能的代码实现过程。包括解决角色连续跳跃问题、编写射击子弹逻辑并添加自动销毁策略、使用管理类脚本显示收集物品数量和角色 HP、通过 UGUI 修改文字 UI 以及绘制获胜按钮、实现游戏暂停和重新开始功能等。

重要亮点

  • 角色跳跃功能实现:通过定义跳跃速度、是否跳跃等变量,在按下特定键时给角色添加向上的瞬间力实现跳跃。为解决连续跳跃问题,使用遮罩层计算角色与地面层之间的距离,只有落地后才能再次跳跃。
  • 攻击功能实现:编写射击子弹的逻辑,按下特定键时在角色前方产生一颗子弹,并为子弹添加刚体组件和自动销毁策略,发射三秒后销毁。
  • GUI 显示物品数量和 HP:创建管理类脚本,挂载到空对象上,实现收集物品数量和角色 HP 的显示。当角色捡到物品时,物品收集数量加一,并在日志中输出。
  • UGUI 优化界面:通过修改文字 UI 的位置和字体颜色,绘制是否获胜的文字 UI。当物品收集数量达到一定值时,游戏获胜,显示 “win”,并可弹出按钮显示获胜。
  • 游戏暂停和重新开始:当游戏获胜时,暂停游戏,时间流速设置为 0。点击获胜按钮可重新开始游戏,通过重新加载第一个场景实现,同时恢复时间流速为正常状态。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Node.js——express中间件(全局中间件、路由中间件、静态资源中间件)

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

10倍数据交付提升 | 通过逻辑数据仓库和数据编织高效管理和利用大数据

数据已经成为企业核心竞争力的关键要素。随着大数据技术的发展&#xff0c;如何高效管理和利用海量的数据&#xff0c;已成为企业在数字化转型过程中面临的重要课题。传统的数据仓库已经不能满足当今企业对数据处理的高效性、灵活性和实时性的需求。在这种背景下&#xff0c;逻…

PHP礼品兑换系统小程序

&#x1f381; 礼品兑换系统&#xff1a;革新企业礼品管理&#xff0c;专属神器来袭&#xff01; &#x1f4bb; 一款专为追求高效与个性化的现代企业量身打造的礼品兑换系统&#xff0c;它基于强大的ThinkPHP框架与前沿的Uniapp技术栈深度融合&#xff0c;不仅完美适配礼品卡…

【玩转全栈】----Django基本配置和介绍

目录 Django基本介绍&#xff1a; Django基本配置&#xff1a; 安装Django 创建项目 创建app 注册app Django配置路由URL Django创建视图 启动项目 Django基本介绍&#xff1a; Django是一个开源的、基于Python的高级Web框架&#xff0c;旨在以快速、简洁的方式构建高质量的Web…

RabbitMQ 高级特性

目录 1.消息确认 1.1 消息确认机制 1.2 手动确认方法 1. 2.1肯定确认 1.2.2 否定确认 1.3 SpringBoot 代码示例 1.3.1 配置确认机制 1.3.2 配置队列,交换机,绑定关系 1.3.3 生产者(向 rabbitmq 发送消息) 1.3.4 消费者(消费队列中的信息) 2.持久性 2.1 交换机…

QT:控件属性及常用控件(3)-----输入类控件(正则表达式)

输入类控件既可以进行显示&#xff0c;也能让用户输入一些内容&#xff01; 文章目录 1.Line Edit1.1 用户输入个人信息1.2 基于正则表达式的文本限制1.3 验证两次输入的密码是否一致1.4 让输入的密码可以被查看 2.Text Edit2.1 输入和显示同步2.1 其他信号出发情况 3.ComboBox…

迅为RK3568开发板篇OpenHarmony实操HDF驱动控制LED-添加内核编译

编译内核时将该 HDF 驱动编译到镜像中&#xff0c;接下来编写驱动编译脚本 Makefile&#xff0c;代码如下所示&#xff1a; 加入编译体系&#xff0c;填加模块目录到 drivers/hdf_core/adapter/khdf/linux/Makefile 文件 更多内容可以关注&#xff1a;迅为RK3568开发板篇OpenHa…

【面试总结】FFN(前馈神经网络)在Transformer模型中先升维再降维的原因

FFN&#xff08;前馈神经网络&#xff09;在Transformer模型中先升维再降维的设计具有多方面的重要原因&#xff0c;以下是对这些原因的总结&#xff1a; 1.目标与动机 高维映射空间&#xff1a;FFN的设计目的是通过一系列线性变换来拟合一个高维的映射空间&#xff0c;而不仅…

从零安装 LLaMA-Factory 微调 Qwen 大模型成功及所有的坑

文章目录 从零安装 LLaMA-Factory 微调 Qwen 大模型成功及所有的坑一 参考二 安装三 启动准备大模型文件 四 数据集&#xff08;关键&#xff09;&#xff01;4.1 Alapaca格式4.2 sharegpt4.3 在 dataset_info.json 中注册4.4 官方 alpaca_zh_demo 例子 999条数据, 本机微调 5分…

【Rabbitmq】Rabbitmq高级特性-发送者可靠性

Rabbitmq发送者可靠性 发送者重连发送者确认1.开启确认机制2.ReturnCallback3.ConfirmCallback MQ的可靠性数据持久化交换机持久化队列持久化消息持久化 Lazy Queue 总结其他文章 Rabbitmq提供了两种发送来保证发送者的可靠性&#xff0c;第一种叫发送者重连&#xff0c;第二种…

计算机网络 (55)流失存储音频/视频

一、定义与特点 定义&#xff1a;流式存储音频/视频是指经过压缩并存储在服务器上的多媒体文件&#xff0c;客户端可以通过互联网边下载边播放这些文件&#xff0c;也称为音频/视频点播。 特点&#xff1a; 边下载边播放&#xff1a;用户无需等待整个文件下载完成即可开始播放…

抖音小程序一键获取手机号

前端代码组件 <button v-if"!isFromOrderList"class"get-phone-btn" open-type"getPhoneNumber"getphonenumber"onGetPhoneNumber">一键获取</button>// 获取手机号回调onGetPhoneNumber(e) {var that this tt.login({f…

论文速读|NoteLLM: A Retrievable Large Language Model for Note Recommendation.WWW24

论文地址&#xff1a;https://arxiv.org/abs/2403.01744 bib引用&#xff1a; misc{zhang2024notellmretrievablelargelanguage,title{NoteLLM: A Retrievable Large Language Model for Note Recommendation}, author{Chao Zhang and Shiwei Wu and Haoxin Zhang and Tong Xu…

Day 15 卡玛笔记

这是基于代码随想录的每日打卡 222. 完全二叉树的节点个数 给你一棵 完全二叉树 的根节点 root &#xff0c;求出该树的节点个数。 完全二叉树 的定义如下&#xff1a;在完全二叉树中&#xff0c;除了最底层节点可能没填满外&#xff0c;其余每层节点数都达到最大值&#x…

【阿里云】使用docker安装nginx后可以直接访问

一、创建目录 mkdir -p config/{cert,conf.d} html logs二、上传nginx.conf的配置文件 user nginx; worker_processes auto;error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid;events {worker_connections 1024; }http {include /etc/ngin…

在elasticsearch中,document数据的写入流程如何?

本文将为您介绍文档内容是如何写入ES集群中。 数据写入ES集群的流程图如下 流程介绍 用户携带数据发起POST请求指向集群9200端口。9200端口将数据写入请求发给主分片。主分片会对数据进行分片计算分发给具体分片。&#xff08;计算方式&#xff1a;hash % primary_number_sha…

sentinel微服务保护

学习链接 SpringCloudRabbitMQDockerRedis搜索分布式 文章目录 学习链接1.初识Sentinel1.1.雪崩问题及解决方案1.1.1.雪崩问题1.1.2.超时处理1.1.3.仓壁模式1.1.4.断路器1.1.5.限流1.1.6.总结 1.2.服务保护技术对比1.3.Sentinel介绍和安装1.3.1.初识Sentinel官网地址github地址…

STM32-CAN总线

1.CAN总线简介 CAN总线是由BOSCH公司开发的一种简洁易用、传输速度快、易扩展、可靠性高的串行通信总线 2.CAN总线特征 两根通信线&#xff08;CAN_H、CAN_L&#xff09;&#xff0c;线路少&#xff0c;无需共地差分信号通信&#xff08;相对的是单端信号&#xff09;&#…

iOS 权限管理:同时请求相机和麦克风权限的最佳实践

引言 在开发视频类应用时&#xff0c;我们常常会遇到需要同时请求相机和麦克风权限的场景。比如&#xff0c;在用户发布视频动态时&#xff0c;相机用于捕捉画面&#xff0c;麦克风用于录制声音&#xff1b;又或者在直播功能中&#xff0c;只有获得这两项权限&#xff0c;用户…

DDD实战课 笔记

DDD实战课 作者&#xff1a;欧创新 01 | 微服务设计为什么要选择DDD&#xff1f; 微服务拆分困境产生的根本原因就是不知道业务或者微服务的边界到底在什么地方。 为什么 DDD 适合微服务&#xff1f; DDD 是一种处理高度复杂领域的设计思想&#xff0c;它试图分离技术实现的…