21.音效特效添加

21.游戏场景-音效特效添加


21.1 知识点

在GameDataMgr脚本中添加播放音效的方法。接受一个音效资源名称作为参数。创建一个新的游戏对象用于播放音效,在游戏对象上添加音频源组件,并从资源中加载指定名称的音频剪辑,并设置给音频源组件。根据音乐数据中设置的音效音量值设置音频源组件的音量。根据音乐数据中设置的音效开关状态设置音频源组件的静音属性。最后,播放音效,并在1秒后销毁游戏对象,释放资源。

/// <summary>
/// 播放音效方法
/// </summary>
/// <param name="resName">音效资源名称</param>
public void PlaySound(string resName)
{
    // 创建一个新的游戏对象用于播放音效
    GameObject musicObj = new GameObject();

    // 在游戏对象上添加音频源组件
    AudioSource a = musicObj.AddComponent<AudioSource>();

    // 从资源中加载音频剪辑并设置给音频源组件
    a.clip = Resources.Load<AudioClip>(resName);

    // 设置音量为音乐数据中设置的音效音量值
    a.volume = musicData.soundValue;

    // 根据音乐数据中设置的音效开关状态设置音频源组件的静音属性
    a.mute = !musicData.soundOpen;

    // 播放音效
    a.Play();

    // 在1秒后销毁游戏对象,释放资源
    GameObject.Destroy(musicObj, 1);
}

在PlayerObject脚本的刀枪事件中添加播放音效逻辑。把开枪特效预制体放到Resource下,在开枪命中的时候添加爆炸特效对象。特效路径是在角色配置文件中配置好的。设置好特效位置再怪物命中点上,设置好旋转,一秒后销毁对象。

/// <summary>
/// 专门用于处理刀武器攻击动作的伤害检测事件
/// </summary>
public void KnifeEvent()
{
    //进行伤害检测
    Collider[] colliders = Physics.OverlapSphere(this.transform.position + this.transform.forward + this.transform.up, 1, 1 << LayerMask.NameToLayer("Monster"));

    //播放音效
    GameDataMgr.Instance.PlaySound("Music/Knife");

    //暂时无法继续写逻辑了 因为 我们没有怪物对应的脚本
    for (int i = 0; i < colliders.Length; i++)
    {
        //得到碰撞到的对象上的怪物脚本 让其受伤
        MonsterObject monster = colliders[i].gameObject.GetComponent<MonsterObject>();
        if (monster != null)
        {
            monster.Wound(this.atk);
            break;
        }
    }
}

public void ShootEvent()
{
    //进行摄像检测 
    //前提是需要有开火点
    RaycastHit[] hits = Physics.RaycastAll(new Ray(gunPoint.position, gunPoint.forward), 1000, 1 << LayerMask.NameToLayer("Monster"));

    //播放开枪音效
    GameDataMgr.Instance.PlaySound("Music/Gun");

    for (int i = 0; i < hits.Length; i++)
    {
        //得到碰撞到的对象上的怪物脚本 让其受伤
        MonsterObject monster = hits[i].collider.gameObject.GetComponent<MonsterObject>();
        if (monster != null)
        {
            //进行打击特效的创建
            GameObject effObj = Instantiate(Resources.Load<GameObject>(GameDataMgr.Instance.nowSelRole.hitEff));
            effObj.transform.position = hits[i].point;
            effObj.transform.rotation = Quaternion.LookRotation(hits[i].normal);
            Destroy(effObj, 1);

            monster.Wound(this.atk);
            break;
        }
    }
}

在MonsterObject脚本中的受伤死亡攻击事件方法中添加音效逻辑

//受伤
public void Wound(int dmg)
{
    //减少血量
    hp -= dmg;
    //播放受伤动画
    animator.SetTrigger("Wound");

    if( hp <= 0 )
    {
        //死亡
        Dead();
    }
    else
    {
        //播放音效
        GameDataMgr.Instance.PlaySound("Music/Wound");
    }
}

//死亡
public void Dead()
{
    isDead = true;
    //停止移动
    agent.isStopped = true;
    //播放死亡动画
    animator.SetBool("Dead", true);

    //播放音效
    GameDataMgr.Instance.PlaySound("Music/dead");
    //加钱——我们之后通过关卡管理类 来管理游戏中的对象 通过它来让玩家加钱 
}
    

//伤害检测
public void AtkEvent()
{
    //范围检测 进行伤害判断
    Collider[] colliders = Physics.OverlapSphere(this.transform.position + this.transform.forward + this.transform.up, 1, 1 << LayerMask.NameToLayer("MainTower"));

    //播放音效
    GameDataMgr.Instance.PlaySound("Music/Eat");

    for (int i = 0; i < colliders.Length; i++)
    {
        if( MainTowerObject.Instance.gameObject == colliders[i].gameObject)
        {
            //让保护区域受到伤害
            MainTowerObject.Instance.Wound(monsterInfo.atk);
        }
    }
}

在开始场景的躺着的怪物动画中,由于添加了死亡事件,所以一直会报错。不能让一个动画文件又有事件又没事件。解决办法是多复制一个动画文件,删除上面的事件重新关联



转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