Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8733235
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T09:36:35+00:00 2026-06-13T09:36:35+00:00

Short and simple, I just don’t get why this works the way it does:

  • 0

Short and simple, I just don’t get why this works the way it does:

using UnityEngine;
using System.Collections.Generic;

// this struct holds data for a single 'shake' source
public struct Shake
{
    public float AmountX;
    public float AmountY;
    public float Duration;

    private float percentageComplete;
    public float PercentageComplete { get { return percentageComplete; } }

    public Shake(float _amountX, float _amountY, float _duration)
    {
        AmountX = _amountX;
        AmountY = _amountY;
        Duration = _duration;
        percentageComplete = 0f;
        Debug.Log("wtf");
    }

    public void Update()
    {
        Debug.Log("a " + percentageComplete);
        percentageComplete += Time.deltaTime;
        Debug.Log("b " + percentageComplete);

        AmountX = Mathf.Lerp(AmountX, 0f, percentageComplete);
        AmountY = Mathf.Lerp(AmountY, 0f, percentageComplete);

    }
}

// This class uses that data to implement the shakes on a game camera
public class CameraShake : MonoBehaviour 
{
    // components
    private Transform myTransform;

    // vars
    private List<Shake> shakes;

    private float totalShakeX;
    private float totalShakeY;

    private void Awake()
    {
        myTransform = transform;

        shakes = new List<Shake>();
    }

    private void Update() 
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            AddShake(new Shake(.1f, .1f, 1f));
        }

        totalShakeX = 0f;
        totalShakeY = 0f;

        for (int i = 0; i < shakes.Count; i++)
        {
            shakes[i].Update();
            Debug.Log("c " + shakes[i].PercentageComplete);

            totalShakeX += shakes[i].AmountX;
            totalShakeY += shakes[i].AmountY;

            if (shakes[i].PercentageComplete >= 1f)
            {
                shakes.RemoveAt(i);
                i--;
            }
        }

        myTransform.position += new Vector3(totalShakeX, 0f, totalShakeY);
    }

    public void AddShake(Shake shake)
    {
        shakes.Add(shake);
    }
}

When I run this code (using Unity3D game engine) the struct Shake does not log the correct values.

Percentage complete logs these values (every frame):
a 0
b 0.001 (or hereabouts, its Time.deltaTime, the maount of time it took to process the previous frame)
c 0

What gives? Why is percentageComplete resetting to 0 every frame?

If I change Shake into a class instead of a struct it works fine.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-13T09:36:36+00:00Added an answer on June 13, 2026 at 9:36 am

    C# does not allow a property access to combine a read and a write, which means an access to a property of a structure type will be considered a read-only access. Unfortunately, C# provides no means of indicating whether a struct method will modify this. Consequently, an attempt to invoke a struct method which modifies this on a read-only struct will compile fine, but it won’t actually work.

    To avoid this problem, if your struct needs to define a method like Update which modifies a struct in-place, you should change it to be something like:

    public static void Update(ref Shake it)
    {
        it.percentageComplete += it.Time.deltaTime;
        it.AmountX = Mathf.Lerp(it.AmountX, 0f, it.percentageComplete);
        it.AmountY = Mathf.Lerp(it.AmountY, 0f, it.percentageComplete);
    }
    

    The compiler would then be able to squawk, correctly, if you were to attempt something like: Shake.Update(ref shakes[i]); when shakes is a List<Shake>, but would allow a construct like var temp = shakes[i]; Shake.Update(ref temp); shakes[i] = temp;, or would allow the first construct (and it would work), if shakes had been a Shake[] rather than a List<Shake>.

    Value types have different semantics from reference types. Sometimes these different semantics can be useful. The semantic differences are more apparent with value types that allow convenient piece-wise mutation than with those that do not, and some people who believe all types should behave identically denounce them as evil for that reason, but I disagree with such thinking. A struct which exposes all its fields, and which has no methods that mutate this, will behave like every other struct meeting that description (save for the precise names and types of its fields). Such behavior is unlike that of any reference type, but that’s what makes it useful. By contrast, while structs with private fields may be coded so as to “pretend” to be immutable, and to eliminate the semantic advantages of value types, mutable storage locations of non-trivial struct types will always hold mutable struct instances, regardless of whether the types pretend to be immutable. IMHO, it’s better for value types to advertise themselves as what they are, than to pretend to behave as something they’re not.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

For some short and simple queries I've been using the query designer in SSMS
Could someone provide a simple example using getopt.pas with short and long command line
If you're anxious to get to the point of this, just skip to the
Pretty simple set-up here, I'm just trying to get two divs to sit side-by-side.
Short and simple, our project has a Launcher component and an Application component and
Short and simple question. In Winforms you can bind a dataview to a combobox
Can anyone show a short and simple code snippet? It should take the name
So, I am writing a short (and simple) regular expression, but I can think
How can i shorter below codes than before? i need short and simple method:
Can someone please break down what a delegate is into a simple, short and

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.