|
Post by Strider on Apr 20, 2021 6:18:24 GMT
So, i was wondering, how can i trigger an attack while underwater?
i guess it could be kind of easy, but i'm not sure how to implement it.
Thanks in advance.
|
|
|
Post by Invector on Apr 20, 2021 13:52:44 GMT
Basically, you need a new parameter on your animator to use as a condition to trigger an underwater attack instead of regular attacks
|
|
|
Post by kingceryn on Apr 21, 2021 6:04:16 GMT
So, i was wondering, how can i trigger an attack while underwater? i guess it could be kind of easy, but i'm not sure how to implement it. Thanks in advance. I use a "vInvectorExtras" script with the same Namespace, to reference the Swimming system. Basically just plays an "Underwater Attack" in the animator, without using the vThirdPersonMotor or vInput scripts. Just copy past the WeakAttack statemachine and make a SwimAttack one. Could also mimic the regular attack triggers, and just use the vSwimming Events to toggle a script bool like "CanAttackunderWater" true/false, and just add an animation trigger. Same steps, slight difference.
|
|
|
Post by Strider on Apr 21, 2021 23:27:10 GMT
So, i was wondering, how can i trigger an attack while underwater? i guess it could be kind of easy, but i'm not sure how to implement it. Thanks in advance. I use a "vInvectorExtras" script with the same Namespace, to reference the Swimming system. Basically just plays an "Underwater Attack" in the animator, without using the vThirdPersonMotor or vInput scripts. Just copy past the WeakAttack statemachine and make a SwimAttack one. Could also mimic the regular attack triggers, and just use the vSwimming Events to toggle a script bool like "CanAttackunderWater" true/false, and just add an animation trigger. Same steps, slight difference. i'm not sure i understand... but i'll give it a try... i think i got it now!
|
|
|
Post by Strider on Apr 22, 2021 0:45:59 GMT
i almost got it, but something is still wrong: i added a new input into the vswimming.cs [Tooltip("Input to attack")]
public GenericInput swimAttackInput = new GenericInput("RightShift", "X", "X");then added a void: private void SwimmingBehaviour()
{
// trigger swim behaviour only if the water level matches the player height + offset
if (tpInput.cc._capsuleCollider.bounds.center.y + heightOffset < waterHeightLevel)
{
if (tpInput.cc.currentHealth > 0)
{
if (!triggerSwimState) EnterSwimState(); // call once the swim behaviour
SwimUpOrDownInput(); // input to swin up or down
AttackUnderwaterInput(); // input to to attack underwater
tpInput.SetStrafeLocomotion(false); // limit the player to not go on strafe mode
tpInput.MoveInput(); // update the input
tpInput.cc.SetAnimatorMoveSpeed(tpInput.cc.freeSpeed); // update the animator input magnitude
}
else
ExitSwimState(); // use the trigger around the edges to exit by playing an animation
}
else
ExitSwimState();
}
private void AttackUnderwaterInput()
{
if (swimAttackInput.GetButton())
{
/*var vel = tpInput.cc._rigidbody.velocity;
vel.y = -swimDownSpeed;
tpInput.cc._rigidbody.velocity = vel;*/
tpInput.cc.animator.SetInteger(vAnimatorParameters.ActionState, 5);
}
}and created the anim file and state for the attack, but the problem is, it works, but after the attack, i can't move, just go up or down, but i can't move to the sides no more.
|
|
|
Post by kingceryn on Apr 22, 2021 5:09:32 GMT
You might need to have the Swim attack states in the same substate as the Swimming animations, so it can transition back.
Also I tend to keep it as simple as possible, so I try not to modify the actual vSwimming script, I just grab the bools and conditions to tell my "vExtras" script whats going on with the Invector stuff.
So I'll literally just have an input, check if underwater, and then manually play an animation via script on the animator- this.Animator.Play("SwimAttackAnimationName"); -then just have it transition back to the swimming animations, so as far as the Invector side is concerned, it just interrupted to play an animation, and then resume swimming
|
|
|
Post by Strider on Apr 22, 2021 18:17:52 GMT
I think is working now, my attack anim had an animator tag with lock movement and lock rotation, if i erase the lock movement, it works fine.
|
|
|
Post by justsomedev on May 10, 2023 22:01:52 GMT
Hey guys, so I was able to successfully implement an attack underwater but the issue I ran into is that the character's swim speed decreases dramatically after attacking. When the character exits the water and re-enters, the swim speed is then rest. I was thinking of resetting the swim speed when the attack is performed, I haven't tried it yet but will shortly. Wanted to post to see if there was a better alternative to the fixing the decrease in speed. I attached the lock movement speed advanced tag to the individual attack states within the state machine in the animator similar to Strider's post.
The input variable:
[Tooltip("Input to make the character Attack Underwater")]
public GenericInput UnderwaterAttackWeak = new GenericInput("Mouse0", "RB", "RB");
then the void:
protected virtual void SwimmingBehaviour()
{
if (water)
{
waterHeightLevel = water.transform.position.y;
curretCharacterDepth = -(characterCenter.y - waterHeightLevel);
isUnderWater = curretCharacterDepth > 0.5f;
isSwimming = isSwimming ? curretCharacterDepth >= -0.2f : curretCharacterDepth >= 0;
}
// trigger swim behaviour only if the water level matches the player height + offset
if (isSwimming)
{
if (tpInput.cc.currentHealth > 0)
{
if (!triggerSwimState)
{
EnterSwimState(); // call once the swim behaviour
}
SwimUpOrDownInput(); // input to swin up or down
tpInput.SetStrafeLocomotion(false); // limit the player to not go on strafe mode
tpInput.MoveInput(); // update the input
tpInput.cc.SetAnimatorMoveSpeed(tpInput.cc.freeSpeed); // update the animator input magnitude
WeakAttackUnderwater(); // input for weak attack underwater
}
//else
//{
// ExitSwimState(); // use the trigger around the edges to exit by playing an animation
//} }
else
{
ExitSwimState();
}
}
//Underwater Attack Weak Input
protected virtual void WeakAttackUnderwater()
{
if (UnderwaterAttackWeak.GetButtonDown())
{
TriggerWeakAttackUnderwater();
}
}
protected virtual void TriggerWeakAttackUnderwater()
{
//tpInput.cc.animator.SetInteger(vAnimatorParameters.AttackID, AttackID);
tpInput.cc.animator.SetTrigger(vAnimatorParameters.UnderwaterWeakAttack);
}
|
|
|
Post by justsomedev on May 11, 2023 3:17:43 GMT
Never mind I solved the issue. Was an easy fix.
|
|