Is it possible to replace multiple variables of a script but call GetComponent only once?

I have this little bit of code:

if (spawnedCar.GetComponent<TrafficCarController>().isCop)
{
    CopController CC = spawnedCar.GetComponent<CopController>();
    CC.player = player;
    CC.CSPR = GetComponent<CarSpawner>();
    spawnedCar.GetComponent<CopController>() = CC;
}

But the last line throws this error: error CS0131: The left-hand side of an assignment must be a variable, property or indexer

Of course, the easiest solution is to simply use GetComponent in every line, but I’m trying to avoid that for performance reasons. Is there any way to change multiple variables of a script that’s found by GetComponent and then replace it without having to call GetComponent to change each variable?

Thank you!

I don’t think you need line 6 above at all. Follow my logic:

line 3 you get the cop controller to the CC variable

line 4 you tell the cop controller (via the CC variable) who is the player

line 5 you tell the cop controller(via the CC variable) where the car spawner is

line 6 appears to tell the cop controller who itself is… this is why it does not make any sense.

The cop controller IS who it is, it does not need to be told who it is. :slight_smile:

This question didn’t make much sense to me and I had trouble parsing it, but I think I realized that the confusion is coming from a misconception: Are you applying struct-based logic to classes? Or, to elaborate:

To change the X value of transform.position you have to do this familiar dance:

Vector3 pos = transform.localPosition;
pos.x = 5f;
transform.localPosition = pos;

The third line there is important because, when you get the position, it returns a copy of the position (because Vector3 is a struct, which are always passed by value), so pos.x only changes the copy, and you have to reassign it. We’re on the same page right now, right?

OK, now you move over to components. So let’s use this code:

spawnedCar.GetComponent<CopController>().someStringProperty = "old";
CopController CC = spawnedCar.GetComponent<CopController>();
CC.someStringProperty = "new";
Debug.Log(spawnedCar.GetComponent<CopController>().someStringProperty);

Now if I understand your mindset correctly, you’re probably thinking that that debug.Log would print out “old”. Is that right?

If so, then there’s the source of your confusion, because that’s wrong - it will print out “new”. Go ahead, add a string variable to your class and try it out.

The reason is that components are a class, not a struct. Because they’re a class, your variable CC doesn’t contain a CopController object per se, but rather points to the same CopController object that is held by the GameObject.

So the answer to your question is, just store “CC” and use that to change values - no need to ever reassign it to apply the changes back to your component, it’ll always be pointing to your component, live on the GameObject, and changes you make to it will work.

2 Likes

Okay my apologies, I think I wasn’t clear enough.

Basically, what I’m doing is when spawning a car, the world’s car spawner script checks if it’s a cop, and if it’s a cop car, I need to tell it who the player is, and what the car spawner script is. So to do this, I could just call GetComponent on each line. However, what I was trying to do was make a copy of the CopController from the first time I call GetComponent, modify that copy, and then apply it when I’m done (hence line 6, which doesn’t work). My thinking was that way, I avoid calling GetComponent multiple times (I suspect it’s not as performant as I’d like). But I guess it is impossible to replace the component this way - I’d need to make a copy, then add a new component, then remove the old component that came with the prefab… right? In which case this is too much work and I’ll just use GetComponent on every line.

As @StarManta was saying above, GetComponent returns a reference to the original. So when you make changes to thing you got from GetComponent, you are making changes directly on the real thing. There’s no need to “apply” anything at the end.

1 Like

You may find it helpful to read about the differences between reference types and value types.

1 Like