• Advertisement
Sign in to follow this  

Unity GameObject State management

This topic is 1444 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am trying to use the 2D portion of Unity3D for the first time so I am creating a breakout clone. 

My issue is that the state management is getting decentralized... and I am not 100% certain if it is because a) It has to be, or more likely b) I'm doing something "wrong".

 

I have 4 major game objects, The ball, the paddle, walls, and blocks. The blocks state is simple, it starts at State N and each time the ball collides with it it moves to state N-1, at state N=0 it gets destroyed.

 

The walls and the paddle are also simple as they have only a single state each.

 

The ball is where it is getting tricky..

The ball has three states: Setup, LockedToPaddle and Moving.

It has a public function setState(state) :It's only public so the animation event can see it. SetState only changes to the new state if the new state is a valid state to transition to (For example, attempting to setState(Moving) from setup will not do anything, nor will setState(x) from state x.

When a state is successfully changed, it will also update the state variable in the animator.

 

The animator has an integer parameter State: 1=Setup, 2=lockedToPaddle,3=Moving

Each state has it's own animation, at the start of each animation there is an animation event which calls setState(State). 

The setup state has a transition with a 3 loop exit condition, which moves to LockedToPaddleState

LockedPaddleState has a conditional transition on State=3 to transition to Moving.

Moving has a conditional transition on State=1 to Setup.

 

Further, I have an inputmanager game object with a delegate OnBallFire which triggers when the user presses the space bar. The ball gameobject has a method ball_OnBallFire() which calls setState(Moving)

 

Then In the collision2d method for the ball, if the ball collides with the "deadzone" (the area below the paddle). It calls setState(Setup).

 

As you can see... stateTransitions are made from all over the place... is this normal? Is there a way to centralize the state transition logic? Is it an issue that the animator can update the state, but the state can also update the animator? 

 

 

 

Share this post


Link to post
Share on other sites
Advertisement


As you can see... stateTransitions are made from all over the place... is this normal? Is there a way to centralize the state transition logic? Is it an issue that the animator can update the state, but the state can also update the animator?

It is correct that events which (may) cause a transition come from various places. Nothing to worry about.

 

It would be a bit more decoupled if others would not call setState(…) but send an event like "ball_hit_deadzone", "ball_hit_block", … to the state machine (i.e. they are passed to the current state). However, whether this decoupling is worth the effort in your case is on your decision. But notice that the same events may trigger other effects, too. E.g. the sound sub-system can be triggered to play the appropriate collision or "loss in deadzone" indicating sounds on the same events.

 

The animation may send events to the state machine, too, but I suspect that it is needed in your use case. A typical case would be that the end of an animation timeline was reached (which does not occur in your case, AFAIS). Another typical case would be that specific timestamps on the timeline cause some effect, e.g. footstep sound or so, but that also is not needed for your use case (again AFAIS).

Share this post


Link to post
Share on other sites


Is it an issue that the animator can update the state, but the state can also update the animator? 

 

I think it's an issue that both the ball and the animator have the same state. You're duplicating state here - they're always the same, so they should probably leverage the same value (which could be stored in the ball) so there are never any synching issues. If you want, you can achieve better decoupling between the ball and the animator by using an interface (I'm not sure how much the ball/animator need to know about each other).

 

As haegarr suggested, you could coalesce your state logic into one piece of code and create new abstractions (e.g. events) to drive transitions between states.

Share this post


Link to post
Share on other sites

Cool.

 

Another question. I noticed in the asset store an AI State machine that worked the same as the animation state machine... in what instances would it be beneficial to use a separate AI state machine rather than just doubling your animation states as AI states? From my limited usage it seems that each task an AI Machine might contain would require an animation and each animation represents a task or action... even if multiple AI States utilize the same animation but have different transition conditions, the animation state only holds a pointer to the animation clip so it would not be outrageous to have multiple animation states that play the same animation right?   

Share this post


Link to post
Share on other sites

Another question. I noticed in the asset store an AI State machine that worked the same as the animation state machine... in what instances would it be beneficial to use a separate AI state machine rather than just doubling your animation states as AI states?


Non-trivial games typically have a lot of animation states that really have nothing to do with what an AI is trying to achieve. The AI might simply be following a path from the navigation system which might include climbing, jumping, dropping, opening a door, etc. The AI doesn't need to care about all of these, but the animation system certainly has to.

