找回密码
 立即注册
查看: 259|回复: 4

[简易教程] Unity暑期萌新入门:音频篇(完)

[复制链接]
发表于 2022-1-4 19:04 | 显示全部楼层 |阅读模式
大渣好。在本篇中将通过会为游戏添加音效,进一步烘托气氛,完成后制作.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,分别重命名为EscapeCaught
(2)按住Ctrl同时选中EscapeCaught,修改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
②把AmbientEscapeCaught 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/

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
发表于 2022-1-4 19:07 | 显示全部楼层
一个暑假完成了2333
发表于 2022-1-4 19:13 | 显示全部楼层
提个问题,为什么控制y失败音效那里的 m_HasAudioPlayed = true;这句没写的话就不播放啊?我理解的结果应该是不停的播放啊?
发表于 2022-1-4 19:16 | 显示全部楼层
两天结束,完结撒花
[欢呼]
发表于 2022-1-4 19:25 | 显示全部楼层
为什么游戏退不出去0.0
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-5-6 17:46 , Processed in 0.105719 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表