unity初学6——简易的UI制作(血条制作)和音频加入以及NPC的对话气泡(2d)

Posted 林浮生

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unity初学6——简易的UI制作(血条制作)和音频加入以及NPC的对话气泡(2d)相关的知识,希望对你有一定的参考价值。

该文来是学习chutianbo老师的笔记,链接b站

UI的创建

1.右键Hierarchy空白处 UI➡canvas

2.这里一共使用了三个素材


层级结构

UI:初始画布
characters:头像
Mask:遮罩层
healthbar:血条
这里我们先回到UI(也就是一开始创建的Canvas)
我们一开始有用的应该只有渲染模式render Mode,他有三种模式
Screen Space - Overlay:这是默认模式,可以让 Unity 在始终在游戏的上层绘制 UI。大多数应用程序使用此模式,因为它们希望 UI 始终位于最上层以便提供所有信息。
Screen Space - Camera:这种模式在与摄像机对齐的平面上绘制 UI。平面的大小确定为始终填充整个屏幕,这样你就可以四处移动摄像机,并且平面将随摄像机一起移动,从而显示与 Overlay 图形相同的形状。但是,由于平面是在世界中绘制的,而不是在屏幕上层绘制的,因此世界中的对象可以绘制在 UI 的上层。
World Space:这种模式可在世界中的任何位置绘制平面。例如,你可以将此平面用作游戏中的计算机屏幕,或者用作墙壁,或者放在角色的上层。这在 3D 游戏中更有用,因为 UI 会随着距离变小。

3.关于拉动之后图像没有随着一起变化
这里就要使用锚点
就是头像四周的小三角形,它可以使我们的子物体在父物体固定的位置上随着父物体变化
4.遮罩层
第一步

第二步

第三步

把这个勾去掉
当然记得把锚点设好

这里
可以使用alt+右下角那个直接填充父物体,血条填充到遮罩层

5.bug时间
这样子做的话,在后面使用代码控制遮罩层缩减时会出现两端缩小,而不是血条向右减少的过程。
所以记得把Mask的pivot(就是中间那个蓝点)拉到left center(左边中间);

关于代码控制血条变化

主要思路是当血条变化时,遮罩层减少,使血条变短;
官方解释:遮罩是 UI 系统中的一种技术,利用这种技术可以将一张图像用作其他图像的“遮罩”。我们可以看成是第一张图像充当一个模板。第二张图像中与第一张图像重叠的部分是可见的,但另一部分则是隐藏的
创建一个UI脚本下挂到我们的HealthFrame

public class UIHealthBar : MonoBehaviour

    // Start is called before the first frame update
    //创建共有静态对象。获取血条本身
    public static UIHealthBar Instance  get; private set; 
    public Image Mask;
    float orignalSize;
    private void Awake()
    
        Instance = this;
    
    void Start()
    
        //设置静态实例为当前类对象
        orignalSize = Mask.rectTransform.rect.width;
    
    //创建一个方法,用来设置现在mask遮罩层的宽度
    public void SetValue(float value)
    
        //设置更改mask遮罩层宽度,根据传输过来的宽度进行更改
        Mask.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, orignalSize * value);
    
    

之后在我们主角血量变化函数中调用即可

  UIHealthBar.Instance.SetValue(currentHealth / (float)maxHealth);

简易的音频使用

这里我们就会用到 Audio Source的组件

下面说起来比较重要的
AudioClip——加入的音乐素材
Mute——禁音
volume——音量
Play on awake——在游戏开始时播放
Spatial Blend 2d——3d 2d就是全图播放都是一个音量,可以用作bgm,越拉向3d就越立体,会出现方位和位置距离的差别
底下那个函数,指的就是最小距离1时音量达到最大,500时听不见音乐;

关于代码控制音频

和使用其他组件一样

  1. Audiosource audioSource;
  2. 在start中实例化 audioSource = GetComponent();
    3.播放即可,clip即为音频,需要可以自己公开一个加进去;
    public void PlaySound(AudioClip clip)

    //可以有第二个参数音量0-1.0f
    audioSource.PlayOneShot(clip);

关于NPC的气泡实现


这里主要使用了TextMeshPro 创建方式也是在UI中找到就行
下为结构图

Dialog:canvas
Image:外面那个背景画
Text:TextMeshPro

问题1:关于字数过长会溢出

在overflow中改为page即可
问题2:无法显示中文:
需要自己下字体包,或者去文章底部看老师的gitee中有下载链接
问题3:如何翻页:
使用代码控制,下附代码
脚本挂给NPC,事件发起交给主角;

