Reverse animation in unity 3D - c#

I have an FBX object with animation. The object is a box with animation for opening. What I'm trying to do is when the user clicks a button the box will open (play open animation) and when the button is clicked again the box will close (play open animation backwards).
While the opening animation is playing and I click the button again the opening animation stops and the box starts to close, that works fine.
The problem is that when the animation is finished (open) and then I click the button to close, the animation is not playing and it just jumps to a closed box without animation.
Here is my code:
public class ClickBtn : MonoBehaviour {
public GameObject box = null;
bool reverse = false;
private void OnMouseDown()
{
Debug.Log(reverse);
if (!reverse)
{
box.animation["Take 001"].speed = 1;
}
else
{
box.animation["Take 001"].speed = -1;
}
reverse = !reverse;
box.animation.Play("Take 001");
}
}

your animation.WrapMode is set wrong (probably WrapMode.Once, which is default). In your case you could use:
WrapMode.PingPong: Ping Pong's back and forth between beginning and end.
animation.wrapMode = WrapMode.PingPong;
Mind you, you don't need
box.animation["Take 001"].speed = -1;
anymore, this is done automatically.

When animation is finished its time is reseted to beginning.
Simple workaround set time to end before playing backwards.
public GameObject box;
bool direction = false;
private void OnMouseDown()
{
Debug.Log(direction);
if (!direction)
{
box.animation["Take 001"].speed = 1;
}
else
{
box.animation["Take 001"].speed = -1;
//if animation already finisihed, set time to end before playing it backwards
if(!box.animation.isPlaying){
box.animation["Take 001"].time =box.animation["Take 001"].clip.length;
}
}
direction = !direction;
box.animation.Play("Take 001");
}

Related

How to create a menu on click of GameObject? (Unity)

I want to be able to hover over a GameObject (agent) and on either right or left click, create a floating menu similar to the windows right click menu. I have tried using a combination of OnGUI() and OnMouseOver() but I either don't get the behaviour I need or get nothing at all. Here is what I have so far:
private void OnMouseOver()
{
mouseOver = true;
mousePos = Input.mousePosition;
}
private void OnMouseExit()
{
mouseOver = false;
}
private void OnGUI()
{
if (mouseOver && Input.GetMouseButtonDown(0))
{
GUI.Box(new Rect(mousePos.x, mousePos.y, 200f, 100f), "this is a test");
}
}
mouseOver and mousePos are initialy set to false.
Input.GetMouseButtonDown() only executes for a single frame so the GUI.Box is being drawn but only for a single frame.
To fix this Input.GetMouseButton() can be used instead as it executes for as long as the button is pressed.
What I do is create my desired menu in a Canvas, add an animator controller and an animation and put it outside of the camera view (the animation moves the menu inside the camera view), finally add a bool condition trigger to hide or show the menu
Then i just attach a click function into a button to fire the animation when somebody clicks it
public class ShowMenu : MonoBehaviour
{
public Animator ObjectBtnAnimations;
public void HideObjControls()
{
if (ObjectBtnAnimations.GetBool("hide"))
{
ObjectBtnAnimations.SetBool("hide", false);
}
else
{
ObjectBtnAnimations.SetBool("hide", true);
}
}
}

Turn off toggle box and graphic when game starts

