Start a script from a keyframed animation - c#

I'm using the old animation system in Unity to keyframe in a camera path (no choice in this). What I'd like to know is if it's possible to have this animation start a script that starts an object to grow in scale depending on the distance of the camera.
I know there is a few ways I could go about this, but I'm specifically asking if it can be done via the animation component. If it is possible, please let me know.

Sure, something like that is easily possible with an Animation Event.
In your animation window, click on the appropriate section in your timeline to add an animation event.
To your object, add a script component that contains the appropriate function you want to call from that animation event. Let's say we create a simple "Test" script that has a public void DoSomething().
using UnityEngine;
using System.Collections;
public class Test : MonoBehaviour
{
void Start() {}
void Update() {}
public void DoSomething()
{
Debug.Log ("Do Something");
}
}
Then click on the animation event and a windows like the following should appear:
From the dropdown you should be able to select your method. Now, if you play your animation, then at the moment of your animation event, the appropriate method will be called.
That should do the trick.

Related

cant play an animation when pressing a button

screen shot of the animator panel
so as you can see I am trying to play an animation called Attack when triggering the parameter Attack but whenever I press the triggering button that I chose the animation just doesn't work and the trigger does not get activated
here is my code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class attack : MonoBehaviour
{
public Animator animator;
void Update()
{
if (Input.GetKeyDown(KeyCode.C))
{
Attack();
}
}
void Attack()
{
animator.SetTrigger("Attack");
}
}
by the way, I am trying to follow this guy's video
https://youtu.be/sPiVz1k-fEs
Suggestions:
Make sure you have assigned this script to a game object.
Assign the right animator that you want to animate in inspector of this script.
Check if you have added 'Attack' parameter in that animator and the spelling is same like the one mentioned as parameter in your code.
and lastly check if you have set the trigger for the transition of animation in the animator( in animator its the arrow that is pointing towards your animation ).
Let me know if you don't understand any of this I'll breifly explain.
Hopefully that will help... Happy coding :)

Animation of UI objects to play on death

Basically, In my scene, underneath a GameObject called 'GameOverUI' I have some buttons and a Panel that covers the screen. I have made a simple animation where the panel's opacity (The alpha channel) increases. Do any of you know how to make it so that when the player dies, it enables GameOverUI and plays the animation for the panel once?
Edit: Forgot to mention, I know how to make it so that 'GameOverUI' is enabled, I just don't know how to make the animation play
If you are looking for a solution with animations, then here you go:
Create a script for your GameOverUI gameObject. Really simple:
public class UIHandler : MonoBehaviour
{
private void OnEnable()
{
//play "dead screen" animation
}
}
Method OnEnable() is a MonoBehavior function, and will be called when you enable a GameObject by calling myGameObject.SetActive(true);.
However, I would recommend thinking about another solution. I usually leave GameOverUI always active and use it to manage its children via script. So I think it would be more elegant to write something like this:
public class UIHandler : MonoBehaviour
{
public void PlayerDied()
{
//play "dead screen" animation
}
}
The difference is, that instead of enabling and disabling the GameObject, you call a method. This way, you will be able to pass data (as function parameters) if you need to do so. For example, you can write to the screen, what caused the death. And further on, the GameObject will be able to manage its UI components for other purposes.
I hope it makes sense and I could be of your help!

How to disable GameObject after animation is finished

So I have an animation that fades into the menu screen but after the animation ends none of my buttons work. I have figured out that it is because the GameObject that holds the black image that fades to clear is always in the front, blocking me from using any of the buttons. I tried to write a script, that's attached to the game object, that disables the GameObject after it completes the animation, but it isn't working.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LevelChanger : MonoBehaviour
{
public Animation anim;
public void SetTrigger()
{
this.StartCoroutine(this.PerformAnimRoutine());
}
private IEnumerator PerformAnimRoutine()
{
var state = anim.PlayQueued("Fade_In", QueueMode.PlayNow, PlayMode.StopSameLayer);
yield return new WaitForSeconds(state.length);
this.gameObject.SetActive(false);
}
}
Is there anything wrong with the code or is there an easier way to accomplish this? I am extremely new to unity so I am very stuck.
If all you are doing is fading a sprite to clear and you seem to know about coroutines, I might start by suggesting you do the fade within a coroutine instead.
Have that decrease the alpha by some fraction each frame and when it's 0 disable the object.
That's just if that sounds more fluid, nothing wrong with the animation way.
Doing it with animations though :
I'm not confident that you can disable the object the animation is on in that animation. If it is available on the dope sheet try that. Otherwise we can use state behaviours or animation events.
Animation Events
These can be used to trigger a function at a certain point of an animation. You can create them similar to keyframes. Here is a link to Unity's guide on this topic.
All you'd need to do is create an event and place it at the end of the animation. Then you need to in a script of that object make a public function that simply disables the object. Call that with the event.
State Behaviours
State Machine Behaviours allow you to define a script to run on a given animation state. It has many functions to hook onto such as OnStateEnter and OnStateExit.
You'd want to click on the state that fades in the animator. In the inspector you should be able to click "Add Behaviour". This will create a script that you can open and edit. Here is the reference for that class.
From there is should be very simple to disable the object through OnStateExit.

I would like two objects to play their separate animations when the user clicks on them in Unity using C#

