- Home /
Copying a Component's values without a new Game Object
Hello, we have an issue that seems like it can't be solved due to the way MonoBehaviours are scripted, but we wanted to ask first before giving up.
Basically, we want to store the starting values of a Light component. The color, intensity, etc. are changed numerous times at runtime, but we want to be able to change them back to the values they started at.
Originally we thought we could somehow make a deep copy of the Light component and store it in a variable of type "Light", but we can't seem to make a deep copy without making an entirely new game object (which can't be destroyed because it will take the default values with it). This is not preferable, because it would essentially create a new game object for every single light we are changing. Is there really no way to store these values other than making a separate variable for every property (color, intensity, range, spotAngle, etc.) and assigning them manually?
maybe this post helps you:
http://answers.unity3d.com/questions/458207/copy-a-component-at-runtime.html
Answer by Bunny83 · Mar 04, 2017 at 05:51 PM
No, there's no other way. The built-in components are not just C# classes. They have a native C++ counterpart to which they are linked to. The C# Component class is basically just a wrapper for the native object. All those values aren't stored on the C# managed side but on the native C++ side. All those "properties" are properties which actually call a native code getter / setter.
The easiest solution is to write a "LightProperties" class which can store all the properties of one light. I quickly did this:
public class LightProperties
{
public float bounceIntensity;
public Color color;
public Texture cookie;
public float cookieSize;
public int cullingMask;
public bool enabled;
public Flare flare;
public float intensity;
public LightmappingMode lightmappingMode;
public float range;
public LightRenderMode renderMode;
public float shadowBias;
public int shadowCustomResolution;
public float shadowNearPlane;
public float shadowNormalBias;
public UnityEngine.Rendering.LightShadowResolution shadowResolution;
public LightShadows shadows;
public float shadowStrength;
public float spotAngle;
public LightType type;
public LightProperties() { }
public LightProperties(Light aLight)
{
Save(aLight);
}
public void Save(Light aLight)
{
bounceIntensity = aLight.bounceIntensity;
color = aLight.color;
cookie = aLight.cookie;
cookieSize = aLight.cookieSize;
cullingMask = aLight.cullingMask;
enabled = aLight.enabled;
flare = aLight.flare;
intensity = aLight.intensity;
lightmappingMode = aLight.lightmappingMode;
range = aLight.range;
renderMode = aLight.renderMode;
shadowBias = aLight.shadowBias;
shadowCustomResolution = aLight.shadowCustomResolution;
shadowNearPlane = aLight.shadowNearPlane;
shadowNormalBias = aLight.shadowNormalBias;
shadowResolution = aLight.shadowResolution;
shadows = aLight.shadows;
shadowStrength = aLight.shadowStrength;
spotAngle = aLight.spotAngle;
type = aLight.type;
}
public void Restore(Light aLight)
{
aLight.bounceIntensity = bounceIntensity;
aLight.color = color;
aLight.cookie = cookie;
aLight.cookieSize = cookieSize;
aLight.cullingMask = cullingMask;
aLight.enabled = enabled;
aLight.flare = flare;
aLight.intensity = intensity;
aLight.lightmappingMode = lightmappingMode;
aLight.range = range;
aLight.renderMode = renderMode;
aLight.shadowBias = shadowBias;
aLight.shadowCustomResolution = shadowCustomResolution;
aLight.shadowNearPlane = shadowNearPlane;
aLight.shadowNormalBias = shadowNormalBias;
aLight.shadowResolution = shadowResolution;
aLight.shadows = shadows;
aLight.shadowStrength = shadowStrength;
aLight.spotAngle = spotAngle;
aLight.type = type;
}
}
To save the state of a Light you can simply do:
LightProperties save = new LightProperties(yourLightComponent);
To restore the properties just do
save.Restore(yourLightComponent);
Of course it could be done with reflection, however there are a lot deprecated properties and some you usually don't want to save (like name, hideFlags, tag, ...). Also this version is faster than any reflection approach ^^. Creating that class only took a few minutes. Just a lot of copy&paste and smart search&replace.
I really appreciate the answer. It's unfortunate we can't make deep copies of lights, but this will work great! $$anonymous$$uch appreciated :)
Your answer
Follow this Question
Related Questions
Adding components from prefab into existing GameObject 2 Answers
[HOW] Copy and Transfer Component with Values to other object? 1 Answer
Copy / Paste As New not copying deep 1 Answer
Flashlight Flicker! 2 Answers
Toggle Light Component On and Off 1 Answer