Greetings, everyone. This is my first forum post and I hope I am in the right place.
For a top down 2D game I’m making, I wanted to implement a grenade which drags enemies to itself. The grenade is instantiated and is deactivated so I don’t have to re-instantiate it over and over again if the player still has grenades they can toss. The script that holds the Grenade information and the script that handles the behaviour of the ability, I also disable. (just in case, as far as I know disabling a game object disables the MonoBehaviour functions of them like Update etc. so this shouldn’t be necessary)
When the player tosses the grenade, I apply a force and a bit of torque to simulate spinning. I check in FixedUpdate
to see if the grenade has left its initial toss state with the bool hasJustBeenTossed
. If the initial tossing phase is over, I apply a counter-force to slow the grenade down a bit in FixedUpdate
before freezing it completely and activating the ability (in my case, I want it to drag enemies towards itself). Here is the code :
void FixedUpdate(){
if(!hasJustBeenTossed)
_rb2D.AddForce(-_rb2D.velocity.normalized * 2f);
}
public IEnumerator TriggerAbilityAfterTime(){
//enabling the script as it is disabled by default
//or after the ability is finished
enabled = true;
//isKinematic is set to true OnEnable
//as the object is parented to the player
//it is set to false here as it detaches from the parent
_rb2D.isKinematic = false;
Toss();
yield return new WaitForSeconds(2f);
TriggerAbility();
}
public void Toss(){
hasJustBeenTossed = true;
_rb2D.AddTorque(0.1f);
_rb2D.AddTorque(25f);
_rb2D.AddForce(_trajectory * _speed, ForceMode2D.Impulse);
StartCoroutine(SetTossedToFalse());
}
public IEnumerator SetTossedToFalse(){
yield return null;
hasJustBeenTossed = false;
}
public void TriggerAbility(){
_rb2D.constraints = RigidbodyConstraints2D.FreezeAll;
_boxCollider2D.enabled = false;
_activationTime = Time.time;
_hasActivated = true;
_suctionAbility.EnableScript();
}
void CheckActivatedLifeTime(){
if(!_hasActivated) return;
if(_activationLifeTime < Time.time - _activationTime){
Reset();
}
}
void Reset(){
print("Reset called");
_suctionAbility.DisableScript();
_hasActivated = false;
hasJustBeenTossed = false;
_rb2D.constraints = RigidbodyConstraints2D.None;
_rb2D.angularVelocity = 0f;
_rb2D.velocity = Vector2.zero;
_rb2D.isKinematic = true;
_boxCollider2D.enabled = false;
transform.parent = _parentTransform;
transform.position = _grenadePosition.position;
gameObject.SetActive(false);
enabled = false;
}
It all works perfectly for the initial toss but not for the subsequent tosses.
My initial toss spins decently. When I logged the angularVelocity
, I got the value of 554.
For the subsequent tosses, however, I don’t see a similar spin.
I logged the angularVelocity
and got the value of 28.
ANY subsequent toss displays the same behaviour.
I also reset the angularVelocity
and velocity
of the RigidBody2D
with Reset()
, which is called when the grenade’s lifetime runs out after its ability activates.
If needed, I could provide a video.