- Home /
Getting a reference to an object from a state behaviour
I have a State Behavior walk and Cry.
When "OnStateEnter" fires from the animator, I want to change some properties on the gameObject that is entering the state.
So when the enemy enters the walk state from the State Behavior overriden method, what is the most efficient way to get a reference to this object that has a script "EnemyScript" attached to it?
Answer by Hellium · Dec 07, 2017 at 08:20 PM
using UnityEngine;
public class MyStateBehaviour : StateMachineBehaviour
{
override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
EnemyScript script = animator.GetComponent<EnemyScript>();
script.DoSomething();
}
}
Is there a less gross way of doing this? I am having a similar issue, and I came to this same solution on my own, but I dont want to be doing a GetComponent on every state enter, because thats going to be happening a lot, on many objects, and thats very bad for performance.
I tried serializing a RigidBody2D varaible and dragging in the component on/from the prefab, but I guess this results in every object in the scene referencing the component in the prefab and not its own rigidbody.
You could take advantage of interfaces I guess.
SOLUTION NOT TESTED
public interface Foo<T>
{
T Component { get; set; }
}
[RequireComponent(typeof(Animator))]
public class Bar : $$anonymous$$onoBehaviour
{
[SerializeField] private EnemyScript enemy;
private void Start()
{
Foo<EnemyScript>[] foos = GetComponent<Animator>().GetBehaviours<Foo<EnemyScript>>();
foreach(var foo in foos)
foo.Component = enemy;
}
}
public class $$anonymous$$yStateBehaviour : State$$anonymous$$achineBehaviour, Foo<EnemyScript>
{
public EnemyScript Component { get; set; }
override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
Component.DoSomething();
}
}
using UnityEngine;
public class MyStateBehaviour : StateMachineBehaviour
{
private EnemyScript script;
override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
if(script == null)
script = animator.GetComponent<EnemyScript>();
script.DoSomething();
}
}
Answer by Bendixsa · Jun 26, 2020 at 04:28 PM
@krupps You can add a base state behavior script, In other words one that acts on the overall state machine. You do this by just clicking on the background of the animator to deselect any states (the base layer itself).
You will then see in the inspector you can add a behavior (it's the only thing you can do here)
This behavior is special because it has additional event hooks and is persistant to the statemachine making it the perfect place to cache some references and a great place to do higher level persistent logic to control the state machine.
Hope This Helps. Enjoy!
Answer by krupps · May 30, 2020 at 09:49 PM
Actually a GetComponent is just a cast so it’s really not that bad
Your answer
Follow this Question
Related Questions
Assign spells/abilities dynamically to a GameObject? 0 Answers
Animation issue (OnTriggerEnter) ***SOLVED*** 1 Answer
Keyframes of animated Child gameobject not shown by parent gameobjects animator issue ? 0 Answers
using Contains(gameObject) to find and destroy a gameObject from a list 2 Answers
Air jumping animation help 1 Answer