2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 Программа не может открыть аудио-файл (скрипт C#, "Unity")
Сообщение07.08.2022, 12:57 
Аватара пользователя


13/02/18
1070
Україна, село
Есть компьютерная программа для создания видео-игр (хотя на ней много чего можно делать, даже визуализировать простенькие физические опыты, там встроенная симуляция механики есть), которая называется "Unity" (да, как модуль к Международной Космической Станции, но к космосу отношения не имеет), программа эта использует язык программирования C# для своих внутренних целей, а именно создания скрипт-программ, скриптов так называемых.
Следуя вот этой инструкции — "Audio", пункт номер четыре, было добавлено аудиофайл, но этот шайтан-программа не проигрывает его и ругается следующим...

Код:
ArgumentNullException: Value cannot be null.
Parameter name: source
UnityEngine.AudioSource.PlayOneShot (UnityEngine.AudioClip clip, System.Single volumeScale) (at <e47743e68760443e90610e227d064273>:0)
UnityEngine.AudioSource.PlayOneShot (UnityEngine.AudioClip clip) (at <e47743e68760443e90610e227d064273>:0)
Idiotic_Ruby_Controller.PlaySound (UnityEngine.AudioClip clip) (at Assets/Scripts/Idiotic_Ruby_Controller.cs:140)
HealthCollectible.OnTriggerEnter2D (UnityEngine.Collider2D other) (at Assets/Scripts/HealthCollectible.cs:19)

Ошибки на линии сто сорок — audio_source.PlayOneShot(clip), и девятнадцять — controller.PlaySound(Collected_clip), соответствующих скриптов. Вот код скриптов, которые не нравятся программе...

(Idiotic_Ruby_Controller)

Код:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Idiotic_Ruby_Controller : MonoBehaviour
{
    public int maxHealth = 5;
   
    public float time_invincible = 2.0f;

    public float maxSpeed = 3.0f;
   
    public int health { get { return currentHealth; } }
   
    public GameObject projectile_prefab;
   
    public ParticleSystem Get_Hit;
   
    public ParticleSystem Consume_Health_Potion;

    int currentHealth;
   
    bool is_invincible;
    float invincible_timer;

    Rigidbody2D rigidbody2d;
    float horizontal;
    float vertical;
   
    Animator animator;
    Vector2 look_direction = new Vector2(1, 0);
   
    AudioSource audio_source;

    // Start is called before the first frame update.
    void Start()
    {
        animator = GetComponent<Animator>();
        rigidbody2d = GetComponent<Rigidbody2D>();
        currentHealth = maxHealth;
        audio_source = GetComponent<AudioSource>();
    }

    // Update is called once per frame.
    void Update()
    {
        horizontal = Input.GetAxis("Horizontal");
        vertical = Input.GetAxis("Vertical");
        Vector2 move = new Vector2(horizontal, vertical);
       
        if (!Mathf.Approximately(move.x, 0.0f) || !Mathf.Approximately(move.y, 0.0f))
        {
            look_direction.Set(move.x, move.y);
            look_direction.Normalize();
        }
       
        animator.SetFloat("Look X", look_direction.x);
        animator.SetFloat("Look Y", look_direction.y);
        animator.SetFloat("Speed", move.magnitude);
       
        if (is_invincible)
        {
            invincible_timer -= Time.deltaTime;
            if (invincible_timer < 0)
                is_invincible = false;
        }
       
        if (Input.GetKeyDown(KeyCode.X))
        {
            RaycastHit2D hit = Physics2D.Raycast(rigidbody2d.position + Vector2.up*0.2f, look_direction, 1.5f, LayerMask.GetMask("NPC"));
           
            // All you are doing here is checking if we have a hit, then trying to find a NonPlayerCharacter script on the object the Raycast hit, and if that script exists on that object, you will display the dialog.
            if (hit.collider != null)
            {
                Non_Player_Character character = hit.collider.GetComponent<Non_Player_Character>();
                if (character != null)
                {
                    character.Display_Dialog();
                }
                //Displaying what hit character from NPC layer in the Console.
                //Debug.Log("Ray has hit the object " + hit.collider.gameObject);
            }
        }

        if (Input.GetKeyDown(KeyCode.C))
        {
            Launch();
        }
    }

    void FixedUpdate()
    {
        Vector2 position = rigidbody2d.position;
        position.x = position.x + maxSpeed*horizontal*Time.deltaTime;
        position.y = position.y + maxSpeed*vertical*Time.deltaTime;
        rigidbody2d.MovePosition(position);
    }
   
    public void ChangeHealth (int amount)
    {
        // Animation increasing health.
        if (amount > 0)
        {
            Instantiate(Consume_Health_Potion, rigidbody2d.position, Quaternion.identity);
        }

        if (amount < 0)
        {
            animator.SetTrigger("Hit");
            Instantiate(Get_Hit, rigidbody2d.position + Vector2.up*1.0f, Quaternion.identity);
           
            if (is_invincible)
                return;

            is_invincible = true;
            invincible_timer = time_invincible;
        }
        currentHealth = Mathf.Clamp(currentHealth + amount, 0, maxHealth);

        //Making changes into UI-Healthbar.
        UI_Health_Bar.instance.SetValue(currentHealth / (float)maxHealth);
           
        //Showing health due to debug console.
        //Debug.Log(currentHealth + "/" + maxHealth);
    }
   
    //Launching cog program function.
    void Launch()
    {
        GameObject projectile_object = Instantiate(projectile_prefab, rigidbody2d.position + Vector2.up*0.5f, Quaternion.identity);
        Projectile projectile = projectile_object.GetComponent<Projectile>();
        projectile.Launch(look_direction, 300);
       
        animator.SetTrigger("Launch");
    }
   
    //Playing sounds of interacted objects.
    public void PlaySound(AudioClip clip)
    {
        audio_source.PlayOneShot(clip);
    }
}

(HealthCollectible)

Код:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class HealthCollectible : MonoBehaviour
{
    public AudioClip Collected_clip;
   
    void OnTriggerEnter2D (Collider2D other)
    {
         Idiotic_Ruby_Controller controller = other.GetComponent<Idiotic_Ruby_Controller>();
         
         if (controller != null)
         {
            //Calling programs from main character script.
            if (controller.health < controller.maxHealth)
            {
                controller.ChangeHealth(1);
                controller.PlaySound(Collected_clip);
                Destroy(gameObject);
            }
         }

        //Debug.Log("Object that entered the trigger: " + other);
    }
}

Было опробовано — удалить с кода HealthCollectible строку Destroy(gameObject), то есть логика в чем? — Может оно уничтожает обьект и поэтому не проигрывает звук, но не помогло. Более того, даже с программой Destroy(gameObject) оно его не уничтожает, хотя должно, то есть программа "заклинивается" на controller.PlaySound(Collected_clip) и все... Я ничего не пойму, это программирование немного раздражает, потому-что непонятно что оно вообще делает и откуда берется ошибка.

 Профиль  
                  
 
 Re: Программа не может открыть аудио-файл (скрипт C#, "Unity")
Сообщение07.08.2022, 20:54 


27/08/14
206
У вас Collected_clip не присвоено значение. Проверьте что выполнен пункт 4 инструкции:
Цитата:
4. Now check your Health Collectible Prefab in your Project window. A new slot called Collected Clip is now available on the Health Collectible component as you made that variable public. Drag and drop the Collectable audio clip you can find in the Audio folder into that slot.

 Профиль  
                  
 
 Re: Программа не может открыть аудио-файл (скрипт C#, "Unity")
Сообщение08.08.2022, 18:57 
Аватара пользователя


13/02/18
1070
Україна, село
Progger в сообщении #1562062 писал(а):
У вас Collected_clip не присвоено значение.
Присвоено это значение.

Изображение

Смысл инструкции в следующем: чтобы не создавать программу "Audio Source" для каждого объекта в так называемой сцене, мы создаем вышеупомянутую программу только для объекта главного персонажа допустим, а в штукенциях что должны выдавать некие звуки при взаимодействии, мы создаем новую переменную к которой будет присоединен звуковой файл, и к которой будет обращаться "Audio Source" главного персонажа.
Переменная типа "аудио-клип" в объекте "вишня", к которой извне можно присоединить ауди-файл.

Код:
public AudioClip Collected_clip;

Программа в коде главного персонажа, которая запускает звук с переменной clip.

Код:
public void PlaySound (AudioClip clip)
    {
        audio_source.PlayOneShot(clip);
    }

Перекачка видео-файла в вышеупомянутую программу clip.

Код:
Idiotic_Ruby_Controller controller = other.GetComponent<Idiotic_Ruby_Controller>();

Код выше вызывается при столкновении объектов, оно закачивает в controller скрипт-программу Idiotic_Ruby_Controller. После этого запускается последовательность в которой проигрывается файл.

Код:
if (controller.health < controller.maxHealth)
            {
                controller.PlaySound(Collected_clip);
            }

Вот именно с помощью тех средств, что загрузились в главного персонажа, а вишня без этой, без дополнительных аудио этих штук, что должно оптимизировать видео-игру. Но по факту, оно тупо стопорит весь процесс, причем именно так, что сам объект вишня не исчезает, но хитпоинтов добавляет, тупизна какая-то... :facepalm: Второй день с этим бредом разбираюсь. Мне уже рекомендуют поменять программу "Юнити" на "Love2D" — а там "чистый лист", блокнот, и создавайте видео-игру...

 Профиль  
                  
 
 Re: Программа не может открыть аудио-файл (скрипт C#, "Unity")
Сообщение09.08.2022, 07:51 
Аватара пользователя


13/02/18
1070
Україна, село
Решено! С помощью человека с интернета. Вся суть была в глупой инструкции, которая сначала объяснила как добавлять к так называемой сцене Auido Source программу как объект, а затем, без объяснений, сказала добавить еще одно такое к объекту главного персонажа, из-за чего я добавил дочерний объект, а надо было компонент.

Проблема: система запрещает доступ к другим объектам в сцене со скрипта GetComponent<Component_Name>(), который расположен "внутри" какого-то конкретного, иного объекта. Даже доступ к дочерним объектам запрещается.

Решение: создать компонент вместо дочернего объекта, к компонентам объекта доступ "внутренним" скриптом разрешается.

Код который помог понять что, к чему...

Код:
public void PlaySound (AudioClip clip)
    {
        //if(audio_source == null)
            //Debug.Log("Audio source is null");
        //if(clip == null)
            //Debug.Log("Audio clip is null");

        audio_source.PlayOneShot(clip);
    }

Оно закомментировано, то есть не должно обрабатывается так называемым компилятором. Этот код, расcкоментированный естественно, выдал что Audio source is null, таким образом дав понять — проблема не в аудио-клипе, а именно в программе Audio Source! Точней в ее по сути отсутствие для скрипта...

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 4 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group