Can’t figure this one out. This is what I have (inside the coroutine obviously)…
Renderer[] renderers = this.gameObject.GetComponentsInChildren<Renderer>();
foreach(Renderer renderer in renderers){
renderer.material.Lerp(orgMat, evolveColor, 5f * Time.deltaTime);
}
I want to have the coroutine pause while this is taking place. I don’t want it to continue on until all the renderers material’s have been changed. I can’t conceive for the life of me how to put this in a while loop though, considering it’s not just ONE thing I’m waiting for. Any suggestions?
Possibly something like this?
IEnumerator Example() {
Renderer[] renderers = this.gameObject.GetComponentsInChildren<Renderer>();
int size = renderers.Length;
int index = 0;
while(index < size) {
renderers[index].material.Lerp(orgMat, evolveColor, 5f * Time.deltaTime);
if(orgMat == evolveColor) {
index++;
}
yield return null;
}
}
Jessy
January 15, 2015, 6:03pm
3
Neither this. nor gameObject. are necessary. GetComponentsInChildren is a method of Component .
I am neither here nor there on this but, this is not what the OP was asking for.
1 Like
Polymorphik:
Possibly something like this?
IEnumerator Example() {
Renderer[] renderers = this.gameObject.GetComponentsInChildren<Renderer>();
int size = renderers.Length;
int index = 0;
while(index < size) {
renderers[index].material.Lerp(orgMat, evolveColor, 5f * Time.deltaTime);
if(orgMat == evolveColor) {
index++;
}
yield return null;
}
}
The only problem with this is that it’s going to change them one at a time, and I need them all to Lerp simultaneously.
Oh you want them ALL okay try this
IEnumerator Example() {
Renderer[] renderers = this.gameObject.GetComponentsInChildren<Renderer>();
bool[] completed = new bool[renderers.Length];
bool isCompleted = false;
while(!isCompleted) {
for(int i = 0; i < renderers.Length; i++) {
renderers[i].materials[i].Lerp(orgMat, evolveColor, 5f * Time.deltaTime);
if(renderers[i].material == evolveColor) {
completed[i] = true;
}
}
foreach(bool checkState in completed) {
if(checkState == false) {
isCompleted = false;
break;
} else {
isCompleted = true;
}
}
yield return null;
}
}
Actually material.Lerp is values between 0 and 1 so…try this.
IEnumerator Example() {
Renderer[] renderers = this.gameObject.GetComponentsInChildren<Renderer>();
bool[] completed = new bool[renderers.Length];
float[] elapsedTimes = new float[renderers.Length];
bool isCompleted = false;
float time = 5.0f; // Total Time for it all to complete
float speed = 1.0f; // How fast we progress
while(!isCompleted) {
for(int i = 0; i < renderers.Length; i++) {
renderers[i].materials[i].Lerp(orgMat, evolveColor, elapsedTimes[i] / time);
if(renderers[i].material == evolveColor) {
completed[i] = true;
}
elapsedTimes[i]+= speed * Time.deltaTime;
}
foreach(bool checkState in completed) {
if(checkState == false) {
isCompleted = false;
break;
} else {
isCompleted = true;
}
}
yield return null;
}
}
Jessy
January 15, 2015, 6:54pm
8
If you’re not here to teach or learn as much as you can, I say GTFO. Put me on block if you disagree.
Every piece of code you don’t have to write is a step in the direction of realizing your vision.
This is a VERY piss poor attitude to have. @Polymorphik was right in saying you didn’t answer the OP. If you’re going to respond to a thread, at LEAST answer what was asked, before giving your two cents. (We’re not saying they’re not wanted.)
Jessy:
If you’re not here to teach or learn as much as you can, I say GTFO. Put me on block if you disagree.
Every piece of code you don’t have to write is a step in the direction of realizing your vision.
http://forum.unity3d.com/threads/unity-developer-network-rules.151494/
Read the rules and follow them or [quote=“Jessy, post:8, topic: 563610, username:Jessy”]
I say GTFO
[/quote]
.
Jessy
January 15, 2015, 7:09pm
11
Someone else responded, and I’ve only got so much time. You don’t appreciate my time and effort to improve you, me, and everyone else who comes along? Block me. I’m not offended. I’d prefer not to have this negativity in my life.
We are oft to blame in this,
'Tis too much proved, that with devotion’s visage
And pious action we do sugar o’er
The devil himself.
1 Like
Alright…so I also looked up the “material.Lerp” documentation and I see this isn’t right for what I’m trying to accomplish. What I ended up doing was writing a customer shader. Now I’m still kind of running into the same problem. Here’s the new code…
foreach(Renderer renderer in renderersArray){
materialsArray = renderer.materials;
originalMaterialsArray = renderer.materials;
orgMatList.Add(originalMaterialsArray);
foreach(Material material in materialsArray){
if(material.shader.name == "Toon/Basic Blender"){
float counter = material.GetFloat("_Blend");
while(counter != 1f){
float increase = material.GetFloat("_Blend") + 0.01f;
material.SetFloat("_Blend", increase);
counter += increase;
yield return null;
}
}
}
}
Obviously this is inside of an IEnumerator. The problem is that it’s only changing ONE of the materials inside the arrays, but I want it to change ALL of them (so long as they meet the criteria). What am I over-looking?
It looks like you are partially manipulating one material before returning to update.
If you want to manipulate all in one frame, this pseudocode might be what you are looking for.
Foreach(renderer){ if(matches criteria) StartCoroutine(manipulate single material)}
EDIT: In the above post, if you want to change all materials, just move the yield outside of the foreach loop.
I gave that a shot @Random_Civilian this way:
private IEnumerator Change(){
foreach(Renderer renderer in renderersArray){
materialsArray = renderer.materials;
foreach(Material material in materialsArray){
yield return StartCoroutine(ChangeToWhite(material));
}
}
yield return null;
}
private IEnumerator ChangeToWhite(Material mat){
if(mat.shader.name == "Toon/Basic Blender"){
float counter = mat.GetFloat("_Blend");
while(counter != 1f){
float increase = mat.GetFloat("_Blend") + 0.01f;
mat.SetFloat("_Blend", increase);
counter += increase;
yield return null;
}
}
}
Didn’t work. It’s still only changing the very first material in the “materialsArray” and that’s it.
Alright, I found a work-around, but I’m SURE there’s got to be a more “efficient” way.
private Renderer[] renderersArray;
private List<Material> materialsList = new List<Material>();
private IEnumerator Change(){
foreach(Renderer renderer in renderersArray){
for(int i = 0; i < renderer.materials.Length; i++){
materialsList.Add(renderer.materials[i]);
}
}
foreach(Material material in materialsList){
StartCoroutine(ChangeToWhite(material));
}
changedForm = Instantiate(changeInto, this.transform.position, this.transform.rotation) as GameObject;
yield return null;
}
private IEnumerator ChangeToWhite(Material mat){
if(mat.shader.name == "Toon/Basic Blender"){
float counter = mat.GetFloat("_Blend");
while(counter != 1f){
float increase = mat.GetFloat("_Blend") + 0.01f;
mat.SetFloat("_Blend", increase);
counter += increase;
yield return null;
}
}
}
Now I just have to get to not execute line 15 until all of the materials have reached their desired blend level.
This might be what you are looking for and simple (on phone right now so sorry for formatting). IN CO ROUTINE:
While (matlistcount> 0)
ENUMERATE LIST BACKWARDS, manipulate,If (criteria met) remove from list
Yield outside of enumeration but inside while loop.
I’m sure your idea might have worked @Random_Civilian and thanks for posting it. I got it solved another way.
foreach(Material material in materialsList){
StartCoroutine(ChangeToWhite(material));
yield return new WaitForSeconds(1);
}
private IEnumerator ChangeToWhite(Material mat){
float counter = mat.GetFloat("_Blend");
while(counter != 1f){ //the 1 here is the time to wait
float increase = mat.GetFloat("_Blend") + Time.deltaTime;
mat.SetFloat("_Blend", increase);
counter += increase;
yield return null;
}
}