So this should be a simple answer but I cannot seem to find it anywhere. In Unity, I have a toggle box I want to turn off when the game starts, but unlike most game objects or text, SetActive does not work with toggle boxes. What is the command to turn the graphic off?
public void StartGame () {
mainText.SetActive (false);
startButton.SetActive (false);
StartCoroutine (SpawnBalls ());
//Turn off toggle box graphic
playing = true;
}
public void AddBall () {
if (ballBox.isOn) {
ballNumber = 3;
//Debug.Log ("yes");
} else {
ballNumber = 2;
}
If I understand you correctly you want to be able to remove the display of the toggle on the start of the game? If so set a reference to the toggle you want to click on and off heres a small example:
Toggle T = GameObject.Find("myToggle").GetComponent<Toggle>();
T.gameObject.SetActive(false);
Make a reference to it and you should be able to click it of and on as you need it tested it out on a game I'm working and it worked for me let me.

Unity Animations

I am trying to change character animations using a script, based on key inputs, but Unity seems to only play the default "standing idle" animation and occasionally switching to the "crouched idle", is there a different way to handle animations or am I just doing the script wrong? Here is my script as it currently stands
using UnityEngine;
using System.Collections;
public class CharacterControl : MonoBehaviour {
private Animator animator;
public bool crouched;
private string sc;
// Use this for initialization
void Start () {
animator = GetComponent<Animator> ();
}
// Update is called once per frame
void Update () {
if (crouched == true) {
sc = "crouch";
} else {
sc = "standing";
}
animator.Play (sc + "_idle");
if (Input.GetButton ("Fire3")) {
if (crouched == false) {
crouched = true;
} else {
crouched = false;
}
}
}
}
Try replacing
if (Input.GetButton ("Fire3")) {
if (crouched == false) {
crouched = true;
} else {
crouched = false;
}
}
with
if (Input.GetButton ("Fire3")) {
crouched = true;
} else {
crouched = false;
}
Now, when you hold down the "Fire3" button, your character should crouch, and when you release it he/she should stand again
Also a suggestion: Put the other code in the function (if (crouched == true) ... animator.Play (sc + "idle"); after this code (the Input.GetButton check). That way, your character should instantly start crouching the same frame that the button is pressed; otherwise, he/she will the frame after
Explanation
Input.GetButton will return true while you're pressing down (in the middle of clicking or touching) on the button each frame. Each time Update is called (around 1/60th of a second) your code will check if you're pressing down, and toggle crouched. When you click/tap the button, you'll likely be pressing down for a few frames, so crouched will switch from true to false, back and forth, a few times. In some cases (when you press down for an odd number of frames) crouched will be switched, but in other cases (when you press down for an even number of frames) crouched will stay as it was before you clicked on the button, preventing your character from crouching, or standing if he was crouching before.
Source: From the official API: Input.GetButton
I would strongly suggest using animation states and transit from one to another when you get an input. Checkout my answer at: Unity 2D animation running partially
Yes you can do the toggle action like this
void Update()
{
if(Input.MouseButtonDown(2))
{
crouched = true;
}
if(Input.MouseButtonUp(2))
{
crouched = false;
}
}
You can try this code:
crouched = Input.GetButtonDown("Fire3") ? true : false;

Hold down button unity3d

I am trying to build a button that changes the game speed when it is being pressed and changes it back when it stops being pressed.
To make this I wrote this functions:
public void OnPointerDown()
{
mouseDown = true;
Background1.sprite = on;
Time.timeScale = 2;
}
public void OnPointerUp()
{
Time.timeScale = 1;
mouseDown = false;
Background1.sprite = off;
}
They are already connected to the button. When the button is pressed the game speed changes, but never changes back (it should happen when I stop holding the button).
Know how to fix this?

Fading out animated Unity loading screen

I am trying to have a simple animated loading screen between my menu scene and the game scene. I am trying to do this by loading the game scene in my loading scene asynchronously. I also want the loading screen to fade in and fade out.
I got the fade-in to work. However, I have two problems which I have been working on for hours, but without any succes. These problems are:
I cannot get the fade-out to work. I tried setting the 'allowSceneActivation' to false for my asynchronous loading, however this causes the loading to not occur at all. Removing this line makes the game load, but it then lacks the fade out.
The animation works very (and I mean VERY) choppy. I understand that the game is loading stuff, so I expect it to be bad, but it's litterally doing a frame every 2 seconds. I tried using a low thread priority (see code below), but no luck. I found people with similar problems, but the frames turned out reasonable when using a lower thread priority.
This is my code for the loading screen:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class LoadIntro : MonoBehaviour {
private bool loaded;
private bool fadingOut;
private bool loading;
AsyncOperation async;
void Start(){
loaded = false;
fadingOut = false;
loading = false;
Application.backgroundLoadingPriority = ThreadPriority.Low;
}
// Use this for initialization
void Update() {
//wait for loading screen to fade in, then execute once
if (!GameObject.Find ("SceneFader").GetComponent<Image> ().enabled && !loaded && !loading) {
loading = true;
async = Application.LoadLevelAsync(mainMenuButtons.leveltoload);
async.allowSceneActivation = false;
StartCoroutine (LoadLevel (async));
}
//if next scene is loaded, start fading out loading screen
if (loaded) {
GameObject.Find ("SceneFader").GetComponent<SceneFadeInOut> ().FadeToBlack();
fadingOut = true;
}
//when faded out, switch to new scene
if (GameObject.Find ("SceneFader").GetComponent<Image> ().color.a >= 0.95f && loaded) {
async.allowSceneActivation = true;
}
}
IEnumerator LoadLevel(AsyncOperation async){
yield return async;
Debug.Log("Loading complete");
loaded = true;
}
}
I have a seperate piece of code for the actual fading, which the code above calls:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class SceneFadeInOut : MonoBehaviour
{
public float fadeSpeed = 1.5f; // Speed that the screen fades to and from black.
private bool sceneStarting = true; // Whether or not the scene is still fading in.
public bool sceneEnding = false;
public string scene;
private Image fadeTexture;
void Awake ()
{
fadeTexture = GetComponent<Image>();
}
void Update ()
{
// If the scene is starting...
if(sceneStarting)
// ... call the StartScene function.
StartScene();
if (sceneEnding)
EndScene();
}
void FadeToClear ()
{
// Lerp the colour of the texture between itself and transparent.
fadeTexture.color = Color.Lerp(fadeTexture.color, Color.clear, fadeSpeed * Time.deltaTime);
}
public void FadeToBlack ()
{
// Lerp the colour of the texture between itself and black.
fadeTexture.color = Color.Lerp(fadeTexture.color, Color.black, fadeSpeed * Time.deltaTime);
}
void StartScene ()
{
// Fade the texture to clear.
FadeToClear();
// If the texture is almost clear...
if(fadeTexture.color.a <= 0.05f)
{
// ... set the colour to clear and disable the GUITexture.
fadeTexture.color = Color.clear;
fadeTexture.enabled = false;
// The scene is no longer starting.
sceneStarting = false;
}
}
public void EndScene ()
{
// Make sure the texture is enabled.
fadeTexture.enabled = true;
// Start fading towards black.
FadeToBlack();
// If the screen is almost black...
if (fadeTexture.color.a >= 0.95f) {
// ... reload the level.
if (scene == "") Application.Quit();
else Application.LoadLevel (scene);
}
}
}
Does anyone have an idea how to solve the issues described above? I've litterally tried every topic I could find, but none of them seem to work. Building my game did not resolve the issues either.
Many thanks in advance!
You are fading out when scene loading gets done. What are you expecting when loading is done? :)
//if next scene is loaded, start fading out loading screen
if (async.isDone) {
GameObject.Find ("SceneFader").GetComponent<SceneFadeInOut> ().FadeToBlack();
fadingOut = true;
}
Obviously it will change the scene and you code doesn't getting enough time to perform fade-out operation. :)
For instance if consider your point. You wrote,
//if next scene is loaded, start fading out loading screen
if (loaded) {
GameObject.Find ("SceneFader").GetComponent<SceneFadeInOut> ().FadeToBlack();
fadingOut = true;
}
//when faded out, switch to new scene
if (GameObject.Find ("SceneFader").GetComponent<Image> ().color.a >= 0.95f && loaded) {
async.allowSceneActivation = true;
}
in Update. Here your loaded check doing 2 things.
1- Start fading out.
2- Switching scene.
Again, why it should wait for fading it out completely while its getting loaded and you are checking alpha >= 0.95 which should execute at first frame when you get loaded to true, because I believe that in first frame alpha would be greater than 0.95.

Categories

Resources