- Home /
Is it possible to change Outline at runtime?
Hello, I'm attempting to change the effect distance of an Outline component that I've attached to a UI Text object at run time. I've attached the following simple script to the Text object which should theoretically reduce the effect distance of an outline over a small period of time.
using UnityEngine;
using UnityEngine.UI;
public class OutlineXAdjust : MonoBehaviour
{
public float speed = 10;
private Outline outline;
void Start()
{
outline = GetComponent<Outline>();
}
void Update()
{
outline.effectDistance.Set(Mathf.MoveTowards(outline.effectDistance.x, 0, Time.deltaTime * speed), 0);
Debug.Log(outline.effectDistance.x);
}
}
For some magical reason however, nothing happens, and the debug continually logs the starting value of outline.effectDistance.x I've tried adjusting the effectColor as well but have had no success there either. Anyone have any idea what the problem is? Many thanks in advance
Answer by Mikilo · Aug 31, 2015 at 05:38 PM
Hello!
Because effectDistance is a struct.
Replace your Update()
void Update()
{
outline.effectDistance = new Vector2(Mathf.MoveTowards(outline.effectDistance.x, 0, Time.deltaTime * speed), 0);
Debug.Log(outline.effectDistance.x);
}
You are welcome. (4 minutes to answer? Not my best score...)
You sir, are the man! Thanks so much for helping me out with that. I was also able to apply that approach to the effectColor:
using UnityEngine;
using UnityEngine.UI;
public class HueShiftTextOutline : $$anonymous$$onoBehaviour
{
public Color[] colors; //set your colors up in the inspector
public float changeColorTime = 0.5f;
public int currentIndex = 0;
private int nextIndex;
private float lastChangeTime;
private float timer = 0.0f;
private Outline outline;
private Color tempColor;
void Start()
{
outline = GetComponent<Outline>();
if (colors == null || colors.Length < 2)
{
Debug.Log("Need to setup colors array in inspector");
}
nextIndex = (currentIndex + 1) % colors.Length;
}
void Update()
{
timer += Time.deltaTime;
if (timer > changeColorTime)
{
currentIndex = (currentIndex + 1) % colors.Length;
nextIndex = (currentIndex + 1) % colors.Length;
timer = 0.0f;
}
tempColor = colors[currentIndex]; // Hard swtich between colors
//tempColor = Color.Lerp(colors[currentIndex], colors[nextIndex], timer / changeColorTime); // Smooth transition between colors
outline.effectColor = new Color(tempColor.r, tempColor.g, tempColor.b);
}
}
Credit where it belongs, much of this script was adapted from a post made by roberbu
I'm curious though, why does it being a struct cause the issue?
Pretty clear and simple.
A struct is a value-type, when you use Set it will override fields of a COPY of that struct.
Therefore, it works the same way for transform.position, localPosition, rotation, etc...
Have a good day mister Chuck!
Ah, that makes sense. I guess I must have misinterpreted the description of the Set function. When would be an appropriate time/place to use Set? Thanks again for your words of wisdom :)
Also, for future viewers, I found this website to be very helpful in understanding the difference between value types and reference types.
You can use Set. That is not the problem, let me show you.
Vector3 pos = transform.position;
pos.Set(1F, 2F, 3F);
transform.position = pos;
It seems obviously not suitable... but who knows. It seems that Set will assign new values to a copy when using directly on transform.position.
So with
Vector3 pos;
pos.Set(1F, 2F, 3F);
the difference between
transform.position = pos;
and
transfrom.postion.Set(1F, 2F, 3F);
would be that in the latter you're only modifying the reference and therefore not modifying the actual position (/value?) of the object?