Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 /
  • Help Room /
avatar image
0
Question by DarKAeRiX · Aug 23, 2016 at 09:22 AM · static-function

Attempting to create a Utility class of static functions. Which object references do I need for Unity's built in functions, and where do I put them?

Trying to create a class of static functions, that I can call in a similar fashion to 'Vector3.RotateAround', 'Vector3.Normalize', etc. Here's what I have so far:

 using UnityEngine;
 
     public class UtilitySetMono : MonoBehaviour
     {
         public static void MoveOnKeyboardPress(KeyCode key, Vector3 direction)
         {
             if (Input.GetKey(key))
             {         
                 transform.Translate(direction * Time.deltaTime);
             }
         }
     }

The first part of the 'transform.Translate' function, the word 'transform', is throwing the following error:

An object reference is required for the non-static field method or property 'Component.transform'.

Where should I insert the object reference, and what do I need to type there?

Comment
Add comment
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

4 Replies

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

Answer by villevli · Aug 23, 2016 at 09:37 AM

This could be an extension method for the Transform class:

 public static void MoveOnKeyboardPress(this Transform transform, KeyCode key, Vector3 direction)

And then you just call it on any transform:

 transform.MoveOnKeyboardPress(key, direction);
Comment
Add comment · Show 4 · 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 DarKAeRiX · Aug 23, 2016 at 10:22 AM 0
Share

I'll look into Extension $$anonymous$$ethods. Thanks for the input.

avatar image villevli DarKAeRiX · Aug 23, 2016 at 10:48 AM 1
Share

You only need $$anonymous$$onoBehaviour on scripts that are attached as components to a gameobject.

avatar image Bunny83 · Aug 23, 2016 at 11:14 AM 1
Share

$$anonymous$$eep in $$anonymous$$d that extension method must be defined in a simple public static class.

 public static class TransformExtension
 {
     public static void $$anonymous$$oveOn$$anonymous$$eyboardPress(this Transform transform, $$anonymous$$eyCode key, Vector3 direction)
     {
         // ...
     }
 }

Though i don't see much "usefulness" in that method ^^. It's a very specific case which you usually don't have that often. It's very limited since it directly relies on Get$$anonymous$$ey (so no other input method is possible) and directly relies on Time.deltaTime. Also it used transform for movement, so it bypasses physics if a rigidbody is in use.

Utility functions should be as versatile as possible.

avatar image Owen-Reynolds · Aug 23, 2016 at 02:41 PM 1
Share

But this is a more complicated way of saying the real problem. Regular functions only know about what you tell them inside the parens. $$anonymous$$oveOn$$anonymous$$eyPress would have to be sent a transform, otherwise it doesn't have one. The first step is to change it to $$anonymous$$o$$anonymous$$P(Transform T, $$anonymous$$eyCode ... ). Now it has a transform input, and can use T.Translate.

An improvement (depending) is the extension method trick. Notice how it's still being sent a transform (but in a funny way.)

Everything written inside a standard Unity class in really a member function, which is why you get access to all globals (including transform.) You've been using that magic rule this whole time. The confusion is that you thought you were writing normal functions, but you really weren't. So a real normal utility function is confusing.

avatar image
1

Answer by _Yash_ · Aug 23, 2016 at 09:30 AM

You can not access non-static (transform here) inside a static functions. You should use singleton pattern. also you can fix just this function by passing transform to it

  using UnityEngine;
  
      public class UtilitySetMono : MonoBehaviour
      {
          public static void MoveOnKeyboardPress(Transform trans, KeyCode key, Vector3 direction)
          {
              if (Input.GetKey(key))
              {         
                  trans.Translate(direction * Time.deltaTime);
              }
          }
      }
Comment
Add comment · Show 9 · 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 ScaniX · Aug 23, 2016 at 09:43 AM 0
Share

Just to clarify: It does not matter where you are calling the method (unless you are calling from within a method of that object). You just need a reference to an object if you want to call a non-static member function.

avatar image DarKAeRiX ScaniX · Aug 23, 2016 at 10:15 AM 0
Share

That's the thing, if Vector3 doesn't need an object reference in order to use its functions, then how can I write my code in a way that I don't need object references, and so that I can call the function like this:

 UtilitySet$$anonymous$$ono.$$anonymous$$oveOn$$anonymous$$eyboardPress(thing1, thing2);

where UtilitySet$$anonymous$$ono is an abstract class?

avatar image ScaniX DarKAeRiX · Aug 23, 2016 at 11:13 AM 1
Share

Vector3 does need a reference.

