欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > Unity自学之旅04

Unity自学之旅04

2025/6/13 20:06:25 来源:https://blog.csdn.net/m0_63622279/article/details/145290035  浏览:    关键词: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。点击获胜按钮可重新开始游戏,通过重新加载第一个场景实现,同时恢复时间流速为正常状态。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词