I am new to coding, so please go easy and try to make this as simple as possible. I am surprised that what I am trying to do appears to be so difficult.
I have two objects, A and B. They each have a different animation, 1 and 2. I want the user to click on A and watch animation 1, or to click on B and watch animation 2. I also want each object to play their relevant animations and then change to different scenes.
Can this be done just in the Animator window without any code using bools or triggers and transitions? (I have tried multiple ways and can't work it out.)
If it needs a code attached to objects A and B, I have a trigger animation script (attached below) but it only plays one of the animations and is just if the mouse button is clicked, not by clicking on object A or B.
I can successfully do what I need with a change scene script: objects A and B have the change scene script attached and two different scenes to change to. How is the animation I want to play different and seemingly so complicated to implement? I haven't needed to declare any gameobjects in that script. Perhaps I need to GetComponent and something to do with PlayAnimation, but I have searched and searched and am surprised no one else has had this issue, or perhaps I'm not asking in the correct way. There are many tutorials that tell you how to play one animation, but not multiple.
using UnityEngine;
using System.Collections;
/// <summary>
/// The TriggerAnimation class activates a transition whenever the Cardboard button is pressed (or the screen touched).
/// </summary>
public class TriggerAnimation : MonoBehaviour
{
[Tooltip("The Animator component on this gameobject")]
public Animator animator;
[Tooltip("The name of the Animator trigger parameter")]
public string triggerName;
void Update()
{
// If the player pressed the cardboard button (or touched the screen), set the trigger parameter to active (until it has been used in a transition)
if (Input.GetMouseButtonDown(0))
{
animator.SetTrigger(triggerName);
}
}
}
using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;
public class ChangeScene : MonoBehaviour
{
public void GoToScene(string sceneName)
{
Debug.Log("I'm going to change scenes!");
SceneManager.LoadScene(sceneName);
}
}
Thank you so much in advance. I'm really stuck. I am trying to learn by following tutorials and using Sololearn, but I'm finding it very difficult to translate what I'm learning into things I want to do.
Here's the updated code:
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
/// <summary>
/// The TriggerAnimation class activates a transition whenever the Cardboard button is pressed (or the screen touched).
/// </summary>
public class TriggerAnimation : MonoBehaviour
{
public Animator animatorVR;
public Animator animatorAR;
public void OnPointerClick(PointerEventData pointerEventData)
{
Debug.Log("Clicked: " + eventData.pointerCurrentRaycast.gameObject.name);
}
void Update()
{
// If the player pressed the cardboard button (or touched the screen), set the trigger parameter to active (until it has been used in a transition)
//OnPointerClick;
{
animatorVR.SetTrigger(onPressVR);
animatorAR.SetTrigger(onPressAR);
}
}
}
I know this doesn't work but am not sure where to go from here.
Detecting a click on an object
Input.GetMouseButtonDown only checks the current state of the button, without any respect as to where the mouse is pointing. You're executing it within the Update event method, which runs every single frame.
The easiest way to detect if you're clicking an object is to put a Collider component (of any shape) on the object and use the OnMouseDown event function.
As noted in the comments by Galandil, OnMouse methods shouldn't be used for touch controls.
Running animations for two different objects
The Animator component can control a tree of objects (the object with the component, but also its children). You can do what you want without any additional code if you put objects A and B under a common parent object with Animator. Otherwise, yeah, you'll have to reference the other object somehow, e.g put something like this on both objects:
[Tooltip("The Animator component on this gameobject")]
public Animator animator;
[Tooltip("The Animator component on the other gameobject")]
public Animator otherAnimator;
...
animator.SetTrigger(triggerName);
otherAnimator.SetTrigger(triggerName);

Non-legacy animation cannot be stopped / controlled

I made an animation using Animation panel, which swaps images from time to time. Read from the Internet, this is not a legacy animation.
Here is the Animation panel screenshot:
Then, I add the Animation and Animator components to the Game Object and assign the animation, which is called Animation01, to it. Here is the screenshot from Inspector of the Game Object:
I try to use the following C# script to stop the animation :
using UnityEngine;
using System.Collections;
public class Scene1 : MonoBehaviour {
public GameObject ball;
// Use this for initialization
void Start () {
ball.animation.Stop();
}
// Update is called once per frame
void Update () {
}
}
but the animation didn't stop. It prompts a notice in Console:
Default clip could not be found in attached animations list.
What did I miss?
UPDATE: By disabling/ removing Animator component, the animation is stopped and cannot be controlled by codes. I need to control the animation by codes.
Unity had implemented two animation systems throughout it's history. Animation component belongs to the legacy animation system, while Animator component belongs to the new animation system. So, adding both components makes no sense: you either use the old system or the new.
The main difference between the legacy and new animation system is that the new animation system is much more advanced in way it's controlled. However, it also means that it's more complicated. It adds another level of abstraction: instead of launching animation yourself, you control variables that influence the behaviour of a special state machine, animation controller.
So, if you want to use animations for something really, really simple, where you want just to launch animations manually, it may be better to use legacy animation system instead. But the components are not the only thing that is different: the animation files themselves are marked to determine if they are "legacy" or not. By default, when you create an animation in the new unity version, it belongs to the new animation system. If you want to use it with a legacy animation, you have to mark it as a legacy animation. Unfortunately, you'll have to do a little hack to achieve that.

Categories