Vate
Vate

Reputation: 44

Unity can't acess prefab's script's variable

I am working on a 3D game on Unity but recently a problem occurred. I can't access a variable from another prefab's script. I tried it before when the object which has to be accessed wasn't a prefab and it worked correctly.

This is the script which tries to access the "slashtime" variable, but when I run it gives back 0 though in the other script the variable is changing continuously.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class collision : MonoBehaviour
{
    public GameObject sword;
    public float slashtime;



    private void Update()
    {
        slashtime=sword.GetComponent<movement>().slashtime;
    }

    private void OnTriggerEnter(Collider collider)
    {



        if (collider.tag == "sword" && slashtime+1f > Time.time)
        {

            Destroy(gameObject);
        }
    }


}

Upvotes: 1

Views: 2628

Answers (2)

user12688476
user12688476

Reputation:

You can use this. It is also working.

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

public class collision : MonoBehaviour
{
    public GameObject sword;
    public float slashtime;

    private void OnTriggerEnter(Collider collider)
    {
        sword = collider.gameObject;
        slashtime=sword.GetComponent<movement>().slashtime;
        if (collider.tag == "sword" && slashtime+1f > Time.time)
        {
            Destroy(gameObject);
        }
    }
}
  • Reason for your code is not working because when you write some code in update then it calls every frame. so when your object is destroyed, update call that code and it shown error.

Upvotes: 2

Major Productions
Major Productions

Reputation: 6062

Reworking your code a bit, with explanations below:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class collision : MonoBehaviour
{
    [SerializeField]
    private GameObject _sword;
    private float _slashTime;

    private void Start()
    {
        _slashTime = GameObject.Find("Movement").GetComponent<Movement>().GetSlashTime();
    }    

    private void OnTriggerEnter(Collider collider)
    {           
        if (collider.CompareTag("sword") && _slashTime + 1f > Time.time)
        {
            Destroy(gameObject); // What is gameObject in this context?  the _sword?  something else?
        }
    }
}
  1. Use private properties. Why? Because it increases modularity and protects the object(s) you're working with from accidentally having their values overwritten.
  2. In conjunction to this, use public methods to obtain/change the values in other objects. Public methods are your API.
  3. It's convention to begin the names of private properties with an underscore.
  4. Like I said in my comment above, you first need to Find() your desired object before you can attempt to GetComponent<T>().
  5. Like others have said, attempting to GetComponent<T>() in Update() is computationally expensive. It's better to get that component at Start() and then talk to it as necessary (in this case, during collision).
  6. CompareTag() is the more modern/accepted way to check a tag.

EDIT:

[SerializeField] will keep the property private while also making it available to the Unity editor. It's good for debugging and linking objects.

Upvotes: -1

Related Questions