Есть компьютерная программа для создания видео-игр (хотя на ней много чего можно делать, даже визуализировать простенькие физические опыты, там встроенная симуляция механики есть), которая называется
"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) и все... Я ничего не пойму, это программирование немного раздражает, потому-что непонятно что оно вообще делает и откуда берется ошибка.