More complex games can't even represent animation with a simple state machine. There are often hierarchical state trees, blend trees, procedural animations, and so on. Such games typically isolate most of the animation state from everything else and rely only on a set of inputs (direction/velocity, whether on the ground or not, etc.) and use a very specialized animation tool for defining the animation states, transitions, blend weights, IK parameters, procedural animations, etc. Physics and AI then provide data for the animation system to make decisions based upon.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
  • Advertisement
  • Popular Tags

  • Advertisement
  • Popular Now

  • Similar Content

    • By NDraskovic
      Hey guys,
      I have a really weird problem. I'm trying to get some data from a REST service. I'm using the following code:
       
      private void GetTheScores() { UnityWebRequest GetCommand = UnityWebRequest.Get(url); UnityWebRequestAsyncOperation operation = GetCommand.SendWebRequest(); if (!operation.webRequest.isNetworkError) { ResultsContainer rez = JsonUtility.FromJson<ResultsContainer>(operation.webRequest.downloadHandler.text); Debug.Log("Text: " + operation.webRequest.downloadHandler.text); } } The problem is that when I'm in Unity's editor, the request doesn't return anything (operation.webRequest.downloadHandler.text is empty, the Debug.Log command just prints "Text: "), but when I enter the debug mode and insert a breakpoint on that line, then it returns the text properly. Does anyone have an idea why is this happening?
      The real problem I'm trying to solve is that when I receive the text, I can't get the data from the JSON. The markup is really simple:
      [{"id":1,"name":"Player1"},{"id":2,"name":"Player2"}] and I have an object that should accept that data:
      [System.Serializable] public class ResultScript { public int id; public string name; } There is also a class that should accept the array of these objects (which the JSON is returning):
      [System.Serializable] public class ResultsContainer { public ResultScript[] results; } But when I run the code (in the debug mode, to get any result) I get an error: ArgumentException: JSON must represent an object type. I've googled it but none of the proposed solutions work for me.
      Also (regardless if I'm in the debug mode or not) when I try to do some string operations like removing or adding characters to the GET result, the functions return an empty string as a result
      Can you help me with any of these problems?
      Thank you
    • By nihitori
      The Emotional Music Vol. I pack focuses on beautiful and esoteric orchestral music, capable of creating truly emotive and intimate moods. It features detailed chamber strings, cello and piano as the main instruments, resulting in a subtle and elegant sound never before heard in video game royalty-free music assets.

      The pack includes 5 original tracks, as well as a total of 47 loops based on these tracks (long loops for simple use and short loops for custom / complex music layering).

      Unity Asset Store link: https://www.assetstore.unity3d.com/en/#!/content/107032
      Unreal Engine Marketplace link: https://www.unrealengine.com/marketplace/emotional-music-vol-i

      A 15 seconds preview of each main track is available on Soundcloud:
       
    • By RoKabium Games
      Another one of our new UI for #screenshotsaturday. This is the inventory screen for showing what animal fossils you have collected so far. #gamedev #indiedev #sama
    • By eldwin11929
      We're looking for programmers for our project.
      Our project is being made in Unity
      Requirements:
      -Skills in Unity
      -C#
      -Javascript
      -Node.js
      We're looking for programmers who can perform a variety of functions on our project.
      Project is a top-down hack-and-slash pvp dungeon-crawler like game. Game is entirely multiplayer based, using randomized dungeons, and a unique combat system with emphasis on gameplay.
      We have a GDD to work off of, and a Lead Programmer you would work under.
      Assignments may include:
      -Creating new scripts of varying degrees specific to the project (mostly server-side, but sometimes client-side)
      -Assembling already created monsters/characters with existing or non-existing code.
      -Creating VFX
      -Assembling already created environment models
      If interested, please contact: eldwin11929@yahoo.com
      This project is unpaid, but with royalties.
       
      ---
      Additional Project Info:
      Summary:
      Bassetune Reapers is a Player-verus-Player, competitive dungeon crawler. This basically takes on aspects of dungeon crawling, but with a more aggressive setting. Players will have the option to play as the "dungeon-crawlers" (called the 'Knights', or "Knight Class", in-game) or as the "dungeon" itself (literally called the 'Bosses', or "Boss Class", in-game). What this means is that players can choose to play as the people invading the dungeon, or as the dungeon-holders themselves.
      Key Features:
      -Intense, fast-paced combat
      -Multiple skills, weapons, and ways to play the game
      -Tons of different Bosses, Minibosses, creatures and traps to utilize throughout the dungeon
      -Multiple unique environments
      -Interesting, detailed lore behind both the game and world
      -Intricate RPG system
      -Ladder and ranking system
      -Lots of customization for both classes s of customization for both classes
    • By RoKabium Games
      Custom coffee mugs have arrived... More caffeine!
      Have a great weekend everyone! 
      #gamedev #indiedev #sama #caffeine
  • Advertisement