I'm developing my first game and I have a player class (FlxSprite) that has a death animation.
I want to remove the player from the stage as soon as the animation ends, but if I use:
player.animation.play('death');
remove(player);
The animation doesn't finish and the player just disappears.
The way I handle this in most of my projects is something like this:
override public function update(elapsed:Float):Void
{
if (!alive)
{
if (animation.finished)
{
exists = false;
}
super.update(elapsed);
}
// other update stuff...
super.update(elapsed);
}
override public function kill():Void
{
if (!alive || !exists)
{
return;
}
alive = false;
animation.play("death", true);
// Note: I DO NOT call super.kill() because I want to leave exists = true
}
And, in your PlayState or wherever you want to remove the object, just check if (!player.exists) remove(player);, I guess? I don't usually use remove, I just wait until the state is destroyed and then clean everything up with FlxDestroyUtil.
Your question isn't super clear, but I'll try help anyway.
Because of the way the game loop is looping, the remove function kills off the sprite before the animation plays. You can check to see when the animation is finished by putting an if statment in your update function, like so.
if (animation.finished) kill()
If you need an actual timed delay, you can see my previous answer where you increase a variable by FlxG.elapsed every update on a variable until it exceeds your timer length.
I hope this answers your question. You may want too look at methods such as kill() in the HaxeFlixel docs, as I think you might be confused with remove().
EDIT: very sorry, forgot to include one important detail. It is likely that you are calling animation.play every single frame - stop once your death animation plays. In my code I saw I have an isDying variable that stops any new animations starting, and checks to see if the current animation is finished. Without this, the finished variable might not flip.
Related
So basically I have two questions. I am also copying off this video from 2014: https://www.youtube.com/watch?v=w8JgpEjm8i8&t=2792s
Question 1
At the end of the video above the guys computer completely crashed and he wasnt able to show the end of how to setup a death animation for my player (link). So currently I have setup a movie clip of the death animation - just the playing spinning around - and put it in another movie clip called 'All Sprites' in which I have my other movie clips such as the different walking directions. So I have placed it in there, labelled it with "Link Death Frame". I then went back to the main script and added code so that once my player dies, the animation will play. Such as:
~
if(linkHealthBarMC.scaleX <= 0.01)
{
linkAlive = false;
}
trace(linkAlive);
if(linkAlive == false)
{
linkMC.gotoAndStop("Link Death Frame");
}
~
However, the issue comes in which the animation doesnt actually play, it just goes straight to the first frame and doesnt play. I have tested it and I know for sure that it gets stuck on the first frame and that something must be wrong with the animation as I tested it with another animation and it worked fine (once I met the requirements for the animation to play). So does anyone have any idea how I can fix this issue so that my character can play a death animation?
Question 2
How do I stop time? Like just completely freeze everything after my character is dead? Because at the moment I am just going to the first frame of the death animation and can still move and attack.
I'd assume this is on an EnterFrame loop. Then you would have two possible causes for this:
1.) You're loop is constantly checking if the 'linkAlive' if statement is false (which it is) and setting your Animation to the first frame. You can check this method by putting a Trace statement in your if statement and if the output window overflows, then that's your culprit.
2.) What you want is gotoAndPlay(-insert label here-)
Tho it is outside the scope of the question you have, I create a variable~Switch State machine to control states for me:
1.) Current State as a number (int, number, or uint)
2.) function with a switch statement (Switch is kind of a fancy if Statement)
3.) inside the cases are instructions
switch(current_state){
case 1:
linkMC.gotoAndPlay('death animation');
break;
}
if (current_state != 1){
-put movement code here-
}
This is close to what I use for my game. Just checking states or you can have a variable like the one above that explicitly checks for the death state and remove the ability to move. If you use a mouse (and I assume event listener) then you can remove the event listener for the mouse. If you use a solution like keyboard inputs then an if statement would be more what you are looking for.
I'm kind of new to this so sorry if I'm writing in the wrong place - let me know and I'll move / delete this comment.
I'm currently having issues detecting controller input while using VRTK.
For example, when I have a collision between two objects, I want to be able to detect what buttons are being pressed on the controllers but can't seem to work out how I can do this.
Also, I have implemented the Interact Use functionality but I'm struggling to work out how to make two buttons do different actions.
For example:
once I grab an object with the simple pointer I want one button to
bring the object closer and another to move it away, but I've only
managed to implement one or the other.
Any suggestions? I've looked everywhere in the docs, examples and Google and can't seem to find anything. Any help would be MUCH appreciated! Pulling my hair out here!
You could utilise the Grabbedmethod on the InteractableObject: https://vrtoolkit.readme.io/docs/vrtk_interactableobject#section-grabbed-1
Or you could use the ControllerGrabInteractableObject event on The InteractGrab script: https://vrtoolkit.readme.io/docs/vrtk_interactgrab#section-class-events
Or you could have an Update routine and check the grabbed status on the controller doing GetGrabbedObject() != null (which checks to see if the controller has an object grabbed if it's null then one isn't grabbed).
Then you can use the ControllerEvents button bools to do something on a button press. So a script with this in that sits on the controller script alias gameobject next to the interact grab script:
void Update() {
if (GetComponent<VRTK_InteractGrab>().GetGrabbedObject != null) {
var controllerEvents = GetComponent<VRTK_ControllerEvents>();
if (controllerEvents.IsButtonPressed(VRTK_ControllerEvents.ButtonAlias.Trigger_Press) {
//Do something on trigger press
}
if (controllerEvents.IsButtonPressed(VRTK_ControllerEvents.ButtonAlias.Grip_Press) {
//Do something on grip press
}
}
}
I can't find any answers to this. What I want is to set a 5 min time limit that begins when the level begins and ends when level ends. I also want it to kill the player if it runs out. This is for Unity2D and I want the timer to be seen at top left or right of screen. So basically I need a time limit like that of Super Mario. In C# code please.
Break up your problem into easier tasks. You will need some type of timer, and you will want to know how to 'kill' the player.
To create a timer, you can take advantage of how Update runs once per frame. Unity also comes with a Time class. In Time, there is a variable deltaTime which keeps track of the time in seconds to complete the last frame. Some other things you might want to add on to your class that acts as a timer is when to start and stop the timer.
To output the value from a timer to the game, you might want to use Unity's UI system and canvas. You might create a text object that is part of a canvas and anchor that text object to the top left corner.
To 'kill' a player, you can have some method that runs once the timer reaches the time in question and run the kill logic you want.
Helpful links:
MonoBehavior Update: https://docs.unity3d.com/ScriptReference/MonoBehaviour.Update.html
Time: https://docs.unity3d.com/ScriptReference/Time.html
UI: https://unity3d.com/learn/tutorials/topics/user-interface-ui
You can create a class that keeps track of the timer and to check if the requirements to fail are still there.
In this case you can have a float for the timer, and a bool for the condition whenever you completed the level or not.
It the timer reaches zero, check if the bool is still false, if it is, then you call something like KillPlayer(). If you complete the level by hitting a trigger or anything that will know if the level should be considered finished, you set the bool to true.
So your final check could look like this:
public float levelTimer = 300f;
public bool levelComplete = false;
void Start()
{
levelTimer = 300f;
levelComplete = false;
}
void Update()
{
levelTimer -= Time.deltaTime;
if(levelTimer <= 0 && !levelComplete)
{
KillPlayer();
//Something like a Game Over screen maybe
}
}
I hope this help you in the right direction.
I need to play animation just one time.
Something like this:
public Animation[] animations;
animations[0].play();
I've looked through StackOverflow, all I found is:
animation["AnimationName"].wrapMode = WrapMode.Once;
animation.Play("AnimationName");
But it makes nothing.
Is this method actually for Unity3D 5?
Are there new ways to play animation one shoot?
I have one way for playing animation on mouse down.
For that open animator controller and add that dropping animation and one will be idle animation(this will have initial stage of dropping). Now make idle animation as default and add transition from idle to dropping animation.
Add parameter to this transition of type "Trigger". Set this parameter in transition condition.
And add one more transition from dropping animation to idle state.
So after dropping animation complete , it will come again in idle state.
Now For scripting :
int dropHash = Animator.StringtoHash("parameterName");
onmouseDown :
animator.SetTrigger(dropHash);
Hope you get some idea. This may help you. Thanks.
You have to use wrapMode. In your case, it can be something like
foreach(Animation anim in animations) {
anim.wrapMode = WrapMode.Once;
anim.Play();
}
I'm restarting development of a game I was working on, and have successfully converted it over to XNA 4.0 using the cheat sheet. Most of it works, some of it doesn't, and I'm in the process of fixing what doesn't work.
One thing that I had was a state system that was heavily based on the state system used as an example of XNA Unleashed, the ebook. I didn't have much in it.... basically just the ability to pause the game.
When I paused the game, the action of the game would stop, and the word "PAUSED" would appear in block letters across the screen, and you'd see the paused action. However, now it seems that the sprite batch automatically clears out everything between frames, so when I pause the game now, the screen clears, leaving PAUSED over a purple background. Back then, I believe that adding "SaveStateMode.SaveState" would prevent that from happening, but that functionality was removed. When I did some research, I found out that it was removed because it was essentially useless, that's all handled in the game state manager.
However, I can't find any documentation on this. Where should I start? Right now, my code looks like this:
In the Playing Game State update method:
if (input.WasPressed(0, Buttons.Start, Keys.Enter))
{
GameManager.PushState((GameState)ThisGame.PausedGameState.Value);
}
public void PushState(GameState newState)
{
AddState(newState);
//Let everyone know we just changed states
if (OnStateChange != null)
{
OnStateChange(this, null);
}
}
private void AddState(GameState state)
{
states.Push(state);
Game.Components.Add(state);
//Register the event for this state
OnStateChange += state.StateChanged;
}
//PausedGameState Draw method:
public override void Draw(GameTime gameTime)
{
ThisGame.SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, null, null, null, null);
DrawPaused(); //draws the Paused Text
ThisGame.SpriteBatch.End();
}
The goal is to make "PAUSED" appear over the screen, with a snapshot of where the gameplay left off... and not "PAUSED" over a cleared purple screen.
Do you suppose that GraphicsDevice.Clear() somehow got called after the state changed to paused? What does the DrawPaused() method do in your code?