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 Lairinus · Mar 26, 2013 at 10:34 PM · c#struct

Can't modify Struct variables C#

Hello,

I have a struct called WeaponType, and in it I have approximately 10 variables.

Upon calling "WeaponType.CurrentWeapon.Ammo = ," I received an error that I couldn't modify the value because it wasn't a variable.

Okay, well that's fine. So I added a function called SetAmmo(int amount) where I thought I would modify the value directly on the struct.

With that function I'm able to "change" the value from the same to the same.(no actual change is noted) Later found out this is because of the fact that it's like a skinwalker from Supernatural and created another instance of itself. (okay, bad reference)

After doing research on it, I don't know how to change it from "mutable" to "immutable," mainly because I don't know what that means.

Can anyone shed some light on this please?

Comment
Add comment · Show 5
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 dorpeleg · Mar 26, 2013 at 10:40 PM 0
Share

Please provide the code showing the deceleration of WeaponType.

Also, where are you accessing WeaponType.CurrentWeapon.Ammo? I'm guessing from another script.

Id so, please show the code referencing the script.

avatar image Lairinus · Mar 26, 2013 at 10:54 PM 0
Share

WeaponType is a struct inside of the Weapons class.

 public struct weaponType
 {
     /*
      * This struct will contain the different weapons. Will only hold a raw value for the data, and $$anonymous$$AYBE a function or 2.
      */
     
     #region Weapon Variables
     private GameObject _sparkObject;
     
     private bool outOfAmmo;
     
     private string _name;
     
     private float _accuracy;
     
     private string _type; //Weapon Type
     
     private bool _playerCanUse; //If the player is allowed to use the weapon
     
     private bool _isEquipped; //Checks if the weapon is equipped or not
     
     private int _currentAmmo;
     
     private int _maxWeaponAmmo;
     
     private int _totalCurrentAmmo;
     
     private int _numberOfClips;
     
     private int _clipSize;
     
     private float _weaponDamage; //Base Weapon Damage
     
     private float _reloadTime;
     
     private float _speed; //Time interval between shots
     
     #region Getters and Setters
     
         public GameObject sparkObject
         {
             get{return _sparkObject;}
             set{_sparkObject = value;}
         } 
     
         public string name
         {
             get{return _name;}
             set{_name = value;}
         }
     
         public float accuracy
         {
             get{return _accuracy;}
             set{_accuracy = value;}
         }
     
         public string type
         {
             get{return _type;}
             set{_type = value;}
         }
     
         public bool playerCanUse
         {
             get{return _playerCanUse;}
             set{_playerCanUse = value;}
         }
     
         public bool isEquipped
         {
             get{return _isEquipped;}
             set{_isEquipped = value;}
         }
     
         public int currentAmmo
         {
             get{return _currentAmmo;}
             set{_currentAmmo = value;}
         }
     
         public int maxWeaponAmmo
         {
             get{return _maxWeaponAmmo;}
             set{_maxWeaponAmmo = value;}
         }
     
         public int totalCurrentAmmo
         {
             get{return _totalCurrentAmmo;}
             set{_totalCurrentAmmo = value;}
         }
         
         public int numberOfClips
         {
             get{return _numberOfClips;}
             set{_numberOfClips = value;}
         }
     
         public int clipSize
         {
             get{return _clipSize;}
             set{_clipSize = value;}
         }
     
         public float weaponDamage
         {
             get{return _weaponDamage;}
             set{_weaponDamage = value;}
         }
     
         public float reloadTime
         {
             get{return _reloadTime;}
             set{_reloadTime = value;}
         }
     
         public float speed 
         {
             get{return _speed;}
             set{_speed = value;}
         }

After this, I then create an instance of the struct by calling

"WeaponType _currentWeapon = new WeaponType();"

Then I encapsulated it:

" WeaponType currentWeapon get{return _currentweapon;} set {_curentWeapon = value;}

Then I access it in another script by using a GetComponent of the Weapons script : " Weapons weapons = GetComponent();"

If I try to access the weapon.currentWeapon.currentAmmo, It doesn't work, but if I do it in the initial "Weapons" script, it does.

In another script, "Action$$anonymous$$anager" I use a function called shoot.

 void shoot()

{ if (weapon.currentWeapon.ammo > 0) { weapon.currentWeapon.ammo -= 1; //At this point I get an error } }

avatar image dorpeleg · Mar 26, 2013 at 11:07 PM 0
Share

Are both scripts on the same object?

You know you need to write it like so GetComponent(); right?

avatar image Lairinus · Mar 26, 2013 at 11:15 PM 0
Share

One script is on the main GameObject, the other script is on a child object. I use a public GameObject set to the non-child object to receive the components.

the way that's set up is:

 public GameObject weaponReference;
 private Weapons weapons;
 
 Awake()
 {
  weapons = weaponReference.GetComponent<Weapons>();
 }

Aside from that though, I think the problem may have to do with me encapsulating the actual weaponType variable ins$$anonymous$$d of making it public..


Answer found... ish.

It WAS the fact that the actual weaponType was encapsulated. If I removed the encapsulation and left it strictly as a public variable, then it works.

On that note, though, is it sound to do so?

avatar image dorpeleg · Mar 26, 2013 at 11:20 PM 0
Share

I'm guessing you are drag'droping the object with the Weapons script.

When you are trying to call the weapon type, it should be: waepons.weaponType.Ammo and so on.

1 Reply

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

Answer by whydoidoit · Mar 26, 2013 at 11:29 PM

You cannot modify the values inside a struct returned from another component the way you are - and for good reason. A struct is passed by value.

When you do this:

     WeaponType currentWeapon get{return _currentweapon;} set {_curentWeapon = value;}

You return a copy of _currentWeapon.

So if you were to do someObject.currentWeapon.maxWeaponAmmo = 5 - you would be doing that on the copy that only existed while that line executed and was immediately thrown away afterwards. So the compiler realises that this isn't smart and refuses it.

Either

  1. Make it a class which won't have that problem

  2. Take the value into a local variable, change the property and set it back. That way you update the copy and assign the copy back.

    var weapon = something.currentWeapon; weapon.maxWeaponAmmo = 5; something.currentWeapon = weapon;

Note that structs can be a lot slower than classes because of all of the hidden copying.

Comment
Add comment · Show 3 · 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 whydoidoit · Mar 26, 2013 at 11:33 PM 0
Share

I just noticed that you have just made it a public member - that will also work (because you have direct access to the copy). Structs are generally a dangerous thing to use (weird copy issues, copy time, lack of serialization support) and in real .NET would be reserved for special cases. The fact that they are stack allocated makes them popular in Unity due to Unity/$$anonymous$$ono's ridiculously poor implementation of Garbage Collection Generations that means big GC spikes that should not happen when disposing of short lived classes.

This doesn't look like a short lived object - if not it would be better off as a class.

avatar image Lairinus · Mar 26, 2013 at 11:41 PM 0
Share

Thanks for the overview of issues with Structs... that information was kind of left out when I read a few months ago that "Structs are just smaller classes that can hold values and functions!"

Tried to avoid using a new class for this, but it seems like that won't be happening lol.

Thanks again, truly enlightened me.

avatar image whydoidoit · Mar 26, 2013 at 11:45 PM 0
Share

Yeah it's those techy details - especially for ex C++ programmers where they are almost identical to classes.

Utility things (think Vector3/Quaternion etc) that you create and use everywhere for a few instants and then forget about should always be structs in Unity.

If it lives for a significant time it should probably be a class.

It's all the intermediate things which are a problem!

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

12 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

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Flip over an object (smooth transition) 3 Answers

Selecting Structs from dropdown menu in inspector. 1 Answer

Finding struct values by string 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