Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么即使不按任何一个3D对象材质,它们也会发出声音?_C#_Visual Studio_Unity3d_Game Development - Fatal编程技术网

C# 为什么即使不按任何一个3D对象材质,它们也会发出声音?

C# 为什么即使不按任何一个3D对象材质,它们也会发出声音?,c#,visual-studio,unity3d,game-development,C#,Visual Studio,Unity3d,Game Development,我和我的朋友正在尝试为手机制作一个钢琴应用程序。我们的钢琴键盘“键”是16个彼此相邻的3D对象。问题是,当我在屏幕上几乎任何地方按下时,它会同时播放我放在3D对象上的所有音频剪辑。我尝试了多个脚本,但它们都有相同的问题或不同的解决方案。 以下是我当前使用的脚本: 顺便说一句,我仍然是Unity和C的不速之客,所以欢迎大家的帮助。:) 使用UnityEngine; 使用系统集合; 使用UnityEngine.UI; 使用UnityEngine.Audio; [所需组件(类型(音频源))] 公共类关

我和我的朋友正在尝试为手机制作一个钢琴应用程序。我们的钢琴键盘“键”是16个彼此相邻的3D对象。问题是,当我在屏幕上几乎任何地方按下时,它会同时播放我放在3D对象上的所有音频剪辑。我尝试了多个脚本,但它们都有相同的问题或不同的解决方案。 以下是我当前使用的脚本:

顺便说一句,我仍然是Unity和C的不速之客,所以欢迎大家的帮助。:)

使用UnityEngine;
使用系统集合;
使用UnityEngine.UI;
使用UnityEngine.Audio;
[所需组件(类型(音频源))]
公共类关键1:单一行为
{
声源;声源;
触摸触摸;
void Start()
{
AudioSource=GetComponent();
}
无效更新()
{
如果(Input.touchCount>0)
{
theTouch=Input.GetTouch(0);
如果(触摸阶段==触摸阶段开始)
{
AudioSource.Play();
}
如果(触摸阶段==触摸阶段结束)
{
AudioSource.Stop();
}
if(touch.phase==touch.Moved)
{
AudioSource.Stop();
}
如果(touch.phase==touch.phase.cancelled)
{
AudioSource.Stop();
}
}
}
}

首先,您可能不需要在每个“键”上都使用音频源。如果你只想播放声音,一个就足够了。然而,如果你想要3D声音,左边的按键在你的左扬声器上,那么你需要在每个按键上都有一个音频源

要知道播放哪个键,可以从屏幕位置(单击的位置)向3D世界进行简单的光线投射。您只需要执行一次光线投射,因此不要在关键脚本中执行。如果您对没有3D声音感到满意,请将其与音频源一起移动到单独的脚本中

using UnityEngine;
using UnityEngine.Assertions;

public class Piano : MonoBehaviour
{
    AudioSource audioSource;

    private void Awake()
    {
        audioSource = GetComponent<AudioSource>();
        Assert.IsNotNull(audioSource);
    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            // The user has clicked (or touched) on the screen. Convert it to a position in the 3D world:
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {
                // The user has clicked on a Collider. Does it have a Key script on it?
                Key key = hit.collider.GetComponent<Key>();
                if(key != null)
                {
                    // The user clicked on a key. Play the sound (without interrupting previous sounds).
                    audioSource.PlayOneShot(key.clip);
                }
            }
        }
    }
}

如果您想要3D声音,请将音频源移动到按键(每个按键上有一个音频源)。然后钢琴代码将类似于:

using UnityEngine;

public class Piano : MonoBehaviour
{
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            // The user has clicked (or touched) on the screen. Convert it to a position in the 3D world:
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {
                // The user has clicked on a Collider. Does it have a Key script on it?
                Key key = hit.collider.GetComponent<Key>();
                if(key != null)
                {
                    key.Play();
                }
            }
        }
    }
}
使用UnityEngine;
公共课钢琴:独奏
{
无效更新()
{
if(Input.GetMouseButtonDown(0))
{
//用户已单击(或触摸)屏幕。将其转换为3D世界中的某个位置:
Ray-Ray=Camera.main.screenpointoray(输入.鼠标位置);
雷卡斯特击中;
如果(物理.光线投射(光线,出击))
{
//用户已单击碰撞器。它是否有关键脚本?
Key=hit.collider.GetComponent();
if(key!=null)
{
键。Play();
}
}
}
}
}
关键的脚本是:

using UnityEngine;
using UnityEngine.Assertions;

public class Key : MonoBehaviour
{
    // You could also simply add the sound to the audioSource from the editor.
    public AudioClip clip;
    AudioSource audioSource;

    private void Awake()
    {
        audioSource = GetComponent<AudioSource>();
        Assert.IsNotNull(audioSource);
    }

    public void Play()
    {
        audioSource.PlayOneShot(clip);
    }
}
使用UnityEngine;
使用UnityEngine.Assertions;
公共类密钥:MonoBehavior
{
//您也可以简单地从编辑器向音频源添加声音。
公共音频剪辑;
声源;声源;
私人空间
{
audioSource=GetComponent();
Assert.IsNotNull(音频源);
}
公共游戏
{
音频源:PlayOneShot(剪辑);
}
}

最后,一个3D声音的触摸版。这与前面的示例非常相似,但我们现在还跟踪按键按下的时间

与之前一样,我们使用光线投射来获取用户按下的键。但是我们也存储了fingerId,这样我们就知道它是哪根手指,并且可以在释放手指时释放右键

在本例中,声音片段与音频源一起存储

using UnityEngine;

public class Piano : MonoBehaviour
{
    Key[] allKnownKeys;

    private void Awake()
    {
        allKnownKeys = FindObjectsOfType<Key>();
    }

    void Update()
    {
        foreach (Touch touch in Input.touches)
        {
            if (touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled)
            {
                // Get the key using the fingerID (the finger that pressed down the key)
                Key key = GetKey(touch.fingerId);
                // Was it a key that was released?
                if(key != null)
                    key.Stop();
            }
            else if(touch.phase == TouchPhase.Began)
            {
                // New touch on the screen. Convert it to a position in the 3D world:
                Ray ray = Camera.main.ScreenPointToRay(touch.position);
                RaycastHit hit;
                if (Physics.Raycast(ray, out hit))
                {
                    // The user has touched a Collider. Does it have a Key script on it?
                    Key key = hit.collider.GetComponent<Key>();
                    if (key != null)
                    {
                        key.Play(touch.fingerId);
                    }
                }
            }
        }
    }

    /// <summary>
    /// Gets the key which is already "down" (playing).
    /// </summary>
    /// <param name="fingerId"></param>
    /// <returns></returns>
    private Key GetKey(int fingerId)
    {
        foreach (Key key in allKnownKeys)
            if (key.FingerId == fingerId)
                return key;
        return null;        
    }
}
使用UnityEngine;
公共课钢琴:独奏
{
关键[]所有知识;
私人空间
{
allKnownKeys=FindObjectsOfType();
}
无效更新()
{
foreach(输入触摸,触摸)
{
如果(touch.phase==TouchPhase.end | | touch.phase==TouchPhase.cancelled)
{
//使用fingerID(按下按键的手指)获取按键
Key=GetKey(touch.fingerId);
//这是一把被释放的钥匙吗?
if(key!=null)
键。停止();
}
else if(touch.phase==TouchPhase.start)
{
//屏幕上的新触摸。将其转换为3D世界中的一个位置:
光线=摄影机.main.screenpointoray(触摸.位置);
雷卡斯特击中;
如果(物理.光线投射(光线,出击))
{
//用户触摸了碰撞器。碰撞器上是否有关键脚本?
Key=hit.collider.GetComponent();
if(key!=null)
{
键。播放(触摸。fingerId);
}
}
}
}
}
/// 
///获取已“向下”(播放)的键。
/// 
/// 
/// 
私钥GetKey(int fingerId)
{
foreach(allKnownKeys中的键)
if(key.FingerId==FingerId)
返回键;
返回null;
}
}
以及触摸版的关键脚本:

using UnityEngine;
using UnityEngine.Assertions;

public class Key : MonoBehaviour
{
    AudioSource audioSource;

    private void Awake()
    {
        audioSource = GetComponent<AudioSource>();
        Assert.IsNotNull(audioSource);
        FingerId = -1;
    }

    public void Play(int fingerId)
    {
        if (FingerId >= 0)
            return; // The key is already "down"
        FingerId = fingerId;
        audioSource.Play();
    }

    public void Stop()
    {
        FingerId = -1;
        audioSource.Stop();
    }

    public int FingerId { get; protected set; }
}
使用UnityEngine;
使用UnityEngine.Assertions;
公共类密钥:MonoBehavior
{
声源;声源;
私人空间
{
audioSource=GetComponent();
Assert.IsNotNull(音频源);
FingerId=-1;
}
公共无效播放(int fingerId)
{
如果(FingerId>=0)
return;//键已“关闭”
FingerId=FingerId;
audioSource.Play();
}
公共停车场()
{
FingerId=-1;
audioSource.Stop();
}
public int FingerId{get;protected set;}
}

因为我猜所有键都有这个,而您的脚本只检查
using UnityEngine;

public class Piano : MonoBehaviour
{
    Key[] allKnownKeys;

    private void Awake()
    {
        allKnownKeys = FindObjectsOfType<Key>();
    }

    void Update()
    {
        foreach (Touch touch in Input.touches)
        {
            if (touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled)
            {
                // Get the key using the fingerID (the finger that pressed down the key)
                Key key = GetKey(touch.fingerId);
                // Was it a key that was released?
                if(key != null)
                    key.Stop();
            }
            else if(touch.phase == TouchPhase.Began)
            {
                // New touch on the screen. Convert it to a position in the 3D world:
                Ray ray = Camera.main.ScreenPointToRay(touch.position);
                RaycastHit hit;
                if (Physics.Raycast(ray, out hit))
                {
                    // The user has touched a Collider. Does it have a Key script on it?
                    Key key = hit.collider.GetComponent<Key>();
                    if (key != null)
                    {
                        key.Play(touch.fingerId);
                    }
                }
            }
        }
    }

    /// <summary>
    /// Gets the key which is already "down" (playing).
    /// </summary>
    /// <param name="fingerId"></param>
    /// <returns></returns>
    private Key GetKey(int fingerId)
    {
        foreach (Key key in allKnownKeys)
            if (key.FingerId == fingerId)
                return key;
        return null;        
    }
}
using UnityEngine;
using UnityEngine.Assertions;

public class Key : MonoBehaviour
{
    AudioSource audioSource;

    private void Awake()
    {
        audioSource = GetComponent<AudioSource>();
        Assert.IsNotNull(audioSource);
        FingerId = -1;
    }

    public void Play(int fingerId)
    {
        if (FingerId >= 0)
            return; // The key is already "down"
        FingerId = fingerId;
        audioSource.Play();
    }

    public void Stop()
    {
        FingerId = -1;
        audioSource.Stop();
    }

    public int FingerId { get; protected set; }
}