How do i make cassette tape play in game?

Hi Am creating my first demo game and I am having trouble with the last important C# script when making.:face_with_spiral_eyes:
Basically the character grabs a cassette tape and the player can use 5 features in tape mode.:smile:
Like play, stop, forward, backwards, and escape to get out of tape mode. The player can walk around while playing the tape. And hopefully the esc key doesn’t interfere with the pause script.

All I really need is a basic template where I can really modify it to my own scripting needs. And maybe other Dev’s out there who really want to use this script also.:wink:

The console say’s:

NullReferenceException: Object reference not set to an instance of an object
TapePickup.Update () (at Assets/Scripts/TapePickup.cs:50)

That could be why it’s not working. But I feel like I probably need a better script what I made.
I am using Unity 5.3.3f1
here’s what I made in For Tape Pick Up:

using UnityEngine;
using System.Collections;

public class TapePickUp : MonoBehaviour {

    public AudioClip TapeGrab;
    public GameObject Tape;
    public float interactDistance = 5f;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Mouse0))
        {
            Ray ray = new Ray(transform.position, transform.forward);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit, interactDistance))
            {
                if (Input.GetKeyDown(KeyCode.UpArrow))
                {
                    AudioSource audio = GetComponent<AudioSource>();
                    audio.Play();
                    Debug.Log("Play Tape");
                }

                if (Input.GetKeyDown(KeyCode.DownArrow))
                {
                    AudioSource audio = GetComponent<AudioSource>();
                    audio.Stop();
                    Debug.Log("Stop Tape");
                }

                if (Input.GetKeyDown(KeyCode.RightArrow))
                {
                    AudioSource audio = GetComponent<AudioSource>();
                    audio.Play();
                    Time.timeScale = 3f;
                    Debug.Log("Forward Tape");
                }

                if (Input.GetKeyDown(KeyCode.LeftArrow))
                {
                    AudioSource audio = GetComponent<AudioSource>();
                    audio.Play();
                    Time.timeScale = -3f;
                    Debug.Log("Rewind Tape");
                }

            }
            GameObject Tape_01 = GameObject.Find("Tape");
            if (hit.collider.CompareTag("Tape"))
            {
                if (Tape_01 != null)
                Destroy(hit.collider.gameObject);
                Debug.Log("Tape gone.. O_o");
            }

        }
    }
}

most like, can you post the complete error (including the line number at the end)

Right. Let me update that in my first comment. :smile:

NullReferenceException: Object reference not set to an instance of an object
TapePickup.Update () (at Assets/Scripts/TapePickup.cs:50)

the code block between lines 50 and 55 depends on the hit which is only instantiated by the raycast on line 16 (hit being populated in the scope of the if statement lines 17-48, but not outside).

What are you trying to do with that block specifically, it appears to be the “destroy tape” block which you don’t want within the raycast’s if as it stands as it would destroy the tape immediately
 I’m assuming there needs to be some logic added like “if the tape ran out, destroy it”?

What about if I delete all the coding the from 25-47 and I will have one function to press for the Cassette tape. Like grab mouse button 1 and press up arrow to press play tape. The the other features that aren’t really important. (for now).I will see if that works.

I tried fixing the problem nothing happened what I did. I deleted some code and I even started from scratch, and nothing. I think the ray cast needs to be on the interact script for the character. And ray cast shouldn’t be on tape pick up script at all.

Hey I fixed it the problem. I had to turn the Tape script like it’s a door key. And all the ray casting coding goes in the player interact Script. I had to use 4 Scripts to make this really work.

1.TapePickUp ( contains index of object)
2. Interact script ( The function of the object)
3. Inventory (The collections of Objects)
4. DestroyObject ( Get rid of Object)
And the object is the tape.

This is TapePickUp

using UnityEngine;
using System.Collections;

public class TapePickUp : MonoBehaviour
{
    public int index = -1;
}

This is Interact Script

using UnityEngine;
using System.Collections;

public class InteractScript : MonoBehaviour
{

    public float interactDistance = 5f;
    public AudioClip keyPickup;
    public AudioClip TapePickSound;
    public AudioClip TapeClip;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Mouse0))
        {
            Ray ray = new Ray(transform.position, transform.forward);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit, interactDistance))
            {
                if (hit.collider.CompareTag("Door"))
                {
                    DoorScript doorScript = hit.collider.transform.parent.GetComponent<DoorScript>();
                    if (doorScript == null) return;

                    if (doorScript.name == "hinge")
                    {
                        doorScript.ChangeDoorState();
                        return;
                    }

                    if (Inventory.Keys[doorScript.index] == true)
                    {
                        doorScript.ChangeDoorState();
                    }

                }
                else if (hit.collider.CompareTag("Key"))
                {
                    Inventory.Keys[hit.collider.GetComponent<Key>().index] = true;
                    AudioSource.PlayClipAtPoint(keyPickup, hit.collider.transform.position);
                    Destroy(hit.collider.gameObject);
                }
                else if (hit.collider.CompareTag("Tape"))
                {
                    Inventory.Tapes[hit.collider.GetComponent<TapePickUp>().index] = true;
                    AudioSource.PlayClipAtPoint(TapePickSound, hit.collider.transform.position);
                    AudioSource.PlayClipAtPoint(Tap, hit.collider.transform.position);
                    Destroy(hit.collider.gameObject);

                }
            }

        }
    }
}

and this is Inventory

using UnityEngine;
using System.Collections;

public class Inventory : MonoBehaviour
{

    public static bool[] Keys = new bool[5];
    public static bool[] Tapes = new bool[6];

    void Start()
    {
        Keys[0] = false;
        Keys[1] = false;
        Keys[2] = false;
        Keys[3] = false;
        Keys[4] = false;
        Tapes[0] = false;
        Tapes[1] = false;
        Tapes[2] = false;
        Tapes[3] = false;
        Tapes[4] = false;
        Tapes[5] = false;
    }
}

and last Destroy object

using UnityEngine;
using System.Collections;

public class DestoryObject : MonoBehaviour {

    void OnCollisionEnter(Collision col)
    {
        if (col.gameObject.name == "Key 01")
        {
            Destroy(col.gameObject);
        }
        if (col.gameObject.name == "Tape_01")
        {
            Destroy(col.gameObject);
        }
    }
}

Why not make it all one script?

Also things like your inventory script would be simpler with a foreach loop.