#Multiple scripts in one object

1 messages ยท Page 1 of 1 (latest)

stoic kiln
#

I'm not quite sure what you're saying here - do I not need to put all the Update() calls there? The problem I'm currently experiencing is how I'm trying to call Update() seperately between two scripts (PlayerMovement and PlayerStatManager) when both override Creature (the superclass) 's Update() function

spark basin
#

Oh ok...

stoic kiln
#

in Creature.cs

// Update is called once per frame
    public virtual void Update() {
        // Movement
        if(isGrounded) {
            creatureRB.drag = dragValue;
        } else { creatureRB.drag = 0; }

        // Health
        if(creatureHP <= 0) {
            //Die();
        }
        
        Debug.Log(isGrounded);
    }

in PlayerMovement ```cs
public override void Update() {
// Input
hrzAxis = Input.GetAxisRaw("Horizontal");
vrtAxis = Input.GetAxisRaw("Vertical");
dshAxis = Input.GetAxisRaw("Jump");

    Vector3 moveVec = Vector3.Normalize(new Vector3(hrzAxis, 0, vrtAxis));

    // Move
    if(isGrounded) {
        if(!isDashing) { 
            creatureRB.AddForce(moveVec * playerAccel * Time.deltaTime, ForceMode.VelocityChange);
            if(dshAxis == 1) { dashRoutine(moveVec); }
        }
        if(isDashing) {
            //coroutine go here
        }
    }

    base.Update();
}

IEnumerator dashRoutine(Vector3 dirVec) {
    isDashing = true;
    this.dashVector = dirVec;
    yield return new WaitForSeconds(this.dashTime);
    isDashing = false;
}
spark basin
#

I would say not to use protected "unity" keywords.

dull falcon
#

What functionality is still in Creature after moving all that stuff to components?

spark basin
#

The same could be say like "public int string();"

#

Instead of calling Update() in your Creature class, I would say ForceRefresh(), or UpdateInformation()

dull falcon
#

Tick

spark basin
#

So that you don't confuse you and the compiler which "Update()" method to invoke.

#

Exactly Danny.

stoic kiln
# dull falcon What functionality is still in Creature after moving all that stuff to component...

Creature.cs still has a bunch of useful functions that are useful for the Player class, so

// Collision Methods
    public virtual void OnCollisionStay(Collision collision) {
        if(collision.gameObject.CompareTag("Ground")) {
            isGrounded = true;   
        }
    }

    public virtual void OnCollisionExit(Collision collision) {
        if(collision.gameObject.CompareTag("Ground")) {
            isGrounded = false;
        }
    }

    // Health Management
    public virtual void Die() {
        Destroy(gameObject);
        OnDeath();
    }
    public virtual void OnDeath() {}


    public virtual void ApplyDamage(float damage) { 
        if(!isImmune) { 
            creatureHP -= damage; 
            //immuneTimeRoutine();
        } else {}
    }
    public virtual void ApplyKnockback(Vector3 knockback) { 
        if(!isImmune) {
            creatureRB.AddForce(knockback, ForceMode.Impulse); 
            // coroutine bs immuneTimeRoutine();
        } else {}
    }

    // invulnerability time coroutine
    protected virtual IEnumerator immuneTimeRoutine() {
        isImmune = true;
        yield return new WaitForSeconds(immuneTime);
        isImmune = false;
    }
spark basin
#

You'd run into the same problem for OnCollisionStay and OnCollisionExit.

#

You're competiting against ambiguous keyword.

stoic kiln
#

I'm aware I'm not doing the coroutine stuff correctly yet, just haven't implemented it quite yet

spark basin
#

Or rather, ambiguous method keyword

dull falcon
#

Damage functions to health (or some hitbox) component
Grounding logic to the character controller component

#

Immunity and Knockback would be part of your damage/combat system in some form too

stoic kiln
spark basin
#

Wouldn't Immunity be a tagword for damage block?

#

Same for Knockback?

dull falcon
#

The primary difference is that the input source changes to AI instead of PlayerInput

#

Rest of them are just additional features that the gameobject has

stoic kiln
spark basin
#

They still have Health component and mover component anyway?

#

You wouldn't need to create specific script for specific creature.

dull falcon
#

Flying enemy would probably be swapped character controller (and AI changes)

spark basin
#

You'd just create a rule of what your character should be

dull falcon
#

Shield enemy would probably just react to damage events differently

spark basin
#

It's more of a higher abstraction level of thinking. Can't quite think of it better in Entity Component System?

stoic kiln
#

Yeah, so this is why I was thinking of creating an abstract class Creature; I could just create new functions to override what is needed in Creature, and the rest of it would just be inherited

dull falcon
#

Just inherit from individual components if you need to change how some of the components behave

spark basin
#

I've learned my mistake when I wrote the code too "specific" to a game.

#

It becomes harder to fix/adjust later the year. Quite a pain to troubleshoot and debug.

#

If it's all driven by component based, or rather to say, "Generic" behavior. You can easily adjust the behavior quite easy, without having to worry other things break.

dull falcon
#

Unity already has the component model modelled pretty well. You can install all the packages and throw components all day to a gameobject and at no point will you see Actor, Creature, Entity or some other god class that crosses all those boundaries.

spark basin
#

Sounds like we've become unreal blueprint here ๐Ÿ˜…

stoic kiln
#

Sorry, just trying to wrap my head around this

dull falcon
#

Well they aren't quite that separated

stoic kiln
#

Alright, so my original plan for all this was basically just to have 5 god classes that dictate how things in the game behave
Creature, which would have controlled things like players & NPCs - specifically physics, health, collision and death handling
AIBehavior, which would have been just a general AI controller; things like how far it wants to stay from the player and other NPCs, how often it moves in to attack, etc.
Weapon, which would have contained data like attack speed & damage, launched Projectile prefab, icon and name
Projectile, which would have controlled projectiles; sword slashes, arrows, etc
and Pickup, which would have controlled health/time pickups, as well as dropped weapons

The impression I get from your explanations is that Unity discourages this - in place of Creature, for instance, I should have a bunch of scripts that manage the different aspects it would have controlled; for instance, a DamageSystemManager, a MovementController, etc - but I'm kind of lost on the theory of this

spark basin
#

AIBehaviour should only mimic input feed into your components, such as mover or actions

#

Because then you can have PlayerBehaviour and NetworkBehaviour in case you'd need to get multiplayer going?

stoic kiln
#

yeah that was the idea, it'd just look at the surrounding area and output a desired result to Creature

dull falcon
#

A bit like how Unity comes with Renderer, CharacterController, Transform, Rigidbody, Collider, Animator

stoic kiln
dull falcon
#

Yours. I agree with most of your components, but Creature specifically seems to cover several components

#

Primarily Health and Character Controller

#

And I'm sure it would end up with all the things you didn't think of, since Creature is a type of class that can contain just about anything ๐Ÿ˜„

stoic kiln
#

Basically what I'm taking away from this is everything else is fine, but Creature needs to be broken up into more specific components

spark basin
#

Could Creature not be a scriptable object?

dull falcon
#

Destructible box could just be a health component with some the destructible component listening for health death.

stoic kiln
#

yeah, that's the lesson I'm taking away from this - it would be more efficient as well since it's not calling all the other stuff that deals with AI, movement, etc

#

the one concern I still have is handling the player, since there's some functionality that no other creature implements; UI control, time (as a resource, my game involves a timer feature as one of its primary mechanics), and the player's inventory are the examples I can think of atm

#

but honestly it sounds like I could just make those seperate components and implement them in the player gameobject*

spark basin
#

In this case, a prefab just for the player (Active/current) player. You'd write behaviour that only player can support that AI/Enemy can't.

dull falcon
#

It's fine to have different gameobjects if those gameobjects have different behaviour

spark basin
#

Danny, I've wonder what you'd call them, if it isn't component?

#

Behaviour?

#

Controller?

#

Actor?

dull falcon
#

Well different behaviour in Unity generally means different components

#

Granted some components can behave very differently based on the data they have

spark basin
#

Sounds like a great debate ๐Ÿ˜…

dull falcon
#

Player inventory would just be inventory. Odds are it's not terribly player specific in the end. The UI implementation is the primary difference there

#

In general AI can just simulate those UI and Input actions to do any action the player could do

stoic kiln
#

Another one of my remaining concerns is handling Weapons - the Creature 'class' would have stored a weapon object (the attacks of each enemy prefab would just be their own Weapon) which the PlayerInventory script would have swapped out; Creature's damage handling system would then have called functions through that Weapon instance (creating projectiles, etc.)

dull falcon
#

That would generally be some sort of EquipmentController

#

Manages currently equipped item(s)

#

On equip it spawns the item object to the appropriate place and passes input to the item to do its thing

stoic kiln
#

EquipmentController being the thing that calls functions from Weapon (things like creating projectiles), or would said functions be moved over to EquipmentController?

dull falcon
#

I would have as much as the logic as possible on the item itself

#

It generally just boils down to calling methods like PrimaryUse(), SecondaryUse(), Equip()

stoic kiln
#

I see, and so those would be called in AIBehavior probably

dull falcon
#

Probably would just send input to EquipmentController and have EquipmentController do the item management

spark basin
#

Wouldn't that be define in Input System? ๐Ÿ˜…

stoic kiln
#

I mean, as I see it, AIBehavior is effectively a form of input system? it generates inputs for the objects on the fly based on its environment.

dull falcon
dull falcon
stoic kiln
#

in NPCs it's just the AIBehavior's commands being fed to the movement/weapon system rather than player inputs

dull falcon
#

What items do I have, what gameobjects do I sense, how can I move

#

Obviously you don't have to handle everything, but just figuring out whether your item is ranged or melee is something you probably wanna figure out

stoic kiln
#

yeah, it'd probably just be different configurations of AIBehavior; an archer enemy would keep more distance from the player, change positions more frequently, etc.

#

thank you both for this extremely illuminating discussion!