资源大湿 发表于 2022-1-4 19:04

Unity暑期萌新入门:音频篇(完)

大渣好。在本篇中将通过会为游戏添加音效,进一步烘托气氛,完成后制作.exe文件。
一、基本概念
Audio Sources(声音源):用于播放声音的组件。
Audio Clips(声音片段):在Audio Sources中播放的片段。
The Audio Listener:相当于“耳朵”,用来接收声音的组件,默认在Camera上。

二、添加音效及设置脚本
1.背景音
(1)在Hierarchy窗口中新建一个空的子对象,命名为Ambient。
(2)打开Assets > Audio 文件夹,把SFXHouseAmbience的声音片段拖进Ambient中,这将会自动添加Audio Sources组件。


(3)设置参数

[*]Play On Awake:勾选,背景音乐将会在游戏开始时自动播放。
[*]Loop:勾选,循环播放。
[*]Volume:0.5,音量大小。
[*]Spatial Blend:0,背景音乐应用2D模式。



2.结束音效
(1)在Hierarchy窗口中再复制两个Ambient GameObject,分别重命名为Escape和Caught。
(2)按住Ctrl同时选中Escape和Caught,修改Audio Source设置:

[*]Play On Awake:取消勾选,只需要在游戏结束的时候播放一次。
[*]Loop:取消勾选,结束音效不需要循环播放。
[*]Volume(音量):1。



(3)替换胜利音效与被抓音效

[*]打开Assets > Audio 文件夹:
[*]把SFXWin拖到Escape GameObject中,替换Audio Clip;



[*]把SFXGameOver 拖到Caught GameObject中,替换Audio Clip。



(4)整理Hierarchy
①新建一个空的GameObject,命名为Audio。
②把Ambient,Escape和Caught GameObjects拖进Audio中。

(5)修改GameEnding脚本
①思路:执行EndLevel()时,通过bool变量m_HasAudioPlayed判断是否已经播放过结束音效,确保只播放一次对应结局的音效。
②打开GameEnding脚本,修改代码:



新增变量


修改后脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class GameEnding : MonoBehaviour
{
    public float fadeDuration = 1f;                     //淡入淡出时间1S
    public float displayImageDuration = 1f;             //淡入完毕后等待时间1S
    public GameObject player;                           //玩家
    public CanvasGroup exitBackgroundImageCanvasGroup;//用于调节通关界面alpha值的CanvasGroup   
    public CanvasGroup caughtBackgroundImageCanvasGroup;//用于调节被抓界面alpha值的CanvasGroup   

    bool m_IsPlayerAtExit;                              //玩家是否到终点
    bool m_IsPlayerCaught;                              //玩家是否被抓
    float m_Timer;                                    //计时器

    public AudioSource exitAudio;                     //通关音效
    public AudioSource caughtAudio;                     //被抓音效
    bool m_HasAudioPlayed;                              //音效是否播放过

    /// <summary>
    /// 达到出口,进入触发器时调用
    /// </summary>
    /// <param name="other"></param>
    private void OnTriggerEnter(Collider other)
    {
      //如果进入触发器范围的是玩家,改变布尔变量
      if (other.gameObject == player)               
      {
            m_IsPlayerAtExit = true;
      }
    }

    //玩家被抓时在Observer脚本里调用
    public void CaughtPlayer()
    {
      m_IsPlayerCaught = true;
    }

    /// <summary>
    /// 每帧调用
    /// </summary>
    private void Update()
    {      
      if (m_IsPlayerAtExit)       //如果玩家到达出口,执行EndLevel();                     
      {
            EndLevel(exitBackgroundImageCanvasGroup,false,exitAudio);
      }
      else if (m_IsPlayerCaught)//如果玩家被抓,执行重新加载场景;
      {
            EndLevel(caughtBackgroundImageCanvasGroup,true,caughtAudio);
      }
    }

    /// <summary>
    /// 关卡结束
    /// </summary>
    void EndLevel(CanvasGroup imageCanvasGroup,bool doRestart,AudioSource audioSource)
    {
      //当结束音效没有播放过时,播放对应的音效
      if (!m_HasAudioPlayed)
      {
            audioSource.Play();
            m_HasAudioPlayed = true;      //true表示音效已经播放过
      }

      m_Timer = m_Timer + Time.deltaTime; //计时器,每帧累加时间
      
      //alpha值随着百分比改变
      imageCanvasGroup.alpha = m_Timer / fadeDuration;

      //当计时器时间大于总等待时间
      if (m_Timer > fadeDuration + displayImageDuration)
      {
            if (doRestart)
            {
                SceneManager.LoadScene(0);//场景载入,只有一个场景,下标为0
            }
            else
            {
                Application.Quit();//退出游戏,这个要游戏打包后才会执行,在Unity里不会关闭游戏。
            }
      }
    }
}
编辑完成后保存脚本。

(6)回到Hierarchy窗口,选中GameEnding GameObject,为其GameEnding 脚本的字段分配引用:
①把Escape拖进Exit Audio字段中;
②把Caught 拖进Caught Audio字段中。



3.脚步声
(1)设置
①打开JohnLemon 的预制体,把SFXFootstepsLooping拖到JohnLemon GameObject上,给主角添加脚步声。
②设置其Audio Source参数:

[*]Play On Awake:取消勾选,当JohnLemon行走时才会播放脚步声。
[*]Loop(循环播放):勾选。


