Adding multiple scripts to an custom inspector

Hi,

I’m currently working on making a modular character controller, this is made of multiple scripts, for example (canFly) (canSwim) (canJump) etc will all be separate scripts.

At the moment I can drag and drop them onto the controller and they work fine.

But I would like to make a custom editor for my character controller where I can just drag and drop these ‘abilities’ into an abilities list/dictionary.

Is there a way of doing this? I have looked around and haven’t found anything, I have looked at using scriptable objects, which would work but its a bit more restrictive than what I want.

Don’t ask why I’m doing this, just because would like too.

I have added a mock-up of the kind of thing I would like to achieve.

198508-abil.png

There are going to be lots of ways to approach this. So this might not be quite what you want but hopefully it will be of some use.

I would not try to show the ability component fields in the Character Controller inspector. I think this would be overly complicated with little benefit. From your comments I understand the abilities are MonoBehaviours that can have their own inspector fields. If I understand correctly you want to simplify the user experience of adding and removing ability components.

I would first add a base class for your abilities so that you can easily find ability components:

public abstract class CharacterAbility : MonoBehaviour
{
}

public class FlyAbility : CharacterAbility
{
    ...
}

You could create an enum with the “Flags” attribute to represent the enabled ability types , and add an inspector field to the character controller using this enum:

[Flags]
public enum CharacterAbilityTypes
{
    None = 0,
    Flying = 1 << 0,
    Jumping = 1 << 1,
    Swimming = 1 << 2
}

public class ModularCharacterController : MonoBehaviour
{
    public CharacterAbilityTypes abilities;
}

In your controller custom inspector you then add/remove the ability components depending on what options are selected in the controller inspector:

public override void OnInspectorGUI()
{
    base.OnInspectorGUI();

    var characterController = target as ModularCharacterController;

    UpdateAbility<FlyAbility>(characterController.abilities.HasFlag(CharacterAbilityTypes.Flying));
    UpdateAbility<SwimAbility>(characterController.abilities.HasFlag(CharacterAbilityTypes.Swimming));
    UpdateAbility<JumpAbility>(characterController.abilities.HasFlag(CharacterAbilityTypes.Jumping));
}

private void UpdateAbility<T>(bool hasAbility) where T : CharacterAbility
{
    var characterController = target as ModularCharacterController;
    var abilityComponent = characterController.GetComponent<T>();

    if (!hasAbility && abilityComponent != null)
    {
        Undo.DestroyObjectImmediate(abilityComponent);
    }
    else if (hasAbility && abilityComponent == null)
    {
        Undo.AddComponent<T>(characterController.gameObject);
    }
}

Inspector then looks like:
198547-inspector1.png

198548-inspector2.png

That’s an awesome answer, thanks so much for your help!