[SOLVED]How to Change a Serialized Field Value Through Code Via Another Script

So right now I’m developing a game in which I need decals to be displayed on vehicles. I got a decal editor asset from the unity store( I think it was called DecalSystem), I had to change the code around a little bit to get it to work during runtime. The way it kinda works (from my understanding), is that it grabs a material, and from that material grabs whatever sprite/sprites are on it, and it uses those two things to create and draw the decal. However, one of the scripts involved with this system has two serialized fields. I guess originally you were meant to click on these fields/drop downs, to select the material you wanted, along with which sprite you wanted of that material to draw the decal. However, for my use, I want to assign the sprite within the serialized field through another script. For some reason when I try to access the Sprite serialized field, it won’t assign the sprite that I chose in the script. I’m new to serialization, so if somebody could help enlighten me on what I need to do to change the serialized field through another script that would be great. Below I’ll add some pictures and code to clarify.

Script Containing Serialized Fields:

namespace DecalSystem {
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using UnityEditor;
    using UnityEngine;
    using UnityEngine.Serialization;

    [RequireComponent( typeof( MeshFilter ) )]
    [RequireComponent( typeof( MeshRenderer ) )]
    [ExecuteInEditMode]
    public class Decal : MonoBehaviour {

        [FormerlySerializedAs( "material" )] public Material Material;

        //the field im trying to access
        [FormerlySerializedAs( "sprite" )] public Sprite Sprite;

        [FormerlySerializedAs( "affectedLayers" ), FormerlySerializedAs( "AffectedLayers" )] public LayerMask LayerMask = -1;
        [FormerlySerializedAs( "maxAngle" )] public float MaxAngle = 90.0f;
        [FormerlySerializedAs( "pushDistance" ), FormerlySerializedAs( "PushDistance" )] public float Offset = 0.009f;

        private Vector3 oldScale;

        public MeshFilter MeshFilter {
            get {
                return gameObject.GetComponent<MeshFilter>() ?? gameObject.AddComponent<MeshFilter>();
            }
        }
        public MeshRenderer MeshRenderer {
            get {
                return gameObject.GetComponent<MeshRenderer>() ?? gameObject.AddComponent<MeshRenderer>();
            }
        }


        [MenuItem( "GameObject/Decal" )]
        internal static void Create() {
            new GameObject( "Decal", typeof( Decal ), typeof( MeshFilter ), typeof( MeshRenderer ) ).isStatic = true;
        }


        public void OnValidate() {
            if (!Material) Sprite = null;
            if (Sprite && Material.mainTexture != Sprite.texture) Sprite = null;

            MaxAngle = Mathf.Clamp( MaxAngle, 1, 180 );
            Offset = Mathf.Clamp( Offset, 0.005f, 0.05f );
        }

        void Awake() {
            var mesh = MeshFilter.sharedMesh;
            var meshes = GameObject.FindObjectsOfType<Decal>().Select( i => i.MeshFilter.sharedMesh );
            if (meshes.Contains( mesh )) MeshFilter.sharedMesh = null; // if mesh was copied
        }

        void OnEnable() {
            //if (Application.isPlaying) enabled = false;
        }

        void Update() {
            if (transform.hasChanged) {
                transform.hasChanged = false;
                BuildAndSetDirty();
            }
        }


        void OnDrawGizmosSelected() {
            Gizmos.matrix = transform.localToWorldMatrix;
            Gizmos.color = Color.green;
            Gizmos.DrawWireCube( Vector3.zero, Vector3.one );

            var bounds = DecalUtils.GetBounds( this );
            Gizmos.matrix = Matrix4x4.identity;
            Gizmos.color = Color.white;
            Gizmos.DrawWireCube( bounds.center, bounds.size + Vector3.one * 0.01f );

            //Gizmos.matrix = transform.localToWorldMatrix;
            //Gizmos.color = Color.yellow;
            //var mesh = MeshFilter.sharedMesh;
            //if (mesh) {
            //    var vertices = mesh.vertices;
            //    var normals = mesh.normals;
            //    for (var i = 0; i < vertices.Length; i++) {
            //        Gizmos.DrawRay( vertices[ i ], normals[ i ] * 0.15f );
            //    }
            //}
        }


        public void BuildAndSetDirty() {
            if (Sprite) DecalUtils.FixRatio( this, ref oldScale );
            DecalBuilder.Build( this );
            DecalUtils.SetDirty( this );
        }


    }
}

Part of script that tries to access “sprite” from above script:

IEnumerator ToggleLeftWaiter()
    {

        yield return new WaitForSecondsRealtime(0.09f);

        if (canToggle == false)
        {

          


          
            index--;

            if (index < 0)
            {
                index = decalprefab.Length - 1;

            }

            selectedDecal = index + 1;
          
          


            //changes the texture of the material that the serialized script uses
            decalRightSidePos.GetComponent<Renderer>().sharedMaterial.mainTexture = decalprefab[index].texture;
            decalLeftSidePos.GetComponent<Renderer>().sharedMaterial.mainTexture = decalprefab[index].texture;

           //my attempt at trying to change the sprite serialized field to my selected sprite
            decalRightSidePos.GetComponent<Decal>().Sprite = decalprefab[index];
            decalLeftSidePos.GetComponent<Decal>().Sprite = decalprefab[index];
            canToggle = true;
        }



    }

The “Decal” script is the one that I’m trying to access. The attached file shows what the Decal script looks like in the inspector.

Turns out what I was doing was correct, the problem resided in my initial setup before I attempted to change decals. Somehow the actual material disappeared from the the object that had the Decal script, which ended up bringing back a nullexception because there was no material to get a sprite from. After fixing some stuff on the inspector side in the object receiving the decal I was able to resolve the issue.

1 Like