Hi!, I’m trying to recreate some sort of Action JRPG Battle (Sword of Mana, Legend of Zelda: A link to the past), but when I try to make colissions only the first one works, after that one it seems like you have to leave the collision area and re-enter on it for another collision to work…
I’m currently using the “OnTriggerEnter2D” method but is not working correctly.
I have already tried the “OnTriggerExit2D” but it works pretty much the same but inverted…
If I use the method “OnTriggerStay2D” a lot of collisions take place in a single attack, and the objective dies in a single hit.
I have recorded a video to show the actual behavior:
And here’s the code of the Player:
using UnityEngine;
using System.Collections;
public class PlayerControllerV3 : MonoBehaviour
{
Animator anim;
Rigidbody2D rb;
private SpriteRenderer playerRenderer;
bool isAttacking;
bool isWalking;
public BoxCollider2D attackTrigger;
public float attackTriggerSize;
public Vector2 speedVector;
public int life;
public int magic;
private float attackTimer;
public float attackCoolDown;
public float damageAnimDuration;
// Use this for initialization
void Start ()
{
anim = GetComponent<Animator>();
rb = GetComponent<Rigidbody2D>();
playerRenderer = GetComponent<SpriteRenderer>();
anim.SetFloat("x", 1);
attackTrigger.enabled = false;
}
//Update is called once per frame
void Update()
{
// ***PLAYER DIES***
if (life < 1)
{
//Call GameOver
Destroy(gameObject);
}
// *** MOVEMENT ***
float input_x = Input.GetAxisRaw("Horizontal");
float input_y = Input.GetAxisRaw("Vertical");
//if the absolute value of "input_x" OR "input_y" is greater than 0 the player IS walking
if (Mathf.Abs(input_x) + Mathf.Abs(input_y) > 0)
{
isWalking = true;
playerMoves(input_x, input_y);
}
else
{
isWalking = false;
anim.SetBool("isWalking", isWalking);
rb.velocity = new Vector2(0,0);
}
// *** PLAYER ATTACK START ***
if (Input.GetKeyDown("j") && isAttacking == false)
{
playerStartsAttack();
}
// *** PLAYER ATTACK FINISHES ***
if (isAttacking)
{
playerFinishesAttack();
}
}
// Player Moves
void playerMoves(float in_x,float in_y)
{
anim.SetBool("isWalking", isWalking);
//detect direction and normalize
Vector2 movement = new Vector2(in_x,in_y).normalized;
//Add speed
movement.x *= speedVector.x;
movement.y *= speedVector.y;
//Add time-syncronizing with UnityEngine
movement *= Time.deltaTime;
//Add movement speed to the rigidbody
rb.velocity = movement;
//show anims
anim.SetFloat("x", in_x);
anim.SetFloat("y", in_y);
}
// Player Starts Attack
void playerStartsAttack()
{
rb.velocity = new Vector2(0,0);
isAttacking = true;
attackTimer = attackCoolDown;
if(anim.GetFloat("x") < 0) //LEFT
{
attackTrigger.offset = new Vector2( attackTriggerSize*-1 , attackTriggerSize*0 );
attackTrigger.enabled = true;
}
else if(anim.GetFloat("x") > 0) //RIGHT
{
attackTrigger.offset = new Vector2( attackTriggerSize*1 , attackTriggerSize*0 );
attackTrigger.enabled = true;
}
else if(anim.GetFloat("y") > 0) //UP
{
attackTrigger.offset = new Vector2( attackTriggerSize*0 , attackTriggerSize*1 );
attackTrigger.enabled = true;
}
else if(anim.GetFloat("y") < 0) //DOWN
{
attackTrigger.offset = new Vector2( attackTriggerSize*0 , attackTriggerSize*-1 );
attackTrigger.enabled = true;
}
}
// Player Ends Attack
void playerFinishesAttack()
{
if (isAttacking)
{
if(attackTimer > 0)
{
rb.velocity = new Vector2(0, 0);
attackTimer -= Time.deltaTime;
}
else //attack has ended
{
isAttacking = false;
attackTrigger.enabled = false;
}
}
anim.SetBool("isAttacking",isAttacking);
}
// Player receives damage
IEnumerator playerDamage(int damage)
{
life -= damage;
playerRenderer.color = new Color (255,0,0,255);
yield return new WaitForSeconds(damageAnimDuration);
playerRenderer.color = new Color(255, 255, 255, 255);
yield break;
}
}
using UnityEngine;
using System.Collections;
public class PlayerAttackTrigger : MonoBehaviour
{
public int damage = 20;
void OnTriggerEnter2D(Collider2D col)
{
if (col.isTrigger != true && col.CompareTag("Enemy"))
{
col.SendMessageUpwards("enemyDamage", damage);
}
}
}
Any ideas?
Can anyone help me?, thanks in advance.