How to make a turret with OnTriggerEnter
Hi there! I've just started coding and i'm trying to make a dungeon-like game. I wanted to make a trap that when the player enters a trigger, an arrow is fired at him. I don't want to use any AI, just a arrow firing straight forward. I already made the sprite and have tried using Instantiate, but i don't really know the syntax. Thx! The only code i have is a projectile script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Projectile : MonoBehaviour
{
Rigidbody2D rigidbody2d;
public float projectileDistance;
void Awake()
{
rigidbody2d = GetComponent<Rigidbody2D>();
}
void Update() {
if(transform.position.magnitude > projectileDistance){
Destroy(gameObject);
}
}
public void Launch(Vector2 direction, float force){
rigidbody2d.AddForce(direction * force);
}
void OnCollisionEnter2D(Collision2D other) {
Debug.Log("projectile collision with " + other.gameObject);
Destroy(gameObject);
}
}
Answer by streeetwalker · Oct 01, 2020 at 04:16 AM
You just need to call Launch from within an OnTriggerEnter event handling function in script that is a component of your trap object.
Assuming "straight forward" is your projectile's +x axis, use Vector3.forward for the direction parameter of your launch script.
To call Launch, your trap script will need a reference to the projectile script - it's not clear if you are spawning the projectile dynamically or it already exists in your scene. Either way you need a variable that references the projectile to be able to call Launch
This bit of code has some problems:
void Update() {
if(transform.position.magnitude > projectileDistance){
Destroy(gameObject);
}
First, you are dealing with a Rigidbody so it is better to use FixedUpdate; and also rigidbody2d.position instead of transform.position. It is better to do that in FixedUpdate because the rigidbody motion is calculated by the physics engine, and Update may not be in sync with the engine timing. While it is OK in your circumstance to use transform.position to get the position of something, I'd use the rigidbody instead just as a matter a habit. If you are using rigidbody motion, it is very important not to set transform.position.
Secondly and most important: position.magnitude
is not meaningful - it only means something if starting position of your projectile is (0,0) You need to get the distance traveled from it's starting position. So (current position - start position).magnitude
Lastly, as a matter of practice getting the magnitude is an expensive operation: better to use sqrMagnitude and compare it with the square of your projectileDistance - precompute the square of projectileDistance when your game starts and store it in a variable to use in the comparison.
Thx! I want to spawn a prefab of an arrow, I don't need to use instantiate or something like that besides calling Launch?
If the arrow is not already in the scene, you have to use Instantiate the prefab to "spawn" it. That is usually what is meant by spawning an object - to create an object. You have to do that using Instantiate before you can call a function on a script component of the object.