I have an animation in unity, and basically it shows Donald Trump running:
I also have this one frame animation of Trump jumping:
Basically, when he jumps, the jump animation plays, and when he lands, the walk animation plays again.
This all works, and this code runs it:
function Update() {
trump.velocity = Vector2(speed, trump.velocity.y);
if (jump > 0) {
jumpBool = true;
}
else {
jumpBool = false;
}
animator.SetBool("Jump", jumpBool);
That's in the physics script. Then from the animator:
This all works, and the animations change when they are supposed to. The issue is, it lags before it finishes. I think that when Trump jumps, the walk animation finishes before it switches to the jump animation. My question is, how do I automatically switch animations immediately, so it won't look so laggy?
You can immediately call the Jump animation to be played at the point you make the JumpBool = true. Doing so you don't need to wait for the walk animation finish, it will simply stop the Walk and and move to Jump.
function Update() {
trump.velocity = Vector2(speed, trump.velocity.y);
if (jump > 0) {
animator.Play("Trump Jump");
//jumpBool = true;
}
else {
//jumpBool = false;
}
//animator.SetBool("Jump", jumpBool);
You don't even need to Set the bool, after the Jump animation has finished it will move back to the Walk animation.
Related
I am very new to coding and I'm still trying different languages out, I started off with GameMaker Studio and changed to Godot due to its compatibility with Mac I might as well learn something newer since GameMaker has been out for quite some time.
I want to create a RPG game and apply animation to each direction the character moves but the animation only plays after the key is pressed AND lifted. This means that while my key is pressed, the animation stops, and the animation only plays while my character is standing still, which is the complete opposite of what I want. The script looked really straight forward, but doesn't seem to be working.
I would tag this as the GDScript language instead of Python, but I guess I'm not reputable enough to make a new tag, so I tagged it under python because it is the most similar.
#variables
extends KinematicBody2D
const spd = 100
var direction = Vector2()
var anim_player = null
func _ready():
set_fixed_process(true)
anim_player = get_node("move/ani_move")
#movement and sprite change
func _fixed_process(delta):
if (Input.is_action_pressed("ui_left")) :
direction.x = -spd
anim_player.play("ani_player_left")
elif (Input.is_action_pressed("ui_right")):
direction.x = spd
anim_player.play("ani_player_right")
else:
direction.x = 0
if (Input.is_action_pressed("ui_up")) :
direction.y = -spd
anim_player.play("ani_player_up")
elif (Input.is_action_pressed("ui_down")):
direction.y = (spd)
anim_player.play("ani_player_down")
else:
direction.y = 0
if (Input.is_action_pressed("ui_right")) and (Input.is_action_pressed("ui_left")):
direction.x = 0
if (Input.is_action_pressed("ui_up")) and (Input.is_action_pressed("ui_down")) :
direction.y = 0
# move
var motion = direction * delta
move(motion)
As you check the input in _fixed_process, you call anim_player.play() several times a frame, which always seems to restart the animation, and thus, keeps the very first frame of the animation visible all the time.
As soon as you release the key, anim_player.play() stops resetting the animation back to start, and it can actually proceed to play the following frames.
A simple straight-forward solution would be to remember the last animation you played, and only call play() as soon as it changes.
You need to know if the animation has changed
First you need to put these variables in your code:
var currentAnim = ""
var newAnim = ""
And then you add this in your _fixed process:
if newAnim != anim:
anim = newAnim
anim_player.play(newAnim)
To change the animation you use:
newAnim = "new animation here"
So I am animating an avatar, and this avatar has its own animator with states and such.
When interacting with props, the props itself has an animator with states in it. In both case, I transition to some animations through parameters in the animator (bool type).
For example, for a door, the character will have "isOpeningDoor", while the door will have "isOpen".
Now the question: when I change the value on an animator on GO1, and then change the bool on GO2; do the first animation finish and then the second start? Because in my case, it does not happen; they start almost at the same time.
void OnTriggerEnter (collider door)
{
if (door.gameObject.tag=="door")
{
GOAnimator1.SetBool("isOpeningDoor", true);
GOAnimator2.SetBool("isOpen", true);
}
}
I believe that I am doing it wrong, since I change the parameter on the animator, but I do not check for the animation to end; is this even possible or am I doing something not kosher?
I really think it might be doable!
As you have it in your code now, the animations on GO1 and GO2 start at almost the same time because that's how it's written. The OnTriggerEnter() function will complete the execution in the frame it is called, and return the control to Unity.
What I think that might help you are coroutines and sendMessage between gameobjects:
http://docs.unity3d.com/Manual/Coroutines.html
http://docs.unity3d.com/ScriptReference/GameObject.SendMessage.html
The idea is to:
Create a coroutine in GO2 that waits an amount of time until it sets the GOAnimator2 variable to activate the door animation.
Create a function in GO2 that calls the aforementioned coroutine
From the OnTriggerEnter() send a message to GO2 to execute the newly created function
It reads complicated, but it's fairly simple. The execution would be like this:
1.Code for the coroutine:
function GO2coroutine(){
float timeToWait = 0.5f; //Tweak this
for ( float t = 0f; t < timeToWait; t+=time.deltaTime)
yield;
GetComponent<Animator>().SetBool("isOpen",true);
}
Code for the function calling it:
function callCoroutine() {
StartCoroutine("Fade");
}
And the code modification for your OnTriggerEnter():
void OnTriggerEnter (collider door)
{
if (door.gameObject.tag=="door")
{
GOAnimator1.SetBool("isOpeningDoor", true);
GO2.SendMessage("callCoroutine");
}
}
I didn't have a chance to test the code, so please don't copy paste it, there might be slight changes to do.
There is another way, but I don't like it much. That is making the animation longer with an idle status to wait for the first game object animation to end... but it will be a hassle in case you shorten the animation because you have to, or have any other models or events.
Anyway, I think the way to go is with the coroutine! Good Luck!
I'm a new in Unity and making my first 2D game. I seen several topics on this forum in this issue, but I didn't found the solution.
So I have a lovely shooting animation and the bullet generation. My problem, I have to generate the bullet somewhere at the middle of the animation, but the character shoots the bullet and the animation at the same time, which killing the UX :)
I attached an image, about the issue, this is the moment, when the bullet should be initialized, but as you can see it's already on it's way.
Please find my code:
The GameManager update method calls the attackEnemy function:
public void Awake(){
animator = GetComponent ();
animator.SetTrigger ("enemyIdle");
}
//if the enemy pass this point, they stop shooting, and just go off the scren
private float shootingStopLimit = -6f;
public override void attackPlayer(){
//animator.SetTrigger ("enemyIdle");
if (!isAttacking && gameObject.transform.position.y > shootingStopLimit) {
isAttacking = true;
animator.SetTrigger("enemyShoot");
StartCoroutine(doWait());
gameObject.GetComponentInChildren ().fireBullet ();
StartCoroutine (Reload ());
}
}
private IEnumerator doWait(){
yield return new WaitForSeconds(5);
}
private IEnumerator Reload(){
animator.SetTrigger ("enemyIdle");
int reloadTime = Random.Range (4,7);
yield return new WaitForSeconds(reloadTime);
isAttacking = false;
}......
My questions:
- How can I sync the animation and the bullet generation ?
Why not the doWait() works ? :)
Is it okay to call the attackPlayer method from the GameManager update ?
The enemies are flynig from the right side of the screen to the left, when they reach the most right side of the screen, they became visible to the user. I don't know why, but they to a shooting animation (no bullet generation happen )first, only after it they do the idle. Any idea why ?
Thanks,
K
I would suggest checking out animation events. Using animation events, you can call a method to instantiate your bullet.
To use Mecanim Animation Events you need to write the name of the function you want to call at the selected frame in the "Function" area of the "Edit Animation Event" window.
The other boxes are for any variables that you want to pass to that function to trigger whatever you have in mind.
Triggering/blending between different animations can be done in many different ways. The event area is more for other things that you want to trigger that are not related to animation (e.g. audio, particle fx, etc).
I am new to Unity/coding and trying to create a simple 2-step animation in which I can adjust the delay times for each step. I have a lift in my game that uses two animations: "Up" and "Down".
I'm using an enumerator to play the animations, and this is what I have so far:
IEnumerator Go()
{
while(true)
{
GetComponent<Animation>().Play ("Up");
yield return new WaitForSeconds(delayTime);
break;
GetComponent<Animation>().Play ("Down");
yield return new WaitForSeconds(delayTime);
break;
}
}
I understand I could just animate the whole thing as one motion, but I want to be able to adjust the delay times on the fly. My goal is to animate these two in succession. Up, then down. At the moment my lift goes up and stays there. What am I doing wrong?
Thanks for the help!
Remove the break-clauses:
IEnumerator Go()
{
while(true)
{
GetComponent<Animation>().Play ("Up");
yield return new WaitForSeconds(delayTime);
GetComponent<Animation>().Play ("Down");
yield return new WaitForSeconds(delayTime);
}
}
Now it should loop the two animations. In the original code the break statements are causing the execution jump out of the loop and, therefore, the Play for the "Down" is never called and execution of the function is terminated.
If you want the lift go up and down only once you need to remove the while loop.
Right, I've got a slight problem here, in which I've attempted to implement a lap timer.
In my protect override void update I've got this;
if ((IntersectPixels(destinationRedRect, car2redTextureData, startingLineRectangle, startingLineTextureData)))
{
{
redHit = true;
_timer1 += gameTime.ElapsedGameTime.TotalMilliseconds;
}
}
What I'm saying here^ is, if car2red is colliding with the starting line, the timer begins, but if it's not, timer does not add seconds (it just stops_ . How can I make it so, if car2red hits the startingLine and moves forward a few pixels (without touching starting line) the timer still continues?
Thank you.
You should have a separate if statement like this:
if (redHit) {
_timer1 += gameTime.ElapsedGameTime.TotalMilliseconds;
}
if ((IntersectPixels(destinationRedRect, car2redTextureData, startingLineRectangle, startingLineTextureData)))
{
redHit = true;
//Only use this line if you want to reset the timer to 0 when the player crosses that line again.
_timer1 = 0;// I'm assuming that _timer1 is a double
}