Skip to content

Entity (Deprecated)

Mariusz edited this page May 20, 2020 · 1 revision

(The following content has been removed and is no longer available in the WarWolfWorks library)


The Entity class is the parent class of the entity system as well as all of it's EntityComponents. To use this class, include

using WarWolfWorks.EntitiesSystem;

at the top of your script.

Setup

To use the Entity class, you must first inherit from it, as it is an abstract class; Let's start by making a Player script:

using System;
using WarWolfWorks.EntitiesSystem;

namespace AwesomeJoJoGame.EntitiesSystem
{
    public sealed class Player : Entity
    {
        public override Type EntityType => typeof(Player);
    }
}

The key takeaway here is to override the EntityType field with a type, as this is the only abstract field of the Entity class. In this case, the player (usually) doesn't have a sub-type, so let's just pass it's own type.

Now let's say that you want to expose the Rigidbody to your components; The standard approach would be to draw it inside MonoBehaviour's Awake() method with GetComponent<Rigidbody>, however, most unity methods have an overridable alternative in the Entity class (EntityComponent behaves in the same way), which are required to be used instead of the standard MonoBehaviour method.

Here's an example:

"Standard" Approach

using UnityEngine;

namespace AwesomeJoJoGame
{
    public sealed class Player : MonoBehaviour
    {
        public Rigidbody Rigidbody { get; private set; }

        private void Awake()
        {
            Rigidbody = GetComponent<Rigidbody>();
        }
    }
}

Entity Approach

using System;
using UnityEngine;
using WarWolfWorks.EntitiesSystem;

namespace AwesomeJoJoGame.EntitiesSystem
{
    public sealed class Player : Entity
    {
        public override Type EntityType => typeof(Player);
        public Rigidbody Rigidbody { get; private set; }

        protected override void OnAwake()
        {
            Rigidbody = GetComponent<Rigidbody>();
        }
    }
}

When you put that script on a GameObject, you will see a "Entity Name" field; This acts like a tag to help you find one or more specific entities using EntityManager.Find(Predicate<Entity>) or EntityManager.FindAll(Predicate<Entity>).

More Examples

Now of course, the player wouldn't be the only entity in the game, otherwise it would defeat the whole point of having an Entity system. So let's make an two enemies Slime and Zombie with the sub-type Enemy:

Enemy.cs

using System;
using WarWolfWorks.EntitiesSystem;

namespace AwesomeJoJoGame.EntitesSystem
{
	public abstract class Enemy : Entity
	{
        public override Type EntityType => typeof(Enemy);

        public Entity Target { get; protected set; }

        public abstract bool Harmful { get; }

        [HideInInspector]
        public bool AIActive;

        protected abstract void AI();

        protected override void OnAwake()
        {
            Target = EntityManager.Find(e => e.IsEntity(typeof(Player)));
        }

        protected override void OnFixed()
        {
            if(AIActive) AI();
        }
    }
}

Slime.cs

namespace AwesomeJoJoGame.EntitiesSystem
{
	public class Slime : Enemy
	{
        public override bool Harmful => false;

        protected override void AI()
        {
            //Some sort of Jumping mechanic, idk
        }
    }
}

Zombie.cs

using UnityEngine;

namespace AwesomeJoJoGame.EntitiesSystem
{
	public class Zombie : Enemy
	{
        public override bool Harmful => true;

        [SerializeField]
        private float Speed;

        protected override void AI()
        {
            transform.position = Vector3.MoveTowards(transform.position, Target.Position, Speed);
        }
    }
}

You can also make multiple sub-types, like a Boss class which would be an abstract class that inherits from Enemy:

using System;

namespace AwesomeJoJoGame.EntitiesSystem
{
	public abstract class Boss : Enemy
	{
        public override sealed bool Harmful => true;

        public override sealed Type EntityType => typeof(Boss);
    }
}

Supported Systems

The Entity system also has some pre-made systems that are supported by default:

Parenting system

