Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Hugbot · Apr 05, 2013 at 03:55 AM · animationtiling

Making a Tiled Animated Image With a Material

I'm pretty positive the answer to this is no, but I wanted to check here to make sure.

I have two classes that work with a plane to render a texture onto it. The first class "AnimatedImage.cs" uses a Material and works with the offsets and tiling to animate over the texture so that it is displayed on to the plane.

The second class "TiledImage.cs" works by using the material to wrap over a specified sized image, where it's size is set, and then via the tiling spans it accordingly across the area.

Both of them interact through the material a same way, by modifying the tiling and offset accordingly. My goal is to convert the "TiledImage.cs" into an "AnimatedTileImage.cs" so that when it tiles I can animate it as well.

Below is the code for the two classes. I'm looking for any opinions or suggestions on how to correctly perform this, if at all possible.

//---------------------------------------------------------------- START OF CLASS //----------------------------------------------------------------

 using UnityEngine;
 using System.Collections;
 
 public class AnimatedImage : MonoBehaviour {
     public int columnSize = 1;
     public int rowSize = 1;
     
     public int currentFrame = 0;
     public int startFrame = 0;
     public int endFrame = 0;
     
     public float lastUpdateTime = 0;
     public float framesPerSecond = 12;
     
     public Material spriteTexture;
     
     //tells to animate or not
     public bool isAnimating = true;
     public bool flipImage = false;
     public bool animateOnce = false;
     
     public GameObject renderPlane;
     
     public float defaultXRotation = 0;
     public float defaultYRotation = 0;
     public float defaultZRotation = 0;
     
     //Used to manage the image size, concern should be applied though, on account that
     //it won't be adjusting the scale for this, so scale will still be 1, and the image may
     //be far larger than that... not sure what the repercussions are for this
     public float imageWidth = 1;
     public float imageHeight = 1;
     public float imageDepth = 1;
     
     public virtual void Start() {
         performAnimatedImageConfiguration();
         
         //You need to call this if the image isn't animating otherwise the image displayed will be
         //entire texture used. This will set the offset and size to the location on the texture/material
         //being used
         if(isAnimating == false) {
             SetToCurrentFrameOnTexture();
         }
     }
     
     public virtual void Update () {
         //updates animation
         if(isAnimating || animateOnce) {
             UpdateAnimation();
         }
     }
     
     //update the animation
     public void UpdateAnimation() {
         //something something helps with fps?? Maybe?? seems to work
         if((Time.time - lastUpdateTime) > 1/framesPerSecond) {
             lastUpdateTime = Time.time;
             if(currentFrame < endFrame) {
                 currentFrame++;
             }
             if(currentFrame >= endFrame && (!animateOnce || isAnimating) ) {
                 currentFrame = startFrame;
             }
         }
         
         SetToCurrentFrameOnTexture();
     }
     
     public void SetToCurrentFrameOnTexture() {
         Vector2 size = new Vector2((float)(1.0 / columnSize), (float)(1.0 / rowSize));
        
         // split into horizontal and vertical index
         int uIndex = currentFrame % columnSize;
         int vIndex = currentFrame / columnSize;
     
         // build offset
         // v coordinate is the bottom of the image in opengl so we need to invert.
         Vector2 offset = new Vector2((float)(uIndex * size.x), (float)(1.0 - size.y - vIndex * size.y));
           
         renderPlane.renderer.material.SetTextureOffset ("_MainTex", offset);
         renderPlane.renderer.material.SetTextureScale ("_MainTex", size);
     }
     
     public void performAnimatedImageConfiguration() {
         renderPlane = GameObject.CreatePrimitive(PrimitiveType.Plane);
         DestroyImmediate(renderPlane.collider);
         
         renderPlane.transform.parent = this.transform;
         renderPlane.transform.position = this.transform.position;
         renderPlane.transform.rotation = Quaternion.Euler(defaultXRotation, defaultYRotation, defaultZRotation);
         renderPlane.transform.localScale = new Vector3(1, 1, 1);
         
         configureSprite();
         setFlipImage(flipImage);
         configureTwoTriangleMeshFilter();
     }
     
     /*
     This is a cludgy solution to a problem that I was concerned about with animated images.
     The problem being that when rendering on a plane way more triangles and vertices are used
     than needed. In order to circumvent this I've used a solution/example from the unity documentation
     and modified it so that there aren't any issues integrating it. The problem being that it fixes a 
     number of weird bugs on my list... and I'm not sure why. The player no longer needs to be rotated
     initially because it's handled by assumedly the normals configured in this solution. I don't
     think this is a complete fix to a lot of our concerns, but I honestly feel that it will allow
     us the ability to limp through the rest of our game without many concerns about wasting resources
     on our animated images.
     
     Again this is modified from the initial example, so use this link for reference if you need
     a referesher:
     http://docs.unity3d.com/Documentation/Manual/Example-CreatingaBillboardPlane.html
     */
     public void configureTwoTriangleMeshFilter() {
         //This gets the meshfilter and provides a reference to it so it can be changed
         //accordingly... There is a new mesh declared because we are changing it out
         //so that it is a more simple mesh rendering.
         MeshFilter mf = renderPlane.GetComponent<MeshFilter>();
         Mesh mesh = new Mesh();
         mf.mesh = mesh;
         
         //This configures the amount of vertices used on the plane, making it so that
         //there are just four points used for rending. The width and height are used
         //as a way to offset correctly from the center point of the game object being used
         Vector3[] vertices = new Vector3[4];    
         vertices[0] = new Vector3(-imageWidth/2, -imageHeight/2, 0);
         vertices[1] = new Vector3(imageWidth/2, -imageHeight/2, 0);
         vertices[2] = new Vector3(-imageWidth/2, imageHeight/2, 0);
         vertices[3] = new Vector3(imageWidth/2, imageHeight/2, 0);    
         mesh.vertices = vertices;
     
         //This configures the triangles to be used for rendering and associates them
         //with the vertices declared above
         int[] tri = new int[6];
         //triangle one
         tri[0] = 0;
         tri[1] = 2;
         tri[2] = 1;
         //triangle two
         tri[3] = 2;
         tri[4] = 3;
         tri[5] = 1;
         mesh.triangles = tri;
     
         //This sets the normal of the plane to face the direction desired. I used the forward
         //normal on account that it's consistent with having x in the positive direction and y
         //in the positive direction in the scene view, you can set this to however you wish
         Vector3[] normals = new Vector3[4];
         normals[0] = Vector3.forward;
         normals[1] = Vector3.forward;
         normals[2] = Vector3.forward;
         normals[3] = Vector3.forward;
         mesh.normals = normals;
     
         //I uh... don't really understand this part... I think it's got something to do with
         //associating the scale... or something...
         Vector2[] uv = new Vector2[4];
         uv[0] = new Vector2(0, 0);
         uv[1] = new Vector2(1, 0);
         uv[2] = new Vector2(0, 1);
         uv[3] = new Vector2(1, 1);
         mesh.uv = uv;
     }
     
     //configures the plane texture
     public void configureSprite() {
         renderPlane.renderer.material = spriteTexture;
     }
     
     //offsets the cube to the plane being used so all I have to do is call this and each
     //on is reset around the actual game object being tethered to
     public void alignShapesToObject() {
         renderPlane.transform.position = transform.position;
     }
     
     //sets animation sequence with current, start, and end frame
     public void setAnimationFrames(int cFrame, int sFrame, int eFrame) {
         currentFrame = cFrame;
         startFrame = sFrame;
         endFrame = eFrame;
     }
     
     //pass in true or false in order to set this
     public void setFlipImage(bool flip) {
         flipImage = flip;
         
         //This is fucking attrocious, remove this redundancy if you're trying to make your code look better in the future
         if(flipImage) {
             if(renderPlane.transform.localScale.x < 0) {
                 Vector3 tempRenderPlane = renderPlane.renderer.transform.localScale;
                 tempRenderPlane.x *= -1;
                 renderPlane.renderer.transform.localScale = tempRenderPlane;
             }
         }
         else {
             if(renderPlane.transform.localScale.x > 0) {
                 Vector3 tempRenderPlane = renderPlane.renderer.transform.localScale;
                 tempRenderPlane.x *= -1;
                 renderPlane.renderer.transform.localScale = tempRenderPlane;
             }
         }
     }
     
     public void animateOnceAndStopAtEnd(int cFrame, int sFrame, int eFrame) {
         animateOnce = true;
         isAnimating = false;
         setAnimationFrames(cFrame, sFrame, eFrame);
     }
     
     public void animateOver(int cFrame, int sFrame, int eFrame) {
         animateOnce = false;
         isAnimating = true;
         setAnimationFrames(cFrame, sFrame, eFrame);
     }
 }

