I drew a little red animation thing for when my player gets hit. I have an arrow shooter in my level but my problem is the red damage effect instantiates where my player is at, but when my player moves the object stays in the player's old position. Like lets say my player is at x:10. The effect will spawn at x:10 but when I move to x:17 the effect will stay at x:10.
Here's my code
public int damagedealt;
public Player playerscript;
public GameObject RedDamage;
public Vector2 playerpos;
public GameObject player;
// Start is called before the first frame update
void Start()
{
playerscript = FindObjectOfType<Player>();
}
// Update is called once per frame
void Update()
{
playerpos = player.transform.position;
player = GameObject.FindGameObjectWithTag("Player");
transform.Translate(Vector2.right * speed * Time.deltaTime);
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Player"))
{
playerscript.health -= damagedealt;
Instantiate(RedDamage, playerpos, transform.rotation);
Destroy(gameObject);
}
}
and if it's useful at all here's the damage effect script
{
public float duration;
// Start is called before the first frame update
void Start()
{
duration = .7f;
}
// Update is called once per frame
void Update()
{
duration -= Time.deltaTime;
if (duration <= .13f )
{
Destroy(gameObject);
}
}
}
You can either add a follow script to the object you would like to follow your player or you can child the object to the player. When an object is childed to another, its transform becomes relative to its parent. In your case, your instantiated object would move relative to your player.
As this seems like a temporary effect that is repeated multiple times, it might make sense to child an empty object for the sole purpose of spawning your effect there. Create an empty gameObject that is childed (meaning placed under in the scene hierarchy) to your player object. Make sure to set the position of this new empty object in a place where you would like to spawn your object.
Once you are happy with where the object is placed, you can alter your Instantiate
slightly to fit the new approach.Instantiate
has a few overloads to the method. The one I will use is as follows
public static Object Instantiate(Object original, Transform parent);
Instead of specifying a rotation, position, etc, you will specify the parent at which the object will be placed and childed to. Here is what the script would now look like
public int damagedealt;
public Player playerscript;
public GameObject RedDamage;
public Vector2 playerpos;
public GameObject player;
// serializing a field will expose it in the editor even if marked private
// while not allowing other scripts to access it
[SerializeField] private Transform DisplayDamageFeedback = null;
// Start is called before the first frame update
void Start()
{
playerscript = FindObjectOfType<Player>();
}
// Update is called once per frame
void Update()
{
playerpos = player.transform.position;
player = GameObject.FindGameObjectWithTag("Player");
transform.Translate(Vector2.right * speed * Time.deltaTime);
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Player"))
{
playerscript.health -= damagedealt;
Instantiate(RedDamage, DisplayDamageFeedback);
Destroy(gameObject);
}
}
Make sure to assign the reference to DamageFeedback
in the inspector to the empty gameObject you created earlier. If you need help on any of the steps just let me know.