To use it, implement the IEntityParentable class after the inherited entity type; Then, implement both the Entity Parent field as well as event Action<Entity, Entity> OnParentSet; If you're unsure of how you want to implement it, a simple way would be:

using System;
using WarWolfWorks.EntitiesSystem;
using WarWolfWorks.Interfaces;

namespace AwesomeJoJoGame.EntitiesSystem
{
	public abstract class Enemy : Entity, IEntityParentable
	{
        public override bool Harmful => true;

        public override Type EntityType => typeof(Enemy);

        private Entity parent;
        public Entity Parent
        {
            get => parent;
            set
            {
                if (parent == value)
                    return;
                parent = value;
                OnParentSet?.Invoke(this, parent);
            }
        }

        public event Action<Entity, Entity> OnParentSet;
    }
}

To verify if an Entity has a parent and use it, you can simply type:

if(entity is IEntityParentable)
{
   ((IEntityParentable)entity).Parent.Position = Vector3.zero;
}

Public Methods

T AddEntityComponent<T>() where T : Component, IEntityComponent

Adds an entity component based on given generic type.

IEntityComponent AddEntityComponent(Type)

Adds an entity component based on given type.

void Destroy()

Destroys the entity. Note: Required to use, do not use MonoBehaviour's Destroy method as it will likely break.

void DestroyUnofficially()

Destroys the entity without calling any Destroy method.

T GetEntityComponent<T>()

Gets the entity component of specified generic T type.

T GEC<T>()

Equivalent to GetEntityComponent().

bool TryGetEntityComponent<T>(out T)

A try-get version of GetEntityComponent.

bool TGEC<T>(out T)

Equivalent to TryGetEntityComponent(out T).

IEnumerable<T> GetEntityComponents<T>()

Returns all entity components which are of given generic T type.

IEntityComponent[] GetAllEntityComponents()

Returns all entity components.

bool IsEntity(Type)

Returns true if the entity is of given type.

bool IsUnderlyingEntity(Type)

Returns true if the entity's underlying type is equal to the given type.

bool RemoveComponent<T>()

Removes the first EntityComponent of the given generic T type, without destroying it (The script stays, however the Entity will no longer detect it). Note: This method still calls EntityComponent.OnDestroyed().

bool RemoveComponent(IEntityComponent)

Removes a specific EntityComponent; Similarly to RemoveComponent<T>(), it removes it without destroying it.

bool RemoveEntityComponent<T>() where T : Component, IEntityComponent

Removes the first EntityComponent of given generic T type.

bool RemoveEntityComponent(Type)

Removes the first EntityComponent of given type.

Public Properties/Fields

event Action<Entity, CallType> OnCallEventTrigger

Invoked when OnAwake(), OnStart(), OnEnabled(), OnDisabled() and OnDestroyed() are called.

Quaternion Rotation

Pointer to transform.rotation.

Vector3 Position

Pointer to transform.position.

Vector3 Euler

Pointer to transform.eulerAngles.

Stats Stats (get-only)

Stats class of the current entity. (Initiated on Entity creation.)

AnimationManager AnimationManager (get-only)

The Entity's AnimationManager. (Only usable if entity was created with it.

Public Virtual Properties

string Name

Name of the entity.

Protected Virtual Methods

void OnAwake()

Equivalent to MonoBehaviour.Awake().

void OnStart()

Equivalent to MonoBehaviour.Start().

void OnEnabled()

Equivalent to MonoBehaviour.OnEnable().

void OnDisabled()

Equivalent to MonoBehaviour.OnDisable().

void OnFixed()

Equivalent to MonoBehaviour.FixedUpdate().

void OnUpdate()

Equivalent to MonoBehaviour.Update().

void OnDestroyed()

Equivalent to MonoBehaviour.OnDestroy().

void OnBeforeDestroy()

Called right before OnDestroyed().

Protected Methods

void CallComponentMethods(CallType)

Calls the execution method of all EntityComponents.

Clone this wiki locally