Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 tylerlybb · Oct 18, 2016 at 12:23 PM · animationmateriallerpeventswap

Material transition through animation

I have this script that ping pongs back and forth between two materials (doesn't transition textures but that's fine with me for what I'm doing). How would I change it so that instead of ping ponging I can cause the transition to happen through using animation events? So, I could have an animation that on frame 60 I trigger a transition to material 2 and on frame 120 transition back to material 3.

 using UnityEngine;
 using System.Collections;
 
 public class swap_mats : MonoBehaviour {
     // Blends between two materials
     public Material material1;
     public Material material2;
     public float duration = 2.0F;
     public Renderer rend;
     void Start() {
         // At start, use the first material
         rend = GetComponent<Renderer>();
         rend.material = material1;
     }
     void Update() {
         // Ping-pong between the materials over the duration
         float lerp = Mathf.PingPong(Time.time, duration) / duration;
         rend.material.Lerp(material1, material2, lerp);
     }
 }
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 tylerlybb · Oct 18, 2016 at 01:52 PM 0
Share

Okay, thank you. However, what would that public method look like exactly? (to transition from material 1 to material 2) Sorry, I'm quite new to scripting.

2 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Zodiarc · Oct 18, 2016 at 12:33 PM

As far as I understand the animation events, you need two public methods. One to transition from material 1 to 2 and one form 2 to 1. Then you select your animation in the editor and in the timeline you can create an animation event (through the right click context menu I guess) where you need to pull in the game object that has this script attached and select the corresponding function.

Comment
Add comment · Show 6 · Share
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 tylerlybb · Oct 19, 2016 at 02:41 AM 0
Share

Okay, thank you. However, what would that public method look like exactly? (to transition from material 1 to material 2) Sorry, I'm quite new to scripting.

avatar image Zodiarc tylerlybb · Oct 19, 2016 at 07:49 AM 0
Share

Exactly the same as you already do it in Update, but without the pingpong. $$anonymous$$ethod 1 would be renderer.material.Lerp(material1, material2, speed Time.deltaTime); and method 2 renderer.material.Lerp(material2, material1, speed Time.deltaTime);

avatar image tylerlybb · Oct 19, 2016 at 09:39 AM 0
Share

Zodiarc, thank you so much!

However... "speed Time.deltaTime" as you wrote it, did not work for me. Is it because I need to declare "speed" somewhere? And is there supposed to be anything between "speed" and "Time.deltaTime"?

But I got it to work by simply removing "speed". It works now, however, the material switches immediately. I assume this is because the third spot (after material1, material2) is the spot that deter$$anonymous$$es the speed of the transition and by me putting just "Time.deltaTime" in there, the speed is the time it took to render the last frame, so essentially, it switches the material in about the time to render the following frame, which is why it appears to switch immediately. Am I understanding this right? If I wanted the transition to take longer than one frame, how would I do that?

avatar image Zodiarc tylerlybb · Oct 19, 2016 at 09:42 AM 0
Share

Yes it was a formatting error in the comment. There should be a multiplication sign between speed and Time.deltaTime. You can leave the speed parameter out, but then the transition will always take 1 second. You can define the parameter as a class variable so you can adjust the transition speed to your needs. The third value of the lerp function is how long the transition will take. Setting it to Time.deltaTime will mean, that the transition should be done after 1 second. If it swaps immediatelly then the problem is somwhere else. $$anonymous$$aybe you need a wrapper method which starts the transition as a coroutine https://docs.unity3d.com/$$anonymous$$anual/Coroutines.html

Does the animation stutter at the point where the transition is happening?

avatar image tylerlybb Zodiarc · Oct 19, 2016 at 10:30 AM 0
Share

(thanks for continuing to help me with this) The animation does not stutter. And when I put a multiplication sign between speed and Time.deltaTime, and then define speed up above I don't get any errors but the transition still happens immediately. First of all, am I defining speed right? I changed the following line in my script ...

      public float duration = 2.0F;

... to ...

      public float speed = 2.0F;
Show more comments
avatar image
0

Answer by tylerlybb · Oct 19, 2016 at 12:23 PM

I read the documentation on coroutines then came up with this (down below) for the code to use. It doesn't work: I now don't even get the immediate transitions I was seeing before. Now it just does a one frame flash at the end of the animation (neither of my animation events are at the end of the animation).

Also, I'm pretty sure what I have in update isn't right. I don't know how to do this because I think it's more complicated than the example used in the documentation. I only say this because, for mine, I only want to restart the coroutine "SwitchToMat1", for example, if that coroutine is not finished yet. Or do I misunderstand how coroutines work?

 using UnityEngine;
 using System.Collections;
 
 public class swap_mats : MonoBehaviour {
     public Material material1;
     public Material material2;
     public Renderer rend;
     void Start() {
         rend = GetComponent<Renderer>();
         rend.material = material1;
     }
     void Update() {
             StartCoroutine("SwitchToMat1");
             StartCoroutine("SwitchToMat2");
     }
     public IEnumerator SwitchToMat1() {
         GetComponent<Renderer>().material.Lerp(material2, material1, Time.deltaTime);
         yield return null;
     }
     public IEnumerator SwitchToMat2() {
         GetComponent<Renderer>().material.Lerp(material1, material2, Time.deltaTime);
         yield return null;
     }
 }

Side note: I decided to remove the "speed" multiplier since without it you said I should still be seeing a one second transition, which should work just fine for what I'm doing.

Comment
Add comment · Show 5 · Share
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 Zodiarc · Oct 19, 2016 at 12:29 PM 0
Share
 public IEnumerator switchTo$$anonymous$$aterial() {
     // your material lerp here
 }
 
 public void switchTo$$anonymous$$aterialWrapper() {
     StartCoroutine("switchTo$$anonymous$$aterial");
 }

Then assign the wrapper function to the animation event.

If this doesn't work try this: https://forum.unity3d.com/threads/cant-get-material-lerp-to-work.8936/

By the way the documentation states "$$anonymous$$ost often you want the materials that are interpolated between to be the same (use the same shaders and textures) except for colors and floats. Then you use Lerp to blend between them." https://docs.unity3d.com/ScriptReference/$$anonymous$$aterial.Lerp.html

If you actually want to blend between textures, I would recommend a custom shader.

avatar image tylerlybb Zodiarc · Oct 20, 2016 at 10:09 AM 0
Share

First of all, thanks again for your help. I really appreciate it.

I still get an error. I am also getting errors when I use the script from the forum that you suggested but I'll tell you more about that in a separate reply.

Here's the error I'm getting:

Assets/$$anonymous$$atTransition.cs(12,28): error CS0161: `$$anonymous$$atTransition.switchTo$$anonymous$$aterial()': not all code paths return a value

Here is my complete updated script:

 using UnityEngine;
 using System.Collections;
 
 public class $$anonymous$$atTransition : $$anonymous$$onoBehaviour {
     public $$anonymous$$aterial material1;
     public $$anonymous$$aterial material2;
     public Renderer rend;
     void Start() {
         rend = GetComponent<Renderer>();
         rend.material = material1;
     }
     public IEnumerator switchTo$$anonymous$$aterial() {
         GetComponent<Renderer>().material.Lerp(material1, material2, Time.deltaTime);
     }
     public void switchTo$$anonymous$$aterialWrapper() {
         StartCoroutine("switchTo$$anonymous$$aterial");
     }
 }

avatar image tylerlybb tylerlybb · Oct 20, 2016 at 10:52 AM 0
Share

FYI - I resolved the errors I was getting from the forum thread you suggested, but just like we learned, the gradual transition only works when it's a ping pong being called through update on every frame. As soon as I try and trigger it through an animation event, the transition happens immediately over one frame. So that brings me back to your suggestion to handle this through a coroutine. So if you have any more ideas on getting that to work, again, I would really appreciate it.

Show more comments

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

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Error in AnimationState.cpp Line: 307 1 Answer

Change texure on NGUI BUTTUN press 0 Answers

Can I make animations snap to a frame? 1 Answer

Animation Event issue what am I doing wrong here 2 Answers

how do you add an event to an imported animation 1 Answer


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