public class NonPlayerCharacter : MonoBehaviour

 public float displaytime=4.0f;
    public GameObject dialogBox;
    float timerDisplay;
    public GameObject dlgTMP;
    TextMeshProUGUI tmTxtBox;
    int totalPages;
    int currentPage = 1;
     void Start()
    
        dialogBox.SetActive(false);
        timerDisplay = -1.0f;
        tmTxtBox = dlgTMP.GetComponent<TextMeshProUGUI>();
    
    private void Update()
    
        totalPages = tmTxtBox.textInfo.pageCount;
        if (timerDisplay >= 0)
        
            timerDisplay -= Time.deltaTime;
            if (Input.GetKeyUp(KeyCode.Space))
            
                if (currentPage < totalPages)
                
                    
                    currentPage++;
                
                else
                
                    currentPage = 1;
                
                
                tmTxtBox.pageToDisplay = currentPage;
            
        
        else
        
            dialogBox.SetActive(false);
        
    
    public void DisplayDialog()
    
        timerDisplay = displaytime;
        dialogBox.SetActive(true);

    

关于和NPC的互动实现

使用射线碰撞对象实现,我们的NPC对象需要放到NPC层(自己创一个layer);

 if (Input.GetKeyDown(KeyCode.F))
        
            RaycastHit2D hit =Physics2D.Raycast(rigidbody2dRuby.position+Vector2.up*0.2f,lookDirection,1.5f,LayerMask.GetMask("NPC"));
            if(hit.collider!=null)
            
                Debug.Log($"对象是hit.collider.gameObject");
                NonPlayerCharacter npc = hit.collider.GetComponent<NonPlayerCharacter>();
                if (npc != null)
                
                    npc.DisplayDialog();
                
            
        

链接:chutianbo老师关于UI的介绍
链接:chutianbo老师字体下载

unity制作血条怎么一点一点加血

先创建一个3D的物体命名为Player来代表人物,在它下面创建一个Canvas,点击Canvas在Inspector窗口里可以看见他有一个叫Canvas的组件,点开把渲染模式改成世界空间,这样你就可以canvas里面的UI移动到世界空间里的物体上了,这样一来我们的血条就不会和一般的UI一样一

直在屏幕的固定地点而是跟着人物移动。

2. 接下来就是做血条了,先在Canvas下创建一个图片把它调到Player头上合适的位置并调成长条形。调图片只需要把Canvas的坐标重置再重置图片的坐标(因为他们的坐标都是基于父物体的),然后再调好大小和具体位置就行了。刚刚我们已经做了一个图片的UI了,可以用它来代表血条,但是游戏中往往是基础血条一个颜色而受伤后血条减少的部分是另一个颜色来作为对比,甚至像DNF里的BOSS会有很多颜色的血条来对比。所以我们直接Ctrl+D快速复制另一张图片,把原本的图片作为背景色,新创建的图片作为基础色(注意一定是背景的图片在上面,因为最下面也就是最新创建的UI会遮挡前面的UI)。

3.血条的雏形做好后,给两张图片里的Image组件里都添加一个2D图片作为源图像,然后改一下颜色,这里基础血量我就设置为绿色,而背景就设置为红色。接下来在作为基础血条的UI里找到Image组件>选择图像类型>已填充>填充方法>水平。这样我们的血条就做好了,改变基础血条里下的填充总数(FillAmount)就能实现血量减少的效果。(如果是3D项目中找不到2D的源图像可以在包管理器里添加2DSprite,然后在层级面板里点击右键->2D->Sprites随便创建一个图片,然后找到Image组件里的源图像点一下就可以找到源图像的位置,再把刚刚创建的图片删了把源图像添加到血条中去就行了。)

4.现在我们的血条就差最后一步了,那就是如何根据当前血量自动变化了。看了刚刚的操作其实大家应该都知道了,就是在代码中把填充总数和血量关联起来,方法有很多种,我这里就提供一种比较简单也好理解的思路。

首先要获取基础血条的Image组件,不过我们的脚本一般都是在Player身上,所以我们先去找game object,方法很多就不说明了。找到Image组件后让一个数等于它的fillAmount就行了,不过要注意的是fillAmount是介于0到1之间的一个数,所以最好用当前HP/最大
参考技术A 通过攻击动画使用动画事件自动造成自动互相伤害的效果

https://www.bilibili.com/video/BV19G4y1d7sT/
子弹打伤角色
https://www.bilibili.com/video/BV1VD4y1C71i/
怪物制作,包括受伤
https://www.bilibili.com/video/BV1tD4y1V7JZ/

以上是关于unity初学6——简易的UI制作(血条制作)和音频加入以及NPC的对话气泡(2d)的主要内容,如果未能解决你的问题,请参考以下文章

Ruby‘s Adventrue游戏制作笔记(十三)Unity血条UI的显示

Ruby‘s Adventrue游戏制作笔记(十三)Unity血条UI的显示

unity制作血条怎么一点一点加血

[Unity2D/3D]实用的血条制作(第二期)

unity3d中怎样制作血条跟随角色运动

Unity实战篇 |制作一个跟随鼠标转向的 简易箭头指示标,包括 UI指向 和 3D指向标