Custom creature actions - LeeTwentyThree/ECCLibrary-Legacy GitHub Wiki

Adding CreatureActions onto your creature

If you want to add a CreatureAction to your creature, you can simply add a prefab.AddComponent<CreatureActionType>() call into your AddCustomBehaviour implementation.

If you are adding a CreatureAction that is from vanilla, I recommend you to use dnSpy or another decompiler, to determine what fields you must set on that newly added component, to avoid possible NREs.

Example of adding a CreatureAction to your creature

The following code should be inside your creature's prefab class.

...
public override void AddCustomBehaviour(CreatureComponents components)
{
    CustomBreatheFireAction customAction = prefab.AddComponent<CustomBreatheFireAction>(); // just so you know, this is a CUSTOM action that will create errors if you try to reference it
    customAction.firePrefab = Mod.assetBundle.LoadAsset<GameObject>("FirePrefab");
}
...

Creating custom CreatureActions

If you want to add custom behavior (that does NOT exist in vanilla) to a fish, it is actually relatively simple. You begin by creating a new class which inherits from CreatureAction (from the Assembly-CSharp dll). You then override whichever virtual methods you think are necessary for this behavior.

After you have created the class that inherits from CreatureAction, you just attach that component and assign whatever fields that may be necessary.

Example of a custom creature action class:

...
// swims to the map center and spawns fire every 0.5 seconds when the Aggression is high enough. a silly example, I know.
class CustomBreatheFireAction : CreatureAction 
{
    private float timeSpawnFireAgain;
    private float kFireSpawnInterval = 0.5f;
    public GameObject firePrefab;

    public override float Evaluate(Creature creature) // tells the creature the likelihood of performing this action
    {
        if (creature.Aggression.Value > 0.5f) // the aggression value of a creature is primarily used by the AggressiveWhenSeeTarget (which will be explained in another page)
            return 1f; // 1f is a very high evaluate priority. this creature action is almost guaranteed to be performed.
        else
            return 0f; // 0f is a very low evaluate priority, and as long as this action is returning 0 it will never be performed.
    }

    public override void Perform(Creature creature, float deltaTime) // called constantly while the action is being performed
    {
        swimBehaviour.SwimTo(new Vector3(0f, 0f, 0f), 3f); // swim to 0,0,0 at a velocity of approximately 3 m/s

        // spawn fire every 0.5 seconds
        if (Time.time > timeSpawnFireAgain)
        {
             SpawnFirePrefab();
             timeSpawnFireAgain = Time.time + kFireSpawnInterval;
        }
    }
     
    private void SpawnFirePrefab()
    {
        ErrorMessage.AddMesage("Spawn fire!"); // shows "Spawn fire!" on the top-left of the screen.
    }
}

CreatureAction methods:

public virtual void Awake()

By default, this method simply sets the reference to the CreatureAction's protected swimBehaviour property, which MOST CreatureActions will use at some point in their lifetime. As a result, you should not override this behavior in the majority of cases. If you do, make sure you also call the base.Awake() method.


public virtual void OnEnable()

Creature.OnEnable automatically sets the reference to the Creature when this component is enabled. Whenever you override this method, you want to make sure you also call base.OnEnable(), because you don't want that creature field to be null.


public float GetEvaluatePriority()

Returns a float. CreatureAction.Evaluate returns this value, unless overridden. If this CreatureAction's priorityMultiplier curve is set, it evaluates that curve with the time of day and multiplies that by evaluatePriority to determine the priority of this action. Otherwise, it just returns evaluatePriority.


public virtual float Evaluate(Creature creature)

The CreatureAction with the highest "Evaluate priority" is the one that is used by a creature. A CreatureAction that always returns 1 for Evaluate will always be called. A CreatureAction that returns 1 while it's daytime and 0 while it's nighttime will only be performed during daytime.


public virtual void StartPerform(Creature creature)

Called when a creature begins performing this CreatureAction. May be called multiple times in the component's lifetime.


public virtual void Perform(Creature creature, float deltaTime)

Called very often, but not every frame, so use the deltaTime parameter for things that will be called continuously. Most of your CreatureAction's logic will go here.


public virtual void StopPerform(Creature creature)

Called when a creature stops performing this CreatureAction to perform another. May be called multiple times in the component's lifetime.

⚠️ **GitHub.com Fallback** ⚠️