#Multiple scripts in one object
1 messages ยท Page 1 of 1 (latest)
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
Oh ok...
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;
}
I would say not to use protected "unity" keywords.
What functionality is still in Creature after moving all that stuff to components?
The same could be say like "public int string();"
Instead of calling Update() in your Creature class, I would say ForceRefresh(), or UpdateInformation()
Tick
So that you don't confuse you and the compiler which "Update()" method to invoke.
Exactly Danny.
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;
}
You'd run into the same problem for OnCollisionStay and OnCollisionExit.
You're competiting against ambiguous keyword.
I'm aware I'm not doing the coroutine stuff correctly yet, just haven't implemented it quite yet
Or rather, ambiguous method keyword
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
The thought behind this was that I could extend Creature in other scripts, like enemy ai/etc - should I break up the functions and just have a DamageManager script, etc. as opposed to trying to do it all in one?
I find that in a lot of cases the scripts don't really need to be special for AI
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
My bad, I think I articulated it wrong
What I'm saying is I'd have scripts like FlyingEnemy & ShieldEnemy which would also implement Creature
They still have Health component and mover component anyway?
You wouldn't need to create specific script for specific creature.
Flying enemy would probably be swapped character controller (and AI changes)
You'd just create a rule of what your character should be
Shield enemy would probably just react to damage events differently
It's more of a higher abstraction level of thinking. Can't quite think of it better in Entity Component System?
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
Just inherit from individual components if you need to change how some of the components behave
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.
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.
Sounds like we've become unreal blueprint here ๐
Sorry, just trying to wrap my head around this
Well they aren't quite that separated
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
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?
yeah that was the idea, it'd just look at the surrounding area and output a desired result to Creature
Not doing multiplayer, actually
A bit like how Unity comes with Renderer, CharacterController, Transform, Rigidbody, Collider, Animator
referring to MegaMind's comment, mine or something else*? because that was the way I was thinking about my plan originally, although again I'm not sure what to do
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 ๐
Yeah, I was planning on implementing destructible crates & such as Creatures with a 'blank' AIBehavior
Basically what I'm taking away from this is everything else is fine, but Creature needs to be broken up into more specific components
Could Creature not be a scriptable object?
Destructible box could just be a health component with some the destructible component listening for health death.
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*
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.
It's fine to have different gameobjects if those gameobjects have different behaviour
Danny, I've wonder what you'd call them, if it isn't component?
Behaviour?
Controller?
Actor?
Well different behaviour in Unity generally means different components
Granted some components can behave very differently based on the data they have
Sounds like a great debate ๐
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
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.)
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
EquipmentController being the thing that calls functions from Weapon (things like creating projectiles), or would said functions be moved over to EquipmentController?
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()
I see, and so those would be called in AIBehavior probably
Probably would just send input to EquipmentController and have EquipmentController do the item management
Wouldn't that be define in Input System? ๐
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.
Probably, but right now I just pull the input from it and send it to components myself
Yup. It fetches bunch of data from the object it's controlling and does decisions based on it
in NPCs it's just the AIBehavior's commands being fed to the movement/weapon system rather than player inputs