Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Changing Animated Knight Color :<

Discussion in 'Editor & General Support' started by MSong, Mar 30, 2015.

  1. MSong

    MSong

    Joined:
    Mar 30, 2015
    Posts:
    12
    Hello everyone, I've been using Unity for a couple days now and while I'm getting used to everything, there is this one very specific issue that I haven't seen answers for.
    I've been using this free model (Animated Knight and Slime Monster) to play around with Unity for a while. I've been creating an ability where on fire1 - the character will create 3 dummies of himself that attack the enemy. On instantiation, the dummies play an attack animation and are supposed to fade out their alpha color.
    I can't at all seem to change the color.
    Tried the renderer.material.color thing, doesn't work - give me errors saying object doens't have renderer
    Tried to GetComponentsInChildren<SkinnedMeshRenderer>(), but that doesn't work either...
    Can't even change the base alpha in the materials.. :<

    Can someone help me change the color on this thing?
    Here's the asset.
    https://www.assetstore.unity3d.com/en/#!/content/24471
    Thanks in advance.
     
  2. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    hmm looks like it uses a custom shader.
    I'll go check

    options.JPG

    this is not the BEST way - just A way (from memory so check syntax)

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class changeColour : MonoBehaviour {
    6.  
    7. GameObject knight;
    8. SkinnedMeshRenderer smr;
    9. // Use this for initialization
    10. void Start () {
    11. knight = GameObject.Find("Knight");
    12.  
    13. smr = knight.GetComponent<SkinnedMeshRenderer>();
    14. }
    15.  
    16. // maybe I will make this static..
    17. public void changeRimColor () {
    18.  
    19. // Working on it.
    20.  
    21. }
    22. }
    23.  
    gets you your components. let me go check the exact syntax for that material config.
     
    Last edited: Mar 30, 2015
  3. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    okay... so possible values (assuming you are using that default shader)

    possibleValues.JPG

    Let me whip up some code
     
  4. MSong

    MSong

    Joined:
    Mar 30, 2015
    Posts:
    12
    Thanks for the response twobob, but unfortunately I'vetried that before and it only changes the rim color of the material.
     
  5. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class ChangeColour : MonoBehaviour
    6. {
    7.  
    8. private GameObject knight;
    9. private SkinnedMeshRenderer smr;
    10. public Color colorToBecome;
    11. private bool __colorChangeInAction;
    12. public bool TriggerColorChange;
    13.  
    14.  
    15. // Use this for initialization
    16. void Start()
    17. {
    18. knight = GameObject.Find("Knight");
    19.  
    20. smr = knight.GetComponent<SkinnedMeshRenderer>();
    21. }
    22.  
    23.  
    24. public void changeRimColor(Color colorToBe)
    25. {
    26.  
    27. // Working on it.
    28.  
    29. smr.sharedMaterials[1].SetColor("_RimColor", colorToBe);
    30.  
    31. __colorChangeInAction = false;
    32. TriggerColorChange = false;
    33. }
    34.  
    35. void Update()
    36. {
    37.  
    38. // we do this for when we start doing changes that spread over more than one frame....
    39. if (TriggerColorChange && !__colorChangeInAction)
    40. {
    41. __colorChangeInAction = true;
    42. changeRimColor(colorToBecome);
    43. }
    44. }
    45. }
    46.  
    interface.JPG

    green.JPG

    purple.JPG
     
    Last edited: Mar 30, 2015
  6. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    Well yeah. There is no Tint Color value in the shader. (and I called it "changeRimColor")... ;)

    I am demonstrating how to pass ANY value into the shader.

    So.. next up... adjusting shader. bear with me...

    Alternately.. Apply the DEFAULT shader and put the texture in the albedo bit..
    (but you lose the rim....)

    Will do that afterwards.
     
    Last edited: Mar 30, 2015
  7. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    if you /do/ just want to "Get" a color value and forget the rim...

    switch the shader.
    DefaultShader.JPG
    Let me know as I won't bother adjusting that ancient shader otherwise...
     
  8. MSong

    MSong

    Joined:
    Mar 30, 2015
    Posts:
    12
    I have 4.6.x I can't find the standard so Im using another shader, and now the transparency works, but I'm realizing that code treats each object created as one uniform thing which I don't want. So if i create a dummy knight and apply anything new to him, all the other instance dummy knight will have the same transparency as the last dummy knight made.

    Code (CSharp):
    1. void Attack ()
    2.     {
    3.         // Reset the timer.
    4.         Vector3 newVec = transform.position;
    5.         Quaternion rotation = body.rotation;
    6.         Ray line = new Ray (newVec, transform.forward);
    7.         Vector3 spawnVec = line.GetPoint (200f);
    8.         timer = 0f;
    9.         anim.CrossFade ("Attack");
    10.  
    11.         StartCoroutine(Loop(spawnVec, rotation));
    12.     }
    13.  
    14.     IEnumerator Loop (Vector3 vec, Quaternion rotation)
    15.     {
    16.         for (int i = 3; i>0;i--){
    17.         DestroyObject (Instantiate (knight, vec, rotation), 1.65f);
    18.         yield return new WaitForSeconds(.12f);
    19.         }
    20.     }
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class DummyKnightAttack : MonoBehaviour {
    5.  
    6.     public float fadeTime = 1.5f;
    7.     Color full = new Color(1f, 1f, 1f, 1f);
    8.     Color fade = new Color(1f, 1f, 1f, 0f);
    9.     // Use this for initialization
    10.     Animation anim;
    11.     void Start () {
    12.         GameObject knight;
    13.         SkinnedMeshRenderer smr;
    14.         anim = GetComponent<Animation> ();
    15.         anim.CrossFade ("Attack");
    16.         anim.CrossFadeQueued ("Wait");
    17.         knight = GameObject.Find ("Knight");
    18.         smr = knight.GetComponent<SkinnedMeshRenderer> ();
    19.  
    20.         StartCoroutine (Loop (smr));
    21.     }
    22.  
    23.     IEnumerator Loop (SkinnedMeshRenderer smr){
    24.         float currentTime = 1.5f;
    25.         while (currentTime >= 0.0){
    26.             currentTime -= .1f;
    27.             smr.materials [0].color = Color.Lerp (fade, full, currentTime/fadeTime);
    28.             smr.materials [1].color = Color.Lerp (fade, full, currentTime/fadeTime);
    29.             yield return new WaitForSeconds(.1f);
    30.         }
    31.     }
    32.     /*
    33.                      
    34.     // Update is called once per frame
    35.     void Update () {
    36.         currentTime -= Time.smoothDeltaTime ;
    37.         smr.materials [0].color = Color.Lerp (fade, full, currentTime);
    38.         smr.materials [1].color = Color.Lerp (fade, full, currentTime);
    39.     }
    40.  
    41. */
     
    Last edited: Mar 30, 2015
  9. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    4.6? Doesn't have a standard shader

    I'll have a look
     
  10. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
  11. MSong

    MSong

    Joined:
    Mar 30, 2015
    Posts:
    12
    The transparency fade works, I've just come across a new problem. Objects created aren't given independent gameobject Knight, so if I change the transparency on one dummy, all of them change transparency. So everytime I attack the alpha resets for all dummies created.

    edit: trying sharedmaterials sorry didn't read properly.

    edit2: nop dosn't work. btw Thanks so much for the help, this just isa new problem all of a sudden :>
     
  12. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
  13. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    Renderer.material
    public Material material;
    Description
    Returns the first instantiated Material assigned to the renderer.

    Modifying material will change the material for this object only.

    If the material is used by any other renderers, this will clone the shared material and start using it from now on.
    If you edit the "base" object, any clones made from it will also be affected.
     
  14. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    so you could manually assign new materials I suppose
    renderer.materials[0] = new Material(renderer.sharedMaterial); (something like that)

    Then only deal with that
     
  15. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    The final color modifier example (and the others) are helpful if you want to adjust an old shader (like that one)

    cheers :)

    good luck
    surfaceShaderFinalColorModifier.JPG
     
  16. MSong

    MSong

    Joined:
    Mar 30, 2015
    Posts:
    12
    Code (CSharp):
    1. knight = GameObject.Find  ("Knight");
    2.         smr = knight.GetComponent<SkinnedMeshRenderer> ();
    3.         smr.materials [0] = new Material (smr.sharedMaterials[0]);
    4.         smr.materials [1] = new Material (smr.sharedMaterials[1]);
    5.         knight = GameObject.Find ("Sword02");
    6.         swmr = knight.GetComponent<SkinnedMeshRenderer> ();
    7.         swmr.materials [0] = new Material (swmr.sharedMaterials[0]);
    8.         currentTime = fadeTime;
    9.     }
    10.            
    11.     // Update is called once per frame
    12.     void Update () {
    13.         currentTime -= Time.smoothDeltaTime ;
    14.         smr.materials [0].color = Color.Lerp (fade, full, currentTime);
    15.         smr.materials [1].color = Color.Lerp (fade, full, currentTime);
    16.         swmr.materials [0].color = Color.Lerp (fade, full, currentTime);
    17.     }
    So I've tried this,.. but doesn't work, still all the materials are being treated as one. - I'll try the shader thing a little later - thanks.

    edit2: the final color thing works, but only for the tint not the alpha is there a way i can change that too? tried adding keepalpha option but still doesn't work
     
    Last edited: Mar 30, 2015
  17. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    smr = knight.GetComponent<SkinnedMeshRenderer> ();

    refers to the first - parent - the clone seed.

    Have you tried directly referencing the spawned clones...

    errr.. I don't generally do this as I use pools so.. bear with me..


    GameObject thingy = Instantiate (knight, vec, rotation) as GameObject // ( I think)

    // now work with "thingy" and it's properties

    // now kill it
    DestroyObject (
    thingy,
    1.65f
    );
     
  18. MSong

    MSong

    Joined:
    Mar 30, 2015
    Posts:
    12
    Sorry is there a better way to do this? That creates more problems and as GameObject's getter functions are static and won't work on instances. Can't do thingy.Find("Knight") or thingy.Find("Sword02");;
     
  19. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    Why do you need to?

    thingy IS the gameobject. so "Knight" effectively in that context...
    I am no longer sure I am clear what you want to do...


    if you have something in "thingy"s children you don't want to use Find as that is the very worst, slowest way of finding things.

    you can use thingy.GetComponent<(and a type>() or thingy.FindComponentsInChildren<type>()

    or if you specifically want a gameObject thingy.transform.child[0] <-- then do something with the child - in fact there are a whole bunch of methods available on the thingy GameObject.

    use those?



    Why not work through one of the unity example projects and learn a bit more about how it has been done in the past. These types of things are covered in the HOWTOS

    http://unity3d.com/learn/tutorials/modules/beginner/scripting
    http://unity3d.com/learn/tutorials/modules/beginner/scripting/getcomponent

    :) hope it helps
     
    Last edited: Mar 30, 2015
  20. MSong

    MSong

    Joined:
    Mar 30, 2015
    Posts:
    12


    I'm trying to do something like this. It's a little character I created in star craft 2. I'm not sure if you're familiar with the editor or not, but when the character moves - it creates trails of the same character and fades them out and they all ahve different times when they fade out to 0 alpha. I'm not doing exactly that but it's the same concept. I want to create different units that fadeout at the same time but they use the same gameObject.

    I understand what getComponent is, but I don't understand how I would get to the materials since the structure of GameObject is as below. Could you be more specific, those scripting vices are very generic.

    DummyKnight - Unit that we are creating.
    Knight - Child of DummyKnight containing SkinnedMeshRenderer
    SkinnedMeshRenderer
    Material[0]
    Material[1]
    Sword02 - Child of DummyKnight containing SkinnedMeshRenderer
    SkinnedMeshRenderer
    Material[0]

    How would I reference
     
  21. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    rough guide (where = means can be found by)

    DummyKnight = gameobject (as in, gameobject is the keyword) or w/e name like "thingy" for the instance reference.
    Knight = gameobject.transform.child[0] (or "children" I don't have an IDE in front of me, but like that)

    SkinnedMeshRenderer smr = gameobject.transform.child[0].GetComponent<SkinnedMeshRenderer >();
    Material[0] = smr.SharedMaterials[0]; (or material depending on what you want to happen)

    or Material[0] = gameobject.transform.child[0].GetComponent<SkinnedMeshRenderer >().SharedMaterials[0]; // Full path


    Sword02 = gameobject.transform.child[1] blah blah blah

    does that help?


    And they were generic links because this is a general lack of understanding of general referencing principles. Short of linking to a specific answer where someone explained - at length - the way components and gameObjects are found; simply linking to everything made most sense.
     
    MSong likes this.
  22. MSong

    MSong

    Joined:
    Mar 30, 2015
    Posts:
    12
    Yes it did, but I had to do this
    transform.getChild(0).Find("Knight").
    Thanks its working properly now.
     
  23. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    2,058
    nice one ;)

    Glad to hear it mate.
     
    MSong likes this.