问题
I am working on a simple 2D platformer game in which i have made an knockback effect. When the player gets hit by an obstacle, which currently is just a spike, he has a knockback and temporary invicibility, so when standing on spike during the invicibility he dosen't get hit. However, once the invicibility ends, i want to have player get hit by a spike like in the following GIF.
https://media.giphy.com/media/26FeVTRop5PhBrJQs/giphy.gif
The player gets hit because the invicibility is gone and it is standing on the spike. The problem I have is, if the invicibility ends and the player is still standing on the spike, it dosen't get hit and it cannot be hurt untill it gets off the spikes. Can you suggest how i solve this problem? Here is my code for hiting the player.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HitThePlayer : MonoBehaviour
{
public int damage;
GameObject player;
PlayerController playerController;
PlayerMovement playerMovement;
void Start ()
{
player = GameObject.FindGameObjectWithTag ("Player");
playerController = GameObject.FindGameObjectWithTag ("GameController").GetComponent<PlayerController>();
playerMovement = player.GetComponent<PlayerMovement> ();
}
void OnTriggerEnter2D (Collider2D other)
{
if (!playerController.isInvicible)
{
if (other.gameObject.CompareTag ("Player"))
{
playerController.AddPlayerHealth (-damage);
playerMovement.isKnockedBacked = true;
if (other.transform.position.x < transform.position.x)
{
playerMovement.knockFromRight = true;
}
else
{
playerMovement.knockFromRight = false;
}
StartCoroutine ("KnockBackEffectsDuration");
}
}
}
IEnumerator KnockBackEffectsDuration ()
{
player.GetComponent<Animator> ().SetTrigger ("GotHurt");
StartCoroutine (playerController.Invicibility (3.0f));
yield return new WaitForSeconds (0.2f);
playerMovement.isKnockedBacked = false;
playerMovement.enabled = false;
yield return new WaitForSeconds (0.2f);
playerMovement.enabled = true;
}
}
Also, here is the Invicibility IEnumerator that is in another script.
public IEnumerator Invicibility (float duration)
{
isInvicible = true;
yield return new WaitForSeconds (duration);
isInvicible = false;
player.GetComponent<Animator> ().SetTrigger ("GoIdle");
}
HitThePlayer script references other scripts, so if you need me to bring up those scripts aswell, let me know.
回答1:
The problem is that after the spike trigger is entered and the player is damaged, when the invincibility wears off, your player has already entered the spike trigger and therefore this method is not being called again. One way to solve this would be instead of having the OnTriggerEnter directly damaging the player, you should instead use OnTriggerEnter and OnTriggerExit to set a bool for whether or not the player can be damaged. For example:
bool damageable;
void Update()
{
if (!playerController.isInvicible && damageable)
{
// damage, knockback, etc the player here;
}
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag ("Player"))
damageable = true;
}
void OnTriggerExit2D(Collider2D other)
{
if (other.gameObject.CompareTag ("Player"))
damageable = false; // player is still damageable unless he leaves spikes
}
回答2:
It looks like you probably aren't checking for a collision with the spikes when invincibility ends, though there isn't enough code posted to be sure. Make sure you are calling the OnTriggerEnter2D function when invincibility ends.
来源:https://stackoverflow.com/questions/47338177/getting-hit-after-invicibility-when-standing-on-trap