//---------------------------------------------------------------- END OF CLASS //----------------------------------------------------------------

 using UnityEngine;
 using System.Collections;
 
 public class TiledImage : MonoBehaviour {
     
     //Controls how many tiles to make
     public float XScale = 1;
     public float YScale = 1;
     
     public Material spriteTexture;
     
     public bool flipImage = false;
     
     public GameObject renderPlane;
     
     public float defaultXRotation = 0;
     public float defaultYRotation = 0;
     public float defaultZRotation = 0;
     
     //Used to manage the image size, concern should be applied though, on account that
     //it won't be adjusting the scale for this, so scale will still be 1, and the image may
     //be far larger than that... not sure what the repercussions are for this
     public float imageWidth = 1;
     public float imageHeight = 1;
     public float imageDepth = 1;
     
     public virtual void Start() {
         performAnimatedImageConfiguration();
     }
     
     public virtual void Update () {
         renderPlane.transform.renderer.material.mainTextureScale = new Vector2(XScale , YScale );
     }
     
     public void performAnimatedImageConfiguration() {
         renderPlane = GameObject.CreatePrimitive(PrimitiveType.Plane);
         DestroyImmediate(renderPlane.collider);
         
         renderPlane.transform.parent = this.transform;
         renderPlane.transform.position = this.transform.position;
         renderPlane.transform.rotation = Quaternion.Euler(defaultXRotation, defaultYRotation, defaultZRotation);
         renderPlane.transform.localScale = new Vector3(1, 1, 1);
         
         configureSprite();
         setFlipImage(flipImage);
         configureTwoTriangleMeshFilter();
     }
     
     /*
     This is a cludgy solution to a problem that I was concerned about with animated images.
     The problem being that when rendering on a plane way more triangles and vertices are used
     than needed. In order to circumvent this I've used a solution/example from the unity documentation
     and modified it so that there aren't any issues integrating it. The problem being that it fixes a 
     number of weird bugs on my list... and I'm not sure why. The player no longer needs to be rotated
     initially because it's handled by assumedly the normals configured in this solution. I don't
     think this is a complete fix to a lot of our concerns, but I honestly feel that it will allow
     us the ability to limp through the rest of our game without many concerns about wasting resources
     on our animated images.
     
     Again this is modified from the initial example, so use this link for reference if you need
     a referesher:
     http://docs.unity3d.com/Documentation/Manual/Example-CreatingaBillboardPlane.html
     */
     public void configureTwoTriangleMeshFilter() {
         //This gets the meshfilter and provides a reference to it so it can be changed
         //accordingly... There is a new mesh declared because we are changing it out
         //so that it is a more simple mesh rendering.
         MeshFilter mf = renderPlane.GetComponent<MeshFilter>();
         Mesh mesh = new Mesh();
         mf.mesh = mesh;
         
         //This configures the amount of vertices used on the plane, making it so that
         //there are just four points used for rending. The width and height are used
         //as a way to offset correctly from the center point of the game object being used
         Vector3[] vertices = new Vector3[4];    
         vertices[0] = new Vector3(-imageWidth/2, -imageHeight/2, 0);
         vertices[1] = new Vector3(imageWidth/2, -imageHeight/2, 0);
         vertices[2] = new Vector3(-imageWidth/2, imageHeight/2, 0);
         vertices[3] = new Vector3(imageWidth/2, imageHeight/2, 0);    
         mesh.vertices = vertices;
     
         //This configures the triangles to be used for rendering and associates them
         //with the vertices declared above
         int[] tri = new int[6];
         //triangle one
         tri[0] = 0;
         tri[1] = 2;
         tri[2] = 1;
         //triangle two
         tri[3] = 2;
         tri[4] = 3;
         tri[5] = 1;
         mesh.triangles = tri;
     
         //This sets the normal of the plane to face the direction desired. I used the forward
         //normal on account that it's consistent with having x in the positive direction and y
         //in the positive direction in the scene view, you can set this to however you wish
         Vector3[] normals = new Vector3[4];
         normals[0] = Vector3.forward;
         normals[1] = Vector3.forward;
         normals[2] = Vector3.forward;
         normals[3] = Vector3.forward;
         mesh.normals = normals;
     
         //I uh... don't really understand this part... I think it's got something to do with
         //associating the scale... or something...
         Vector2[] uv = new Vector2[4];
         uv[0] = new Vector2(0, 0);
         uv[1] = new Vector2(1, 0);
         uv[2] = new Vector2(0, 1);
         uv[3] = new Vector2(1, 1);
         mesh.uv = uv;
     }
     
     //configures the plane texture
     public void configureSprite() {
         renderPlane.renderer.material = spriteTexture;
     }
     
     //offsets the cube to the plane being used so all I have to do is call this and each
     //on is reset around the actual game object being tethered to
     public void alignShapesToObject() {
         renderPlane.transform.position = transform.position;
     }
     
     //pass in true or false in order to set this
     public void setFlipImage(bool flip) {
         flipImage = flip;
         
         //This is fucking attrocious, remove this redundancy if you're trying to make your code look better in the future
         if(flipImage) {
             if(renderPlane.transform.localScale.x < 0) {
                 Vector3 tempRenderPlane = renderPlane.renderer.transform.localScale;
                 tempRenderPlane.x *= -1;
                 renderPlane.renderer.transform.localScale = tempRenderPlane;
             }
         }
         else {
             if(renderPlane.transform.localScale.x > 0) {
                 Vector3 tempRenderPlane = renderPlane.renderer.transform.localScale;
                 tempRenderPlane.x *= -1;
                 renderPlane.renderer.transform.localScale = tempRenderPlane;
             }
         }
     }
 }
 

 
Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Hugbot · Apr 05, 2013 at 05:32 PM 0
Share

If I'm being too vague or this isn't being explained well enough please let me know. I'm really just looking for suggestions on avenues I can explore for this, or creative ways to get this functionality going. I can elaborate or answer questions as needed.

0 Replies

· Add your reply
  • Sort: 

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

10 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

A node in a childnode? 1 Answer

Playing 2 Animations at once. *Please Help* 2 Answers

multiple animation model from c4d to unity 0 Answers

Animation Import breaks when altering animations through unity 0 Answers

Animation... Unity 3D...Blender...3rd Person 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges