冉583 2024-04-22 18:31 采纳率: 33.3%
浏览 7

想在unity xr 实现点击不同弦播放不同的音频

想在unity xr 实现点击不同弦播放对应的音频,是否抓取乐器无所谓,之前有尝试过简单的只要点击就播放音频,但我也不知道为什么只用audioSource.Play()不行,但抓取后使用ActivateEventArgs,audioSource.Play()可以运行。有点懵。下面的代码是把搜索的unity 3d代码更改添加了ActivateEventArgs部分,但也还是不能播放音频。应该要怎么改,可以提供点思路吗,提前先谢谢。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
public class Music : MonoBehaviour
{
    public AudioClip[] stringAudioClips;
    private AudioSource audioSource;
    public Transform[] stringTransforms;

    private void Start()
    {
        audioSource = GetComponent<AudioSource>();
        XRGrabInteractable grabbable = GetComponent<XRGrabInteractable>();
        grabbable.activated.AddListener(Playing);
    }

    private void Playing(ActivateEventArgs arg)
    {
        
            int stringIndex = GetClickedStringIndex();
            if (stringIndex >= 0 && stringIndex < stringAudioClips.Length)
            {
                audioSource.clip = stringAudioClips[stringIndex];
                audioSource.Play();
            }
        
    }

    private int GetClickedStringIndex()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;
        if (Physics.Raycast(ray, out hit))
        {
            if (hit.collider.CompareTag("String"))
            {
                for (int i = 0; i < stringTransforms.Length; i++)
                {
                    if (hit.transform == stringTransforms[i])
                    {
                        return i;
                    }
                }
            }
        }
        return -1;
    }
}




  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-04-22 18:31
    关注

    引自免费微信小程序:皆我百晓生

    为了实现点击不同弦播放不同的音频,您可以在代码中稍作调整。首先,确保您的AudioSource组件已经正确地附加到游戏对象上,并且检查每个字符串游戏对象("String"标签)都有一个子物体拥有Collider。此外,确保AudioClip[] stringAudioClips数组里包含了正确的音频文件。

    这里是修改后的代码:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.XR.Interaction.Toolkit;
    
    public class Music : MonoBehaviour
    {
        public AudioClip[] stringAudioClips;
        private AudioSource audioSource;
        public Transform[] stringTransforms;
    
        private void Start()
        {
            audioSource = GetComponent<AudioSource>();
    
            // 添加事件监听器至所有字符串对象的 OnSelect 和 OnDeselect 事件
            foreach (Transform stringTransform in stringTransforms)
            {
                XR交互模块组件 XRInteractiveObject interactiveObject = stringTransform.GetComponent<XRInteractiveObject>();
                if (interactiveObject != null)
                {
                    interactiveObject.Selected += StringSelected;
                    interactiveObject.Deselected += StringDeselected;
                }
            }
        }
    
        private void StringSelected(object sender, UnityEngine.XR.Interaction.Toolkit.SelectionEventData eventData)
        {
            PlayAudioForSelectedString(eventData.interactable.transform);
        }
    
        private void StringDeselected(object sender, UnityEngine.XR.Interaction.Toolkit.SelectionEventData eventData)
        {
            StopAudio();
        }
    
        private void PlayAudioForSelectedString(Transform selectedString)
        {
            int stringIndex = Array.IndexOf(stringTransforms, selectedString);
            if (stringIndex >= 0 && stringIndex < stringAudioClips.Length)
            {
                audioSource.clip = stringAudioClips[stringIndex];
                audioSource.Play();
            }
        }
    
        private void StopAudio()
        {
            audioSource.Stop();
        }
    
        private int GetClickedStringIndex()
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {
                if (hit.collider.CompareTag("String"))
                {
                    return Array.IndexOf(stringTransforms, hit.transform.parent);
                }
            }
            return -1;
        }
    }
    

    在这个版本中,我做了以下几个改动:

    1. Start() 函数中,为每个字符串游戏对象的 XRInteractiveObject 组件添加了 OnSelectOnDeselect 事件监听器。
    2. 删除了 XRGrabInteractable 相关的代码,因为我们不需要通过抓取来触发音频播放。
    3. 新增了 StringSelectedStringDeselected 方法,分别处理字符串被选择和取消选择时的行为。
    4. 修改了 PlayAudioForSelectedString 方法,它现在接受一个 Transform 参数并根据这个参数找到相应的索引。
    5. 添加了一个 StopAudio 方法用于停止当前正在播放的音频。

    这样,在点击具有 "String" 标签的字符串时,会播放对应的音频,当不再选中时,音频将自动停止。确保所有字符串游戏对象都设置了正确的标签和子物体上的 Collider。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 4月22日

悬赏问题

  • ¥15 Windows Script Host 无法找到脚本文件"C:\ProgramData\Player800\Cotrl.vbs”
  • ¥15 matlab自定义损失函数
  • ¥15 35114 SVAC视频验签的问题
  • ¥15 impedancepy
  • ¥15 求往届大挑得奖作品(ppt…)
  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图