(2)修改PlayerMovement脚本
①思路:通过bool变量记录行走状态,行走时播放脚步声,否则停止播放。有一点需要注意,AudioSource.Play()会从头开始播放声音片段,因此我们需要添加一个判断条件,只有脚步声没有在播放时,才执行该方法。
②修改脚本:




修改后脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    public float turnSpeed = 20f;//旋转速度

    Animator m_Animator;    //Animator组件
    Rigidbody m_Rigidbody;//刚体
    Vector3 m_Movement;   //移动向量
    Quaternion m_Rotation = Quaternion.identity;//旋转四元数

    AudioSource m_AudioSource; //AudioSource组件


    void Start()
    {
      //获取组件
      m_Animator = GetComponent<Animator>();      //获取Animator组件
      m_Rigidbody = GetComponent<Rigidbody>();    //获取Rigidbody组件
      m_AudioSource = GetComponent<AudioSource>();//获取AudioSource组件
    }

    void FixedUpdate()
    {      
      //获取按键输入
      float horizontal = Input.GetAxis("Horizontal"); //水平输入AD
      float vertical = Input.GetAxis("Vertical");   //竖直输入WS
      
      //根据输入设置移动向量
      m_Movement.Set(horizontal, 0f, vertical);
      m_Movement.Normalize();                         //转化为单位向量,表示移动方向
      
      //根据输入判断是否在行走
      bool hasHorizontalInput = !Mathf.Approximately(horizontal, 0f); //horizontal与0是否大约相等
      bool hasVerticalInput = !Mathf.Approximately(vertical, 0f);   //vertical与0是否大约相等
      bool isWalking = hasHorizontalInput || hasVerticalInput;      //如果有水平或者竖直输入,则判断为在行走

      //设置动画参数
      m_Animator.SetBool("IsWalking", isWalking);

      //设置脚步声
      if (isWalking)                      //如果在角色行走   
      {
            if (!m_AudioSource.isPlaying)   //且脚步声不在播放
            {
                m_AudioSource.Play();       //播放脚步声
            }
      }
      else
      {
            m_AudioSource.Stop();         //不行走时停止播放
      }

      //旋转向量
      Vector3 desiredForward = Vector3.RotateTowards
            (transform.forward, m_Movement, turnSpeed * Time.deltaTime, 0f);//(现在前方向量,目标方向向量,角速度,向量大小变化)
      m_Rotation = Quaternion.LookRotation(desiredForward);
    }

    //当播放动画的时候,调用刚体控制角色运动
    private void OnAnimatorMove()
    {
      //移动
      m_Rigidbody.MovePosition(m_Rigidbody.position + m_Movement * m_Animator.deltaPosition.magnitude);
      //旋转
      m_Rigidbody.MoveRotation(m_Rotation);
    }
}
修改完成后记得保存脚本哦。

4.给Ghost添加并设置音效
(1)打开Ghost预制体准备进行编辑。
(2)把SFXGhostMove拖到Ghost预制体中。



(3)设置其Audio Source组件参数:

[*]Loop:勾选,因为Ghost一直在巡逻。
[*]Volume(音量):0.4。
[*]Spatial Blend:1,3D模式。
(4)调节3D Sound Settings
我们需要Ghost的音亮随着距离从远到近,渐渐变大。

[*]Max Distance(传播的最大距离):10。
[*]Volume Rolloff(音量衰减曲线):Logarithmic Rolloff(对数衰减)从改为Custom Rolloff(自定衰减),使用默认的自定义曲线。
[*]Spread:180,设置传播角度,当设置为180的时候,声音的一半会都传到每个声道中。



5.修改Listener组件
如果Audio Listener在Camera上,Ghost只有在靠近Camera的时候,音量才会越来越大,而不是越靠近John音量越大。因此我们需要把Audio Listener组件“搬”到John上。

[*]删除Main Camera上的Audio Listener组件。
[*]打开John的预制体,添加Audio Listener组件。
设置完毕后,保存场景。进行到这里,我们基本上算是完成了这个小游戏,戴上耳机试试效果吧。

三、制作.exe文件
1.点击左上角菜单栏,File > Build Settings。(菜单栏Edit > Project Settings...>Player窗口中还有一些分辨率之类的设置,有兴趣的小伙伴可以自行研究,并不影响以下操作)


2.保持其他默认设置,点击Build,最后选择一个文件夹存放生成的文件。



结语:恭喜坚持到这里的小伙伴,你们已经完成了这个小游戏,希望这个系列的教程能够对萌新们入门有所帮助。对Unity有一些基础认识后,你们阔以开启自己新坑啦~(撒花)
John Lemon's Haunted Jaunt官方教程:https://learn.unity.com/project/john-lemon-s-haunted-jaunt-3d-beginner
咱们的游戏开发交流群也欢迎强势插入:869551769
希望参与线下游戏开发学习的,欢~~~~~~迎访问:http://www.levelpp.com/

jquave 发表于 2022-1-4 19:07

一个暑假完成了2333

xiaozongpeng 发表于 2022-1-4 19:13

提个问题,为什么控制y失败音效那里的 m_HasAudioPlayed = true;这句没写的话就不播放啊?我理解的结果应该是不停的播放啊?

七彩极 发表于 2022-1-4 19:16

两天结束,完结撒花
[欢呼]

pc8888888 发表于 2022-1-4 19:25

为什么游戏退不出去0.0
页: [1]
查看完整版本: Unity暑期萌新入门:音频篇(完)