Post by komposite on Sept 23, 2020 23:02:44 GMT
Hi !
I'm trying to find a way to snap my character to the enemy position when attacking, meaning that, when I press an attack button, my character will "snap" (move to) the enemy position (or close to)
This will help adding a bit more of punch (no pun intended) during the fight.
So far, what I've done, is shooting a raycast OnStateEnter of the vMeleeAttackControl (the raycast is shoot on the forward of the character) to get the position of the enemy.
So far, what I've done, is shooting a raycast OnStateEnter of the vMeleeAttackControl (the raycast is shoot on the forward of the character) to get the position of the enemy.
Everything working fine on this part.
But I cannot make my character move toward the target, after trying different method of all kind
Note that I'm setting the rigidbody to is kinematic from the beginning of the state 'till the end of the animation (I was thinking it might help in some way, but... meh)
Anyway, any help is appreciated here
(I'm on 2.5.2)
Here is the modifications I've made :
using System.Collections.Generic;
using UnityEngine;
namespace Invector.vMelee
{
using vEventSystems;
public class vMeleeAttackControl : StateMachineBehaviour
{
[Tooltip("normalizedTime of Active Damage")]
public float startDamage = 0.05f;
[Tooltip("normalizedTime of Disable Damage")]
public float endDamage = 0.9f;
public int damageMultiplier;
public int recoilID;
public int reactionID;
public vAttackType meleeAttackType = vAttackType.Unarmed;
[Tooltip("You can use a name as reference to trigger a custom HitDamageParticle")]
public string damageType;
[HideInInspector]
[Header("This work with vMeleeManager to active vMeleeAttackObject from bodyPart and id")]
public List<string> bodyParts = new List<string> { "RightLowerArm" };
public bool ignoreDefense;
public bool activeRagdoll;
[vHideInInspector("activeRagdoll"), Tooltip("Time to keep Ragdoll active")]
public float senselessTime;
[Tooltip("Check true in the last attack of your combo to reset the triggers")]
public bool resetAttackTrigger;
private bool isActive;
public bool debug;
private vIAttackListener mFighter;
private bool isAttacking;
[Header("Snap Options")]
public bool useSnapping = true;
public LayerMask layerMask;
public float rayDistance;
private bool hasTouchedEnemy;
private RaycastHit hit;
private float positionX;
private Rigidbody rb;
private Transform playerTransform;
override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
mFighter = animator.GetComponent<vIAttackListener>();
rb = animator.GetComponent<Rigidbody>();
playerTransform = rb.transform;
if (debug) Debug.Log("rb is " + rb);
isAttacking = true;
if (useSnapping)
{
if (Physics.Raycast(new Vector3(animator.transform.position.x, 1, animator.transform.position.z), animator.transform.TransformDirection(Vector3.forward), out hit, rayDistance, layerMask))
{
hasTouchedEnemy = true;
if (debug)
{
Debug.Log("I've touched " + hit.transform.name);
Debug.DrawRay(new Vector3(animator.transform.position.x, 1, animator.transform.position.z), animator.transform.TransformDirection(Vector3.forward) * rayDistance, Color.cyan, 3f);
}
}
else
{
hasTouchedEnemy = false;
if (debug) Debug.Log("I didn't touch something");
}
}
if (mFighter != null)
mFighter.OnEnableAttack();
if (debug)
Debug.Log("Enter " + damageType);
}
override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
if (stateInfo.normalizedTime % 1 >= startDamage && stateInfo.normalizedTime % 1 <= endDamage && !isActive)
{
if (debug) Debug.Log(animator.name + " attack " + damageType + " enable damage in " + System.Math.Round(stateInfo.normalizedTime % 1, 2));
isActive = true;
ActiveDamage(animator, true);
if (hasTouchedEnemy)
{
rb.isKinematic = true;
positionX = playerTransform.position.x;
float timer = 0;
while (timer < 1f)
{
timer += Time.deltaTime;
// I WAS PLANNING ON MOVING THE CHARA HERE
if (debug) Debug.Log("I'm moving to " + hit.transform.name + " at position " + hit.transform.position.x);
}
}
}
else if (stateInfo.normalizedTime % 1 > endDamage && isActive)
{
if (debug) Debug.Log(animator.name + " attack " + damageType + " disable damage in " + System.Math.Round(stateInfo.normalizedTime % 1, 2));
isActive = false;
ActiveDamage(animator, false);
}
if (stateInfo.normalizedTime % 1 > endDamage && isAttacking)
{
isAttacking = false;
if (mFighter != null)
mFighter.OnDisableAttack();
}
//if (stateInfo.normalizedTime % 1 > allowRotationAt && isAttacking)
//{
// isAttacking = false;
// if (mFighter != null)
// mFighter.OnDisableAttack();
//}
}
override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
if (debug)
Debug.Log("Exit " + damageType);
if (useSnapping) rb.isKinematic = false;
if (isActive)
{
isActive = false;
ActiveDamage(animator, false);
}
if (isAttacking)
{
isAttacking = false;
if (mFighter != null)
mFighter.OnDisableAttack();
}
if (mFighter != null && resetAttackTrigger)
mFighter.ResetAttackTriggers();
if (debug) Debug.Log(animator.name + " attack " + damageType + " stateExit");
}
void ActiveDamage(Animator animator, bool value)
{
var meleeManager = animator.GetComponent<vMeleeManager>();
if (meleeManager)
meleeManager.SetActiveAttack(bodyParts, meleeAttackType, value, damageMultiplier, recoilID, reactionID, ignoreDefense, activeRagdoll, senselessTime, damageType);
}
}
}