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.