Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by BrimTheOne · Jan 21, 2014 at 11:50 PM · c#collisionclassesweapon

(C#)Accessing a GameObject from a class, inside another class. On collision with other object.

Hello whoever might be reading this.

First off, i'd like to apologize for any bad grammar that might occur.

English is not my main Language.

So, my problem is so :

I got a script(lets call it scriptA), where i got a class inside of it(lets call it classA), that is attached to a gameobject.

and i got another script, at another gameobject(lets call this scriptB), and i am trying to assign a variable from script scriptA's classA to a variable in scriptB, on collision.

now, ive tried dozen of things, without luck. and the most common error it gives me is

"NullReferenceException: Object reference not set to an instance of an object Equip.OnCollisionEnter (UnityEngine.Collision col) (at Assets/Player/SCRIPTS/Equip.cs:42)"

Any help would be insanely appreaciated.

scriptA :

 using UnityEngine;
 using System.Collections;
 
 public class BEGINNERSWORD : MonoBehaviour {
     static GameObject MODEL = Resources.Load("SWORD_MODEL", typeof(GameObject)) as GameObject;
 
     public class BEGINNERSWORD_01 : WEAPONS {
 
     void Init () {
         _NAME = "Beginner Sword";
         _TYPE = 1;
         _VALUE = 001;
         _MODEL = MODEL;
         _ATTDMG = 10;
     }
     }
     //public BEGINNERSWORD_01 BS_01 = new BEGINNERSWORD_01;
 }
 


scriptB:

 using UnityEngine;
 using System.Collections;
 
 public class Equip : MonoBehaviour {
     public GameObject Weapon = null;
     public Transform rHand;
     bool equiped = false;
     GameObject t = null;
     // Use this for initialization
     void Start () {
 
     }
 
     void equip(){ 
         if(!equiped){
         t = Instantiate (Weapon, rHand.position, rHand.rotation)as GameObject;
         t.transform.parent = rHand.transform;
         equiped = true;
         }
         else if (equiped){
         Destroy((GameObject)t);
         equiped = false;
         }
     }
 
     // Update is called once per frame
     void Update () {
         if(Input.GetKeyDown(KeyCode.E)){
             if(Weapon = null){
                 Debug.Log("NoWeapon" + Weapon.tag);
             }
             else{
                 equip ();
             }
         }
     }
 
     public void OnCollisionEnter(Collision col){
         if(col.gameObject.tag == "SWORD"){
             BEGINNERSWORD bs = col.gameObject.GetComponent<BEGINNERSWORD>(); 
             BEGINNERSWORD.BEGINNERSWORD_01 bs1 = GetComponent<BEGINNERSWORD.BEGINNERSWORD_01>();
             Weapon = bs1._MODEL;
             
         
         } 
     }
 }
 
Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image BrimTheOne · Jan 22, 2014 at 04:52 PM 0
Share

I'd hate to be a douche and bump it, but none of these Answers have helped me any further.

Anyone, with the slightest guidance is welcome.

3 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by fafase · Jan 23, 2014 at 06:17 PM

Here is a quick example that works:

 public class OuterA:MonoBehaviour
 {
      public class Inner
      {
          public int val
          public Inner(int value)
          {
              val = value;
          }
      }
      public Inner inner = new Inner(10);
 }
 
 public class OuterB:MonoBehaviour
 {
      public OuterA outer:
      void Start()
      {
          print(outer.inner.val);
      }
 }

Now you get the OuterA component just like any component in Unity using GetComponent. You need an instance of Inner object, simply declaring the class is not enough, it just means you cannot instantiate an object of that class outside of the OuterA without using OuterA as well.

 public class OuterB
 {
     OuterA.Inner inner = new OuterA.Inner(20);
 }

Once you got the OuterA component, the inner instance shows up and the val variable as well after two dereferenciation.

It is not really common to see an inner class that should be public and seen from outside. Or then via a method is more appropriate. Inner classes and structs are more likely to be a container used within the class it is declared and not really known to the other classes.

EDIT: In the case of MonoBehaviour, it is not possible to nest one class into another (at least it does not work in the most simple way), the compiler complains that the script does not have the same name than the component we are trying to use.

So the easiest solution is to take the class out and make it a basic script to be added using :

 gameObject.AddComponent<Component>();



 
Comment
Add comment · Show 8 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image BrimTheOne · Jan 23, 2014 at 08:37 PM 0
Share

but.. what im trying to do, is getting a value from a script on objectA assigned to a variable in objectB.

And the value is a variable from the scripts "class"-that it is inheriting for.

(hope this can kinda visualise it :S )

Itemclass -> weaponclass -> beginnersword.script

player collides sword

begginersword.script(_$$anonymous$$O$$anonymous$$) -> Player.equip.script.

avatar image fafase · Jan 23, 2014 at 08:46 PM 0
Share

The way you do things do not matter. What matters is that you have your inner object instant oater in the outer class with the new command. This is probably the missing part of your implementation. After whether you want to assign or use a value in the class is the same.

avatar image BrimTheOne · Jan 23, 2014 at 08:59 PM 0
Share

But how would i apply this

 public class OuterA:$$anonymous$$onoBehaviour
 {
      public class Inner
      {
          public int val
          public Inner(int value)
          {
              val = value;
          }
      }
      public Inner inner = new Inner(10);
 }

to this

 using UnityEngine;
 using System.Collections;
 
 public class BEGINNERSWORD : $$anonymous$$onoBehaviour {
 
     public class BEGINNERSWORD_01 : WEAPONS{
     void Start() {
         _NA$$anonymous$$E = "beginner sword";
         _TYPE = 1;
         _VALUE = 001;
         _$$anonymous$$O$$anonymous$$ = Resources.Load("SWORD_$$anonymous$$O$$anonymous$$", typeof(GameObject)) as GameObject;;
         _ATTD$$anonymous$$G = 10;
         }
     }
 
 }
avatar image fafase · Jan 24, 2014 at 06:14 AM 0
Share

$$anonymous$$y advice, you are going the wrong way. Do yourself a favor and take this class out and make everything simple. Your design actually does not make sense since ITE$$anonymous$$S and WEAPONS are normal class and then a sub class is declared public within another one... And in the end it does not work. Do yourself a favor and get it out.

On top of that it seems Unity does not appreciate nested $$anonymous$$onoBehaviour classes. It could be the reason why you get the Null reference. It seems Unity requires a script with the class as title of the script. I could be wrong but that is what the error I get seems to say.

All in all, you need your BEGINNERSWORD_01 in its own script.

avatar image BrimTheOne · Jan 24, 2014 at 08:28 AM 0
Share

i changed the BEGINNERSWORD to this -

using UnityEngine; using System.Collections; public class BEGINNERSWORD : $$anonymous$$onoBehaviour { static GameObject model; public void Awake(){ model = Resources.Load("SWORD_$$anonymous$$O$$anonymous$$", typeof(GameObject)) as GameObject; } public WEAPONS wep01 = new WEAPONS("beginnersword",null,001,1,model,10f,0); }

and in Equip i did this

             BEGINNERSWORD bs = col.gameObject.GetComponent<BEGINNERSWORD>(); 
 
             Weapon = bs.wep01._$$anonymous$$O$$anonymous$$;

but it still just gives me "Object reference not set to an instance of an object"

Show more comments
avatar image
0

Answer by Nanobrain · Jan 22, 2014 at 12:15 AM

I think that this line is not necessary:

 BEGINNERSWORD.BEGINNERSWORD_01 bs1 = GetComponent<BEGINNERSWORD.BEGINNERSWORD_01>();

BEGINNERSWORD.BEGINNERSWORD_01 is not a component, but an inner class of a component.

So, do this:

 Weapon = bs.BEGINNERSWORD_01._MODEL;

However, note that _MODEL is declared as a local variable within your Init method. You will need to declare it as a public member outside of a method within your inner class.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image BrimTheOne · Jan 22, 2014 at 05:24 AM 0
Share

Unfortnualy , "_$$anonymous$$O$$anonymous$$" is from the Weapon-class, and it is declared public in there already.

and, when i remove the bs1 , and do "bs.BEGINNERSWORD_01.$$anonymous$$O$$anonymous$$" It tells me "`BEGINNERSWORD_01': cannot reference a type through an expression; try BEGINNERSWORD.BEGINNERSWORD_01' ins$$anonymous$$d" and when i do that it says "An object reference is required to access non-static member WEAPONS.$$anonymous$$O$$anonymous$$'"

avatar image
0

Answer by KellyThomas · Jan 22, 2014 at 05:03 PM

Try running this and see what the console says:

     public void OnCollisionEnter(Collision col){
        if(col.gameObject.tag == "SWORD"){
          Debug.Log(col.gameObject.GetComponent<BEGINNERSWORD>());
          BEGINNERSWORD bs = col.gameObject.GetComponent<BEGINNERSWORD>();

          Debug.Log(col.gameObject.GetComponent<BEGINNERSWORD.BEGINNERSWORD_01>());
          BEGINNERSWORD.BEGINNERSWORD_01 bs1 = GetComponent<BEGINNERSWORD.BEGINNERSWORD_01>();

          Weapon = bs1._MODEL;
        } 

This will test if the GetComponent() calls are returning anything.

It may also be helpful if we can see a screenshot of the Inspector for this object.

In a reply to Nanobrain you say that BEGINNERSWORD.MODEL is public, this is not the case in the code you have posted. Are we seeing an out of date version?

Comment
Add comment · Show 7 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image BrimTheOne · Jan 22, 2014 at 05:29 PM 0
Share

Hello kelly$$anonymous$$, the reason i said it is already public , is because it is public in the class that "BEGINNERSWORD_01" inherits from("WEAPONS"). alt text

This is the Debug Log after trying yours. Although, when i tried this

 public void OnCollisionEnter(Collision col){
         if(col.gameObject.tag == "SWORD"){
             BEGINNERSWORD bs = col.gameObject.GetComponent<BEGINNERSWORD>(); 
             Weapon = BEGINNERSWORD.BEGINNERSWORD_01._$$anonymous$$O$$anonymous$$;
             Destroy(col.gameObject);
             
         
         } 


it said -

An object reference is required to access non-static member `WEAPONS._$$anonymous$$O$$anonymous$$'

if that is to any help at all :-)

Which GO's inspector did you want you want to see?:-)

debuglog.png (11.0 kB)
avatar image BrimTheOne · Jan 23, 2014 at 12:08 PM 0
Share

$$anonymous$$ate?.....

avatar image KellyThomas · Jan 23, 2014 at 12:19 PM 0
Share
  1. To solve that most recent error:

    Weapon = bs._$$anonymous$$O$$anonymous$$;

  2. If we can see the inspector for the game object you have these scripts on it may clear up some questions.

  3. "the reason i said it is already public , is because it is public in the class t,at "BEGINNERSWORD_01" inherits from("WEAPONS"). " If it is defined in a base class there is no need to redefine, however if you do mask it in a child class then you should provide a full definition including specifying the required access modifier.

  4. I'm not sure what you are trying to achieve, but I think you may be going about it the hard way. There is no real need for an inner class (the only advantage I can think of at the moment is a slightly tidier namespace), but a couple of disadvantages. The largest of which is that when scripts are assigned to a game object they are done as a file i.e. there is no way to assign an inner class as a Component using the unity GUI. This may not be an issue now should be a restriction to bear in $$anonymous$$d. .

avatar image BrimTheOne · Jan 23, 2014 at 02:58 PM 0
Share

The reason i redefine it in another script it because that is a weapon, and shouldent it derive from my "WEAPON"-class? And the reason for the inner class is, else it wouldent allow me to attach it to a gameobject. If you know any other way to do this it would be greatly appreaciated :-)

There is really nothing to see in the inspector, other than R-Hand is my characters hand's transform.

what i am trying to achieve is - when my char collides with the weapon, he will equip it. and then later, i will make the Inventory it will be put into.

this is my weapon class although :-)

WEAPON

 using UnityEngine;
 using System.Collections;
 
 public class WEAPONS : ITE$$anonymous$$S {
 
     public int _TYPE;
     public GameObject _$$anonymous$$O$$anonymous$$;
     public float _ATTD$$anonymous$$G;
     public int _INFUSED;
 
 
     public int infusement(int curATT){
         int gain;
         int newAtt;
         gain = curATT - 3;
         newAtt = curATT + gain;
 
         return newAtt;
 
     }
 }




ITE$$anonymous$$(if you were wondering)

 using UnityEngine;
 using System.Collections;
 
 public class ITE$$anonymous$$S : $$anonymous$$onoBehaviour{
     public string _NA$$anonymous$$E;
     public Texture2D _ICON;
     public int _VALUE;
     public ArrayList _ASPECTS = new ArrayList(5);
 
 
 }
 
avatar image KellyThomas · Jan 23, 2014 at 03:50 PM 0
Share

Any non-nested class that derives from Component (typically extending $$anonymous$$onoBehaviour) can be attached to a game object. This should be as simple as drag-and-drop or calling GameObject.AddComponent().

Given that the previous should be a non-issue I wonder if the difficulty was assigning values to an instance field. If so please consider the following example classes (each in their on .cs file). If SampleScript was attached to a game object in scene then an instance of WeaponBase, WeaponPointy, or WeaponBlunt could be assigned to the WeaponInHand field (including by use of the inspector). Note that to have an instance of one of these scripts available at design time it would need to be attached to a game object in scene. Of course WeaponInHand can also hold any instances created programmatically at runtime.

 public class SampleScript: $$anonymous$$onoBehaviour {
     public WeaponBase WeaponInHand;

     void Update() {
         Debug.Log("Wielding: " + WeaponInHand.Name);
 }

 public class WeaponBase: $$anonymous$$onoBehaviour {
     public String Name = Base;
 }

 public class WeaponPointy: $$anonymous$$onoBehaviour {
     void Awake() {
         Name="Pointy";
     }
 }

 public class WeaponBlunt: $$anonymous$$onoBehaviour {
      void Awake() {
         Name="Blunt";
     }
 }

Now the console log you posted earlier indicated that the "`col.gameObject.GetComponent()`" call was returning null. This will only occur if:

  1. col.gameObject does not have a component of type BEGINNERSWORD.BEGINNERSWORD_01 or

  2. Unity getting confused the inner class.

$$anonymous$$y inclination is to think the first scenario is most likely, especially as I believe it is impossible add an inner class as Component using the inspector.

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

20 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

homing missiles and transform and colission help c# 1 Answer

How to call OnTriggerEnter once 5 Answers

Distribute terrain in zones 3 Answers

Hiding a GUI Texture upon death. 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges