Search Unity

Accesing variables through other scripts in Unity 5

Discussion in 'Scripting' started by _Oscar, May 8, 2015.

  1. _Oscar

    _Oscar

    Joined:
    Mar 18, 2015
    Posts:
    11
    I know there are many posts like this but i just can't find an answer that helps me out. So my problem is that I'm trying to acces a boolean through another script but it won't let me do that. Before I switched to Unity 5 I was able to do this but not anymore. So if someone knows how to solve this please let me know to. Thanks!
     
  2. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    can you post an example of the code you have, far easier to understand where you are going wrong if we can actually see what you are doing...


    afaik the only change to this kind of thing was the removal of the quick references like "rigidbody" so you have to explicitly do
    Code (csharp):
    1.  
    2. Rigidbody rigidbody = GetComponent<Rigidbody>();
    3.  
    to access them as you once did.
     
  3. _Oscar

    _Oscar

    Joined:
    Mar 18, 2015
    Posts:
    11
    public class MeleeSystem : MonoBehaviour {

    public int TheDammage = 25;
    public float distance;
    public float maxDistance;
    public Animation swordAnim;
    public AudioSource swordSound;
    public static bool swimming;


    // Use this for initialization
    void Start ()
    {
    swordAnim.GetComponent<Animation>();
    swordSound.GetComponent<AudioSource>();
    }

    // Update is called once per frame
    void Update ()
    {
    if (swimming == false)
    {
    if (Input.GetButtonDown("Fire1"))
    {
    swordAnim.Play("SwordAnim");
    swordSound.Play();
    AttackDammage();
    }
    }
    }

    void AttackDammage()
    {
    if (swimming == false)
    {
    RaycastHit hit;
    if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit))
    {
    distance = hit.distance;
    if (distance < maxDistance)
    {
    hit.transform.SendMessage("ApplyDammage", TheDammage, SendMessageOptions.DontRequireReceiver);
    }
    }
    }
    }
    }

    I'm trying to acces the swimming bool through the FirstPersonController like this

    private bool m_Jumping;
    private AudioSource m_AudioSource;
    private bool inWater = false;

    public MeleeSystem melee;

    // Use this for initialization
    private void Start()
    {
    m_CharacterController = GetComponent<CharacterController>();
    m_Camera = Camera.main;
    m_OriginalCameraPosition = m_Camera.transform.localPosition;
    m_FovKick.Setup(m_Camera);
    m_HeadBob.Setup(m_Camera, m_StepInterval);
    m_StepCycle = 0f;
    m_NextStep = m_StepCycle/2f;
    m_Jumping = false;
    m_AudioSource = GetComponent<AudioSource>();
    m_MouseLook.Init(transform , m_Camera.transform);

    melee.GetComponent<MeleeSystem>();
    }

    but it just gives me an error the namespace could not be found
    I'm I doing something wrong or I'm I on the right track just forgeting something?
     
  4. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    usually you have

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    at the top of the script (they're namespaces). Without them the compiler isn't going to know what you're on about when you try to access functions in those namespaces...

    ps
    [ code] [ /code] tags when you paste in code please, formats it properly :)
     
  5. _Oscar

    _Oscar

    Joined:
    Mar 18, 2015
    Posts:
    11
    Yeah they are there so what can my problem be?
     
  6. _Oscar

    _Oscar

    Joined:
    Mar 18, 2015
    Posts:
    11
    And btw where to put the formating tags?? (I'm a newbie on this kind of stuff:))
     
  7. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    [ code] (without the space)
    paste stuff in
    [ /code] (without the space)

    =>

    Code (csharp):
    1.  (without the space)
    2. paste stuff in
    3.  
    (without the space)

    what is the actual text of the error, which function/namespace is it complaining about?
     
  8. _Oscar

    _Oscar

    Joined:
    Mar 18, 2015
    Posts:
    11
    This is the error I get

    Error 1 The type or namespace name 'MeleeSystem' could not be found (are you missing a using directive or an assembly reference?) C:\Users\Oscar\Desktop\Survival101\Survival101\Assets\Standard Assets\Characters\FirstPersonCharacter\Scripts\FirstPersonController.cs 46 16 Assembly-CSharp-firstpass-vs
     
  9. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    and the MeleeSystem script is saving without errors?
     
  10. _Oscar

    _Oscar

    Joined:
    Mar 18, 2015
    Posts:
    11
    yeah it's saving without any errors and doing exactly what I want
     
  11. _Oscar

    _Oscar

    Joined:
    Mar 18, 2015
    Posts:
    11
    Or like exactly all but not letting me change the boolean value in other scripts
     
  12. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Well there's no way we can help you directly if you don't give us all the relevant information (such as the code that's actually causing the error — which apparently is FirstPersonController.cs line 46).

    It should say something like
    Code (CSharp):
    1. MeleeSystem.swimming = false;
    ...and yes, this still works fine in Unity5, provided both scripts are CSharp. Post the line of code that's actually causing the error (the one you go to when you double-click the error message), and we'll see if we can help.
     
  13. doomprodigy

    doomprodigy

    Joined:
    Dec 12, 2010
    Posts:
    87
    JoeStrout has listed the correct way of referencing the static bool. If you could post your code with the correct forum formatting that would help too. I'd ditch using a static bool and reference it through get component.

    So on your melee script simple make a public bool.

    Code (csharp):
    1. public bool swimming;
    and then on your first person controller.
    Code (csharp):
    1.  
    2. private MeleeSystem mSystem;
    3.  
    4. void Start (){
    5. mSystem = GetComponent<MeleeSystem>();
    6. }
    and to change the value simply go

    Code (csharp):
    1. mSystem.swimming = false;
     
  14. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Since you bring up other ways to do it, a week or two ago I'd have done it exactly as you described. But today I would do it differently, using UnityEvents, so that the code isn't coupled.

    In the first person controller, instead of having a MeleeSystem property, I'd have a UnityEvent property or two:

    Code (CSharp):
    1. public UnityEvent startedSwimming;
    2. public UnityEvent stoppedSwimming;
    Then, in the code where I've detected that I've started or stopped swimming, I'd invoke the appropriate event:

    Code (CSharp):
    1. stoppedSwimming.Invoke();
    That's all we need, code-wise. Then in the inspector, I would hook up handlers for this event to do whatever they need to do — including setting the "swimming" bool (which would need to be public and non-static) on the MeleeSystem component. But note that neither script knows about the other this way; the connection is only in the object (scene or prefab).

    Moreover, if you later find that other things also need to do something when you start or stop swimming — trigger a sound effect, change a GUI indicator, start/stop a breath counter, etc. — you don't need to go add more complexity to that first person controller. One UnityEvent can invoke any number of methods (or set any number of properties), so you just add more handlers to the existing event in the editor, and you're done.

    I was musing today on whether my days of calling GetComponent are over. ...Probably not, completely, but I'll certainly be using it much less than I used to!
     
  15. _Oscar

    _Oscar

    Joined:
    Mar 18, 2015
    Posts:
    11

    Code (csharp):
    1.  
    2. private MeleeSystem mSystem;
    3.         // Use this for initialization
    4.         private void Start()
    5.         {
    6.             m_CharacterController = GetComponent<CharacterController>();
    7.             m_Camera = Camera.main;
    8.             m_OriginalCameraPosition = m_Camera.transform.localPosition;
    9.             m_FovKick.Setup(m_Camera);
    10.             m_HeadBob.Setup(m_Camera, m_StepInterval);
    11.             m_StepCycle = 0f;
    12.             m_NextStep = m_StepCycle/2f;
    13.             m_Jumping = false;
    14.             m_AudioSource = GetComponent<AudioSource>();
    15.             m_MouseLook.Init(transform , m_Camera.transform);
    16.  
    17.             mSystem = GetComponent<MeleeSystem>();
    18.  
    19.  
    20.         }
    21.  
    those are the two lines (the red ones) that give me the same error:
    Error 1 The type or namespace name 'MeleeSystem' could not be found (are you missing a using directive or an assembly reference?) c:\users\oscar\desktop\survival101\survival101\assets\standard assets\characters\firstpersoncharacter\scripts\firstpersoncontroller.cs 46(and 62) 17 Assembly-CSharp-firstpass-vs

    in this case lines 17 and 2

    I don't now but when I type the "MeleeSystem" Shouldn't I get suggestions where it suggests if I want to use it or something like that??
     
    Last edited: May 9, 2015
  16. _Oscar

    _Oscar

    Joined:
    Mar 18, 2015
    Posts:
    11
    I tried using the unityevents (they seem as you said more simple) but when I trie to insert the bool, it isn't there. I've checked and it is just public.
    Skärmbild (12).png
     
  17. _Oscar

    _Oscar

    Joined:
    Mar 18, 2015
    Posts:
    11
    Ok, so I finally managed to get the unityEvent working by using the enabled function and having it checked in the stopped Swimming. I'm still wondering why the swimming bool didn't show up there so an explanation of that is welcome but it's no hurry for it. Thanks to everyone who helped me solve my problems:)!!
     
  18. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    I bet it didn't show up because it's still static. To be available for events, it needs to be a public, non-static (regular ol' instance) property.

    And congrats on taking the UnityEvent approach... it's still pretty new (just introduced in 4.6), and a lot of Unity devs still haven't fully realized how powerful they are. I'm still coming to terms with it myself. But I think you've taken the first step down a very bright, happy path. :)
     
    _Oscar likes this.