All non-static member functions get a this pointer implicitly passed as well. Vector3.Normalize() is non-static and is applying the change to the instance you call it on. Without a Vector3 reference, you cannot call Normalize() without parameters.

Vector3 could also have a static method Normalize() but that one would also need a parameter of type Vector3.

Said in a very simple way:

If you have a method that is supposed to work with an object (in your case a transform which is supposed to be moved) it has to somehow know which one to use.

Example:

You have 100 lights that have a method turnOn(). So you could access a specific light and call turnOn() to switch that one on.

Then you have a helper method (student). And you tell him: turnOn(). Of course he will ask "which light?" as he himself is not connected to any of them. So you have to tell him turnOn(light17) or something like that. (After which he will probably ask "now?" but that is another problem)

Show more comments
avatar image DarKAeRiX · Aug 23, 2016 at 10:12 AM 0
Share

If I pass 'Transform' as the first parameter, then what should that first parameter be during the function call?

For example:

 cmp.usm.$$anonymous$$oveOn$$anonymous$$eyboardPress(new $$anonymous$$eyCode[] { $$anonymous$$eyCode.W, $$anonymous$$eyCode.UpArrow }, dirs.Up);

This is going to throw an error, because it no longer takes two arguments: what should the third (first in the list) be?

avatar image tanoshimi DarKAeRiX · Aug 23, 2016 at 10:17 AM 0
Share

this.transform.

Although I prefer @villevli's suggestion of writing an extension method so that this is not necessary.

avatar image DarKAeRiX tanoshimi · Aug 23, 2016 at 10:36 AM 0
Share

It worked, definitely a step in the right direction. Thanks!

Although this does present another issue, that being that the first parameter has to be 'this.transform' or just 'transform' on every single call. Is that anything that can be worked around, or am I forced to leave it in?

avatar image
1

Answer by Glurth · Aug 23, 2016 at 03:35 PM

I think most of these points have been made in previous answers and comments, just wanted to put them together & summarize. Everyone should feel free to edit this.

 public static class ExtensionClassName
 {
  
    static public Vector2 RotateAboutPoint(this Vector2 pointToRotate, Vector2 centerPoint, float angle)
      {..blah..}
 
    static public Vector2 RotateAboutPoint2(Vector2 pointToRotate, Vector2 centerPoint, float angle)
      {..blah..}

    static float favoriteAngle=30.0f;
 }

Notice the two ways the RotateAboutPoint functions' parameters are defined: the first one has the keyword "this" in front of it. This is no more than a neat syntax trick, which allow this function to be CALLED like so:

 pointToRotate.RotateAboutPoint(centerPoint, angle);  //Where pointToRotate is a Vector2 variable.

This is functionally exactly the same as NOT using the "this" keyword, and calling the function like so:

 ExtensionClassName.RotateAboutPoint2(pointToRoate, centerPoint,angle);

Either way, because these are static functions, you must pass in (or otherwise make accessible) ALL the information needed to compute the return value.

Other ways to make values accessible to static functions, is to store them in static variables. For example the static float favoriteAngle can be read and written by both RotateAboutPoint functions. It can ALSO be access ANYWHERE this class is available with:

 ExtensionClassName.favoriteAngle

Limitations: the name of the static class holding these functios must be used, unless the "This" keyword is specified. Alas, the class names Vector2 and Vector3 and similar, are already defined, so we MUST use a unique class name here. this means we CANNOT define, for example, a function called like so: Vector2.RotateAboutPoint(pointToRoate, centerPoint,angle);

Comment
Add comment · 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
0

Answer by visualbruno · Aug 23, 2016 at 09:56 AM

Hi.

Static function can only access static variables.

Why do you need this function to be static ?

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 DarKAeRiX · Aug 23, 2016 at 10:21 AM 0
Share

I'm creating a Utility Class of static functions, that I can call directly by doing the following:

 UtilitySet$$anonymous$$ono.$$anonymous$$oveOn$$anonymous$$eyboardPress(param1, param2);

without having to declare a reference to UtilitySet$$anonymous$$ono, or having to use GetComponent() or gameObject.AddComponent();

The problem is that with static functions, you need references to $$anonymous$$onoBehaviour/UnityEngine/etc within the function's declaration. I'm fine with that, as long as it means I can call functions directly through the class name, as I would with 'Vector3.$$anonymous$$oveTowards' or 'Vector3.Angle'. The question is, how would I go about doing this?

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

10 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

Related Questions

Can't destroy GameObject in static method 3 Answers

A Question about static, please help me. 1 Answer

An object reference is required to access non-static member 2 Answers


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