Entitas icon indicating copy to clipboard operation
Entitas copied to clipboard

Adding "body parts" to character

Open svanderweele opened this issue 6 years ago • 2 comments

Hi,

I'm wondering how you guys would approach adding Body Parts to an Entity.

This is my current approach :

using btcp.ECS.Core.Services.Interfaces;
using Entitas;
using Entitas.Unity;
using UnityEngine;

namespace btcp.ECS.Core.Services.Unity
{
	public class UnityView : MonoBehaviour, IView, IPositionListener, ISpriteListener{

		public virtual void Link(IEntity entity, IContext context)
		{
			var e = (GameEntity) entity;

			e.AddPositionListener(this);
			e.AddSpriteListener(this);
			
			gameObject.Link(e, context);
		}

		public void OnPosition(GameEntity entity, Vector2 value)
		{
			transform.localPosition = value;
		}

		public void OnSprite(GameEntity entity, string path)
		{
			var sr = gameObject.GetComponent<SpriteRenderer>();
			if (sr == null) sr = gameObject.AddComponent<SpriteRenderer>();
			sr.sprite = Resources.Load<Sprite>(path);
		}
	}
}

using btcp.ECS.Core.Services.Unity;
using Entitas;
using Entitas.VisualDebugging.Unity.Editor;
using UnityEngine;

namespace Siege.ECS.Services.Character
{
    public class CharacterView : UnityView
    {
        public override void Link(IEntity entity, IContext context)
        {
            base.Link(entity, context);
            
            //Add body parts
            foreach (GameObject child in transform)
            {
                var e= (GameEntity)entity;
                var bodyPart = child.GetComponent<SiegeBodyPart>();
                var part = Contexts.sharedInstance.game.CreateEntity();
                part.AddBodyPartId(bodyPart.id.ToString());
                part.AddBodyPart(e.id.value);
            }
        }
    }
}

using UnityEngine;

namespace Siege.ECS.Services.Character
{
    public class SiegeBodyPart : MonoBehaviour
    {
        public BodyPartId id;
    }

    public enum BodyPartId
    {
        Head,
        Torso,
        Left_Arm,
        Right_Arm,
        Left_Leg,
        Right_Leg
    }
}

svanderweele avatar Mar 05 '18 10:03 svanderweele

I see you're using the events, I already like that a lot :)

I don't have any insights into your game, but why do you need entities for the body parts? When you want to stick to the idea that the view maintain themselves then try only using the CharacterView or the BodyParts for the view logic. But sure, depending on your game you can also decide to control the view with systems and entities if necessary. Personally, I try to fully decouple the views from the game logic, as a result I don't have view components or view systems anymore.

sschmid avatar Mar 08 '18 18:03 sschmid

The reason is for sprite swapping. I've got Pirate units that have interchangeable parts, different shirts, different weapons etc.

But now I'm wondering how you would do this without using systems?

using UnityEngine;

namespace Siege.ECS.Services.Character
{
    public class SiegeBodyPart : MonoBehaviour
    {
        public BodyPartId id;
        public Sprite[] Sprites;

        void Start()
        {
            GetComponent<SpriteRenderer>().sprite = Sprites[Random.Range(0, Sprites.Length)];
        }

    }

    public enum BodyPartId
    {
        Head,
        Torso,
        Left_Arm,
        Right_Arm,
        Left_Leg,
        Right_Leg
    }
}

svanderweele avatar Mar 09 '18 04:03 svanderweele