-1

I'm trying to make a game where you jump over spikes. My player is a GameObject with a "PlayerScript" script. My spikes are a prefab with a circle collider as a trigger. I have a script in the spike prefab called "PlayerDetectScript", where I have this code :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class PlayerDetectScript : MonoBehaviour
{
    public bool Screen;
    void Start()
    {
        Screen = false;
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        Screen = true;
    }
}

In my PlayerScript code, I want to make the player jump if I press space, onGround == true, and Screen == false.

I have the first 2 covered, but even with all of the chatGPT and stack overflow, I couldn't get the Screen == true to work. I don't know how to check if a variable is something when the variable is in another file.

public class PlayerScript : MonoBehaviour
{
    public Rigidbody2D rigidBody;
    public float jumpStrength;
    public bool onGround;
    public float currentRotation;
    public GameObject PlayerDetectScript;
    PlayerDetectScript detectScript;
    public bool Screen = false;

    void Start()
    {
        detectScript = GameObject.FindGameObjectWithTag("screen").GetComponent<PlayerDetectScript>();
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space) && onGround && detectScript.Screen == false)
        {
         //something
        }
    }
}

Also I suck a c#.

Good Coder
  • 33
  • 4
  • Because you're reloading the scene with `SceneManager.LoadScene(SceneManager.GetActiveScene().name);` everything in that scene is going to reset to it's default value, so you're setting `Screen` to true but because you're reloading the scene its immediately going to be set to false again in `Start()` – A-Fairooz Aug 10 '23 at 15:31
  • As it is now it seems that you have many spikes clones each having its own PlayerDetectScript with Screen variable. – Nikaas Aug 11 '23 at 03:43

2 Answers2

0
private void OnTriggerEnter2D(Collider2D collision)
{
    bool isSpike = collision.TryGetComponent(out Spike spike);
    if(isSpike)
    {
       spike.Screen = true;
    }

}

Add above code in PlayerScript. Create Spike.cs and add spike prefab.

public class Spike: MonoBehaviour
{
  public bool Screen;
  void Start()
  {
    Screen = false;
  }
}
0

There are multiple ways to access variables in different scripts.

The simplest option is to just assign it in the inspector. Everything in Unity is derived from the Object class, with MonoBehaviours deriving from the Component class. If you're new to C# or Unity that probably won't mean anything, but the takeaway is this: The scripts you write can be handled the same way as the components that come with Unity, so for example a collider or a Rigidbody.

So in your script, you can create a variable for the other script you want to access, and show it in the inspector:

//You can then just drag the PlayerDetectscript into this slot in the inspector
[SerializeField] PlayerDetectScript detectScript;

You could also just assign the GameObject, and then use a GetComponent (Remember, your script is a component), and get it that way:

//You can then just drag the PlayerDetectscript into this slot in the inspector
[SerializeField] GameObject detectScriptObject;

void Start()
{
    detectScriptObject.GetComponent<PlayerDetectScript>()... //You would want to save this to a variable somewhere, as GetComponent is expensive!

//If the script is placed on a child object you can use GetComponentInChildren

}

What you have already done with FindObjectOfType is also valid, but that is an incredibly expensive operation and there isn't usually a time where it's actually the best option to use. If you want to access something without having to manually assign it in the inspector, then you should consider making it static:

public class PlayerDetectScript : MonoBehaviour
{
    public static bool Screen; //This will be accessible by any script by typing 'PlayerDetectScript.Screen'
    void Start()
    {
        Screen = false;
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        Screen = true;
    }
}

Static, or global variables are something to be careful with. Overuse is considered bad practice, but they certainly have their uses. The thing to understand with static variables is that they are singular. There will only ever be one. So you can have multiple instances of your PlayerDetectScript class, but they will all be "sharing" that one variable and its value.

Using this same logic, we can make the entire class static, or otherwise known as a Singleton. Again, there can only be one of these in the scene, so it's a good idea to enforce that in the class:

public class PlayerDetectScript : MonoBehaviour
{
    public static PlayerDetectScript instance; 
    //This is how we will access this instance from other scripts.
    //If the concept of an instance is confusing, 
    //just think about how you can put multiple of this script on different gameObjects. 
    //There will be multiple PlayerDetectScripts all running. 
    //With a singleton we don't want that, there will just be one that is global.
    
    public bool Screen; 
    void Start()
    {
        //Make sure there is only ever one of this Singleton class
        if(instance != null)
        { 
           Destroy(this);   
        }
        else
        {
           instance = this;
        }
    }
}

As savasosmnglu answered, you can also get the component from the OnTriggerEnter (and OnCollisionEnter) methods, as shown in their answer.

A-Fairooz also mentioned about reloading the scene. If you are reloading/changing the scene and want your script to remain, just add this to it:

void Start()
{
    DontDestroyOnLoad(this); //This does what it says on the tin really
}

I hope this helps clear up how you can access other scripts in Unity. If there is anything I have explained poorly please let me know so I can follow up with a better explanation.

TheG
  • 36
  • 4