Search Unity

Convert a variable type in C#

Discussion in 'Scripting' started by Xarbrough, Dec 17, 2014.

  1. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    1,188
    I am trying to write a script that lets my animate either the Image or the SpriteRenderer component of a gameobject, depending on which of the two is attached. I've noticed that my logic works for both types, but I don't know if and how it's possible to convert a variable type depending on what kind of component my script finds in Awake.


    Code (CSharp):
    1. spriteRenderer.sprite = SetMyCurrentFrame();
    2. image.sprite = SetMyCurrentFrame();

    Is it possible in C# to create some kind of Object variable and convert its type to whatever is attached to the gameobject? I'm trying something like this (pseudo code):


    Code (CSharp):
    1. public Object myRenderingComponent; //can be Image or SpriteRenderer
    2.  
    3. void Awake() {
    4.     try
    5.     {
    6.         myRenderingComponent = GetComponent<Image>();
    7.     }
    8.     catch (myRenderingComponent == null)
    9.     {
    10.         myRenderingComponent = GetComponent<SpriteRenderer>();
    11.     }
    12.     catch (myRenderingComponent == null)
    13.     {
    14.     Debug.Log("Please attach an Image or SpriteRenderer component!");
    15.     }
    16. }
    17.  
    18. void Update() {
    19.     //do my rendering code
    20.     myRenderingComponent.enabled = true;
    21.     myRenderingComponent.sprite = SetMyCurrentFrame();
    22.     //...
    23. }

    Thanks a lot for any tips!
     
  2. A.Killingbeck

    A.Killingbeck

    Joined:
    Feb 21, 2014
    Posts:
    483
    Could do it like:


    Code (CSharp):
    1.  
    2. public Component renderingComponent;
    3. public Sprite TheSprite;
    4.  
    5. void Awake()
    6. {
    7.    renderingComponent = GetComponent<Image>() ?? GetComponent<SpriteRenderer>();
    8.  
    9.    if(renderingComponent)
    10.    {
    11.      theSprite = renderingComponent.sprite;
    12.    }
    13.    else
    14.    {
    15.     Debug.Log("Please attach an Image or SpriteRenderer component!");
    16.    }
    17. }
    18.  
    19.  
    20. void Update()
    21. {
    22.    renderingComponent.enabled = true;
    23.    theSprite = SetMyCurrentFrame();
    24. }
    25.  
     
  3. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    1,188
    Thanks, that looks elegant, but Unity is giving me an error that the type "Component" doesn't contain a definition for "enabled" or "sprite".

    Maybe I need a custom type converter to cast from Image to SpriteRenderer or some custom class.
     
  4. TSnake

    TSnake

    Joined:
    Mar 12, 2014
    Posts:
    13
    enabled is strangly removed in Unity3D (bug?) but I don't know if that works if you use active.
    Code (CSharp):
    1. Component.active = true;
    And for convert a Image to SpriteRenderer and the inverte you can use a fonction like this:
    Code (CSharp):
    1.    public void UIImageFromSpriteRenderer(ref Image OutputImage,SpriteRenderer spriterenderer)
    2.     {
    3.         OutputImage.color = spriterenderer.color;
    4.         OutputImage.sprite = spriterenderer.sprite;
    5.         OutputImage.material = spriterenderer.material;
    6.     }
    7.    public void SpriteRendererFromUIImage(Image OutputImage, ref SpriteRenderer spriterenderer)
    8.     {
    9.         spriterenderer.color = OutputImage.color;
    10.         spriterenderer.sprite = OutputImage.sprite;
    11.         spriterenderer.material = OutputImage.material;
    12.     }
     
  5. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,697
    Component doesn't have an enabled property (never has).

    SpriteRenderer is descended from Renderer, which defines an enabled property.

    UnityEngine.UI.Image is descended from Behaviour, which defines a different enabled property.

    A simplified family tree is:
    • Component (no enabled property)
      • Renderer (enabled property)
        • SpriteRenderer
      • Behaviour (enabled property)
        • (a bunch of other classes)
          • Image
    You can still use this line from @A.Killingbeck -
    Code (csharp):
    1. renderingComponent = GetComponent<Image>() ?? GetComponent<SpriteRenderer>();
    But in your Update(), call a method similar to this:
    Code (csharp):
    1. void SetFrame(Component renderingComponent) {
    2.     if (renderingComponent is SpriteRenderer) {
    3.         var spriteRenderer = renderingComponent as SpriteRenderer;
    4.         spriteRenderer.enabled = true;
    5.         spriteRenderer... //(set your other SpriteRenderer-specific stuff here)
    6.     } else if (renderingComponent is UnityEngine.UI.Image) {
    7.         var image = renderingComponent as UnityEngine.UI.Image;
    8.         image.enabled = true;
    9.         image... //(set your other Image-specific stuff here)
    10.     }
    11. }
     
  6. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    1,188
    Thank you! TonyLi's suggestion works and also clears up the inheritance of the mentioned classes.