• 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
1
Question by tutiplain1 · Dec 20, 2013 at 12:41 PM · transformvector3

How to change x,y,z values in a Vector3 properly in c#?

Hi all,

I recently made the change from javascript to c# in all my unity scripts.

Now in Javascript, I can do this with a Vector3, no problems:

 myVector.x = new_x;
 myVector.y = new_y;
 myVector.z = new_z;

However, this same code fails to compile in C#, with an error message about using a temporary variable to store the values. As a workaround, I've found that this way it works:

 myVector = new Vector3(new_x,new_y,new_z);

This gets annoying when dealing with vectors with long names, like transform.position, or when I simply need to change one of three coordinates. Why is it that X,y and Z cannot be directly accessed and is there a simpler way to reassign just one of them? When dealing with transform.position, the position itself allows me to reassign a new Vector3, but not the individual values. Can someone please clarify this for me?

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

3 Replies

· Add your reply
  • Sort: 
avatar image
10

Answer by MartinCA · Dec 20, 2013 at 01:07 PM

This happens because Vector3 is a struct and Transform.position is a getter method that retrieves the position member, but because its a struct it is passed by value and not by reference.

Basically, ever time you call Transform.position, a new Vector3 struct is allocated with the values of position, but it's not in fact the same position object, so semantically it makes no sense to say "transform.position.x = 10.0f", because what it really means is "change the value a random Vector3's x property allocated somewhere on the heap to 10, and then discard it as it is not referenced anywhere"

You can either keep using your method, or alternatively store the result of transform.position, modify it, and then re-assign:

 Vector3 temp = transform.position;
 temp.x = 10.0f;
 transform.position = temp;



[Edit] Looks like we can edit posts again! Just wanted to add that if you're want to further read about this, you can check out http://msdn.microsoft.com/en-us/library/wydkhw2c.aspx, The second exmaple explains what happens with transform.position

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
2

Answer by cs_can · Apr 19, 2015 at 12:32 PM

Declare a static method somewhere in your solution:

 public static Vector3 Change(this Vector3 org, object x = null, object y = null, object z = null) {
      return new Vector3( (x==null? org.x, (float)x), (y==null? org.y, (float)y), (z==null? org.z, (float)z) );
 }

Call it by:

 transform.position = transform.position.Change( y: 1.3f );
Comment
Add comment · Show 2 · 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 deCalle · Feb 17, 2016 at 08:59 PM 0
Share

well i tried to do it, but it keeps on telling me i need a static class, and when i do its not part of monobehaviour and then, that i cannot add abstract classes to a gameobject...

dead end here.. but i figure they are going to implement that soon... still got an error with your script. doesn't understand one line if's. so here you go

STILL A GREAT IDEA AND ONE THAT SHOULD HAVE BEEN I$$anonymous$$PLE$$anonymous$$ENTED LONG AGO

     public static Vector3 Change(this Vector3 org, object x = null, object y = null, object z = null)
     {
         float newX;
         float newY;
         float newZ;
 
         if (x == null)
             newX = org.x;
         else
             newX = (float)x;
 
         if (y == null)
             newY = org.y;
         else
             newY = (float)y;
 
         if (z == null)
             newZ = org.z;
         else
             newZ = (float)z;
 
         return new Vector3(newX, newY, newZ);
     }



Do you have any idea how i could still implement it? same with transferring vector2 to vector3 and vice versae like:

 new Vector3(1,1,2).toVector2() //drops the 2
 
 new Vector2(1,1).toVector3(z = 0) // can choose z or leave it to set z = 0
avatar image Bunny83 deCalle · Feb 17, 2016 at 09:41 PM 0
Share

That method is an extension method. Extension methods need to be declared in a static class. That class can be located anywhere in your project and you can name it any name you want.

I would declare functions like this:

 public static class Vector234Extensions
 {
     // Vector2
     public static Vector2 SetX(this Vector2 aVec, float aXValue)
     {
         aVec.x = aXValue;
         return aVec;
     }
     public static Vector2 SetY(this Vector2 aVec, float aYValue)
     {
         aVec.y = aYValue;
         return aVec;
     }
     
     // Vector3
     public static Vector3 SetX(this Vector3 aVec, float aXValue)
     {
         aVec.x = aXValue;
         return aVec;
     }
     public static Vector3 SetY(this Vector3 aVec, float aYValue)
     {
         aVec.y = aYValue;
         return aVec;
     }
     public static Vector3 SetZ(this Vector3 aVec, float aZValue)
     {
         aVec.z = aZValue;
         return aVec;
     }
     
     // Vector4
     public static Vector4 SetX(this Vector4 aVec, float aXValue)
     {
         aVec.x = aXValue;
         return aVec;
     }
     public static Vector4 SetY(this Vector4 aVec, float aYValue)
     {
         aVec.y = aYValue;
         return aVec;
     }
     public static Vector4 SetZ(this Vector4 aVec, float aZValue)
     {
         aVec.z = aZValue;
         return aVec;
     }
     public static Vector4 SetW(this Vector4 aVec, float aWValue)
     {
         aVec.w = aWValue;
         return aVec;
     }
 }

Now you can simply do:

 transform.position = transform.position.SetX(5f).SetZ(7f);

Vector2 / 3 / 4 already can be implicitly converted into each other. So this does already work:

 Vector2 v = new Vector3(1,2,3); // --> (1,2)
 Vector3 u = v; // --> (1,2,0)

However extension methods don't apply for cases which can implicitly converted. So this doesn't work:

 Vector2 v = new Vector2(1,2);
 Vector3 u = v.SetZ(3); // --> Vector2 doesn't have an extension "SetZ"

You would have to add it explicitly:

     public static Vector3 SetZ(this Vector2 aVec, float aZValue)
     {
         return new Vector3(aVec.x, aVec.y, aZValue);
     }
avatar image
1

Answer by nastasache · Dec 20, 2013 at 01:02 PM

The only way I found is:

 Vector3 tmpPos = transform.position; // Store all Vector3
 tmpPos.y = 1.3f; // example assign individual fox Y axe
 transform.position = tmpPos; // Assign back all Vector3

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

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.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

24 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 avatar image avatar image avatar image avatar image

Related Questions

move a transform to a vector 3? 1 Answer

Difference Between Transform.TransformVector and Transform.TransformPoint 1 Answer

Instantiate GameObject towards player 0 Answers

how to make a character resume after going into a random battle? 1 Answer

using MoveObject to perform 2 translations at the same time 1 Answer

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges