Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

Animator Controller with different spells in a moddable game

Discussion in 'Animation' started by RakNet, Sep 26, 2017.

  1. RakNet

    RakNet

    Joined:
    Oct 9, 2013
    Posts:
    313
    I'm writing a moddable game where you control a mage that can cast spells. I expect the various spells to be quite different. A magic missile may be castable only when idle. A blink may be castable anytime, even when running. Some spells may play different animations based on custom parameters defined by the modder.

    I don't know what the spells are until I import the mods (at runtime). Any mod may define between 0 and infinity number of spells.

    So I'm presented with the problem of how to setup a generic animator controller system that can support this.

    I already have a base animator controller with run, walk, idle. How do I switch to casting a spell?

    Option 1: Switch out animator controllers when the player wants to cast a spell. The new animator controller will be provided by the mod, and is per-spell. I will have a special predefined parameter "Exit" when that spell is done and the character should go back to the base animator controller. The mod is responsible for only allowing spell casts during valid states.

    Problem: I suspect switching out animator controllers will cause the mage to warp animations instead of smoothly blend.

    Option 2: Use the Animator Override controller. Define in the base animator controller a spell system, such as StartCast, UpdateCast, InterruptCast, EndCast, etc.

    Problem: This is really limited - for example, the modder may have different branches depending on what type of equipment you have, extra parameters, etc.

    Option 3: Give the modders the base animator controller to work from. So every spell will reimplement idle, run, walk, etc. but these will be setup with defaults. This is better than option 1 in that the modder has total control over when spells can be cast.

    Problem: I still suspect switching out animator controllers will cause the mage to warp animations instead of smoothly blend.

    Option 4: On import, read every animator controller and copy out a predefined state machine. Add this state machine and any defined parameters to the base state machine.

    Problem: I'm almost certain you cannot modify the animator controller at runtime, or read the state machine.

    Anyone with experience can help out with this? Each approach is a lot of work to test out and I don't want to waste time on something that won't work or look good.
     
  2. CaseyLee

    CaseyLee

    Joined:
    Jan 17, 2013
    Posts:
    40
    yee as you suspected, attempting an animator controller built at run time, will be a dead end. Using the Editor-API many interesting things are possible for proceduraly generating state machines - but they are not accessible at run.

    Also the main issue with switching controllers on an animator component is a performance cost issue more than anything else. it is not too difficult to get the current state's animation and playback time on the first controller (say, 55% playing "idle" animation), and then to "set" the second animator controller to play be playing the same animation at that spot - this is doable. However as I stated, the processes Unity goes threw during a controller change is not something you want to be doing constantly during game-play. At-least that was my understanding after some research.

    eh not sure I want to type the essay I would need to explain my big/similar issue and how I went about it... Ill just say my solution involved a very large, somewhat procedurally generated controller, where in different game characters use the same controller, even though they each only using say, 10% of the states. but most the transition/state logic is in code, and all the transitions are from "any state" to sub-state machines. and the sub state machine say of "idle" determines what one of its contained state to go to from there from be checking the controller paramaters, such as a "charactet-int" which are set at run, sometimes. eh hope that made sense, mostly just food for thought
     
    RakNet likes this.
  3. RakNet

    RakNet

    Joined:
    Oct 9, 2013
    Posts:
    313
    CaseyLee, thanks for letting me know it is slow to switch AnimatorControllers. I wouldn't have known that from casual investigation so you saved me a few days of work.
     
    Last edited: Sep 27, 2017
  4. RakNet

    RakNet

    Joined:
    Oct 9, 2013
    Posts:
    313
    *Edit*

    I found a possible solution. You can setup animations on a GameObject hierarchy and start the game even if that hierarchy doesn't exist on the game start.

    So I add to a root game object multiple AnimatorControllers (one per mod). Then I put the hierarchy under the AnimatorController I actually want to use.

    I found a Unity bug where if you just move the heirarchy with SetParent the AnimatorController won't always start playing the animation. But if you enable and disable the game object the AnimatorController is a component on it will work
     
    Last edited: Sep 27, 2017
  5. RakNet

    RakNet

    Joined:
    Oct 9, 2013
    Posts:
    313
    Here I move the Cylinder between Controller 1 and controller 2. The animation clip is moving the transform on the Cylinder

    upload_2017-9-27_9-29-56.png

    upload_2017-9-27_9-30-29.png

    So even though the Cylinder doesn't exist when the game starts, I can attach it while running and apparently Unity will look for the name of the game object to match up, so long as I disable and then enable the game object the Animator component is attached to.