Jump to content

Help with stopping part thumbnail model from changing when part is changed in editor


Recommended Posts

I am making a part module that will change the color of one of a part's rendered meshes, but am getting an annoying bug where model in the preview thumbnail changes to the color of the part instance in the editor that was most recently changed. It is the right color (whatever is defined in the part.cfg) when first loading into the editor or spawning a new instance of the part, but then will still change afterwards. Any help I can get to fix this would be appreciated.

So far I have tried instantiating the part, both in onAwake() (makes it so that both the preview model and the part I'm trying to change the color of don't change, until the part is loaded in a new scene) and in onStart() (bad idea, calls itself recursively), along with messing around with the prefabs, because I read that they have something to do with the preview model here, although I've had no luck with this so far.

Javascript is disabled. View full album


using System;using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;


namespace KSPModelRocketry
{
public class VariableTexture : PartModule
{


public static float scale = 21;


[KSPField(guiActiveEditor = true, guiName = "Red", guiFormat = "F2", isPersistant = true)]
[UI_FloatRange(minValue = 0, maxValue = 1, stepIncrement = .05f)]
public float red = 1f;
private float r;


[KSPField(guiActiveEditor = true, guiName = "Green", guiFormat = "F2", isPersistant = true)]
[UI_FloatRange(minValue = 0, maxValue = 1, stepIncrement = .05f)]
public float green = 1f;
private float g;


[KSPField(guiActiveEditor = true, guiName = "Blue", guiFormat = "F2", isPersistant = true)]
[UI_FloatRange(minValue = 0, maxValue = 1, stepIncrement = .05f)]
public float blue = 1f;
private float b;


[KSPField]
public string textureMeshName = "Variable";
public Mesh textureMesh;
public Renderer texRend;
public Material mat;


[KSPField]
public bool newUV = true;


public float updateDelay = 0;


public override void OnAwake()
{
changeColor(true);
setUV(newUV);
base.OnAwake();
}


/// <summary>
/// Raises the start event.
/// </summary>
/// <param name="state">State.</param>
public override void OnStart(StartState state)
{
changeColor(true);
setUV(newUV);
base.OnStart(state);
}
/// <summary>
/// Standardizes the uv coords of the mesh.
/// </summary>
private void setUV(bool newUV)
{
if (textureMesh == null)
{
textureMesh = part.FindModelComponent<MeshFilter>(textureMeshName).mesh;
}
if (newUV)
{
Vector2[] uvs = new Vector2[textureMesh.vertices.Length];
for (int i = 0; i < uvs.Length; i++)
{
int j = i % 4;
switch (j)
{
case 0:
uvs[i] = Vector2.zero;
break;
case 1:
uvs[i] = Vector2.up;
break;
case 2:
uvs[i] = Vector2.right;
break;
case 3:
uvs[i] = Vector2.one;
break;
}
}
textureMesh.uv = uvs;
}
}


/// <summary>
/// Called every frame.
/// </summary>
public void Update()
{
if (HighLogic.LoadedSceneIsEditor)
{
updateDelay -= Time.deltaTime;
if (updateDelay <= 0)
{
changeColor();
updateDelay = 0.02f;
}
}
}


/// <summary>
/// Changes the color of a mesh of a part implementing this PartModlue based on it's red, green, and blue values.
/// </summary>
public void changeColor(Boolean forceChange = false)
{
if (texRend == null)
{
texRend = part.FindModelComponent<Renderer>(textureMeshName);
mat = new Material(texRend.material.shader);
}
if (red != r | green != g | blue != b | forceChange)
{
r = red;
g = green;
b = blue;
Color color = new Color(r, g, B);
Texture2D tex = new Texture2D(10, 10);
Color[] colors = new Color[tex.height * tex.width];
for (int i = 0; i < colors.Length; i++)
{
colors[i] = color;
}
tex.SetPixels(colors);
tex.Apply();
mat.mainTexture = tex;
texRend.material = mat;
if (forceChange)
{
print("[VariableTexture]:Changing Color! " +color);
}
}
}
}
}



Edit: was testing a little more and noticed that when you load in a vessel with multiple of the same part that implements the partmodule, they are all the same color. this was working before I added onAwake() (which I added to try and make the parts the right color in the editor) as seen here:

xL54br1.png

Edited by SuperRedNova
another problem
Link to comment
Share on other sites

I don't have any ideas about what the cause of your issue is, but there are a few odd things in that script

1) Identical code in OnAwake and OnStart

Use one or the other, there's no point using both for the same purposes. My intepretation of Awake in that it exists so you can ensure variables are initialised before other modules go looking for it in Start which just isn't an issue here

2) The delay code in Update

What is that for? If you want to skip a frame between running setColor, toggle a boolean or use a coroutine. That delay depends on Time.deltaTime being exactly what you expect it to be for any user which is not guaranteed

Link to comment
Share on other sites

I've since fixed this by setting the original texture to the desired color and getting rid of the onAwake method entirely, which isn't my prefered way but it gets the job done.

My logic for having both methods was this: just having onStart would leave the texture for the model in the thumbnail, so I had added the awake method, but I still needed the onstart method to try and set the color for each instance of the part that was on the vessel when loading in to a new scene. This ended up causing more problems then it solved, unfortunately.

Thanks for pointing out the delay code though, I had had it in there because I saw it in someone else's code that seemed like they were trying to do something similar, but now that I think about it isn't really needed.

Link to comment
Share on other sites

Unity will try to serialize public fields and copy them to the new clone. This causes all of your clones to try to manipulate the same Renderer since your if statements will only cause a new Renderer and Material to be created once during the load screen. Make those fields private or mark them [DontSerialize], or rework your code to remove that kind of state checking logic

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...