Hi guys and girl, alright so this is my first post here, hope you can help me.
I think im pretty good at digging up scripts and mod them but i really cant figure this one out so i need a little help from the pros (you guys):
Alright below is my turret script, when the player is within a certain distance the turrets “sees” the player and starts shooting, the problem is that it shoots a bullet every update, and i want to control the amount of time between each bullet.
Im a newbie, so i would be very happy, if you help me, to post the script as a whole, and if you find it in your heart, explain what you did to make it work. Ive tried alot of things like yield waitforseconds, but im not doing it right.
Here is my turret code:
var attackRange = 30.0;
var shootAngleDistance = 10.0;
var target : GameObject;
var projectile : Rigidbody;
var speed = 20;
function Update () {
target = FindClosestEnemy();
//counter check if enemy is in range
if (Vector3.Distance(transform.position, target.transform.position) > attackRange)
{
return;
}
else{
// Rotate towards target
var targetPoint = target.transform.position;
var targetRotation = Quaternion.LookRotation (targetPoint - transform.position, Vector3.up);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 5.0);
// If we are almost rotated towards target - fire one clip of ammo
var forward = transform.TransformDirection(Vector3.forward);
var targetDir = target.transform.position - transform.position;
if (Vector3.Angle(forward, targetDir) < shootAngleDistance)
var instantiatedProjectile : Rigidbody = Instantiate(projectile, transform.Find("spawnPoint").transform.position, transform.rotation );
instantiatedProjectile.velocity =
transform.TransformDirection( Vector3( 0, 0, speed ) );
Physics.IgnoreCollision( instantiatedProjectile. collider,
transform.root.collider );
}
}
function FindClosestEnemy (): GameObject {
var moblist : GameObject[];
moblist = GameObject.FindGameObjectsWithTag("Player");
var closest: GameObject;
var distance = Mathf.Infinity;
var position = transform.position;
for (var mobcheck : GameObject in moblist) {
var diff = (mobcheck.transform.position - position);
var curDistance = diff.sqrMagnitude;
if (curDistance < distance) {
closest = mobcheck;
distance = curDistance;
}
}
return closest;
}
Cut out the update loop and use something along the lines of this instead:
function Awake()
{
InvokeRepeating("TryShoot", 0, 0.5);
}
function TryShoot()
{
// Insert the code from your update function here.
}
You will have to modify a bit though, especially since your Slerp rotation won’t work properly when it’s not in Update (i.e. called often). Maybe just throw in a boolean there somewhere?
Here are the docs on invokerepeating.
It’s important that you only call it in Awake (unless you know how to control it), since previous invokes wont be cancelled automatically afaik if you call more of them.
You have some ‘bad’ coding there too, you shouldn’t call FindGameObjectsWithTag so often, but I’m sure you’ll iron out the performance issues later
You probably do not want to have a function that rotates your turret only get called every half second, but having something that continuously instantiates the projectile once the angle is in range is a good idea.
private var firingInterval : float; // member variable of script
// inside the Update function
if (Vector3.Angle(forward, targetDir) < shootAngleDistance firingInterval <= 0)
{
firingInterval = 0.5;
instantiate and prepare projectile
}
if (firingInterval > 0) firingInterval -= Time.deltaTime;
you could probably improve this more, such as making a public interval time that the private firingInterval resets itself to, so you can easily change the timing.
You could also put this in a separate function as a coroutine and do all the firing there, where you could check for the correct angle condition and then use “yield WaitForSeconds(0.5)”
Thanks everyone for your quick and useful answers, means alot to me.
priceap, im trying out your code, i dont get any errors, but i still spits out bullets every frame, i prosume i must have inserted your code in the wrong places, im still in the learning process here, could you help me out?
This how my code looks like with your inserted code:
var attackRange = 30.0;
var shootAngleDistance = 10.0;
var target : GameObject;
var projectile : Rigidbody;
var speed = 20;
private var firingInterval : float;
function Update () {
target = FindClosestEnemy();
//counter check if enemy is in range
if (Vector3.Distance(transform.position, target.transform.position) > attackRange)
{
return;
}
else{
// Rotate towards target
var targetPoint = target.transform.position;
var targetRotation = Quaternion.LookRotation (targetPoint - transform.position, Vector3.up);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 5.0);
// If we are almost rotated towards target - fire one clip of ammo
var forward = transform.TransformDirection(Vector3.forward);
var targetDir = target.transform.position - transform.position;
if (Vector3.Angle(forward, targetDir) < shootAngleDistance firingInterval <= 0)
{
firingInterval = 0.5;
//instantiate and prepare projectile
}
if (firingInterval > 0) firingInterval -= Time.deltaTime;
var instantiatedProjectile : Rigidbody = Instantiate(projectile, transform.Find("spawnPoint").transform.position, transform.rotation );
instantiatedProjectile.velocity =
transform.TransformDirection( Vector3( 0, 0, speed ) );
Physics.IgnoreCollision( instantiatedProjectile. collider,
transform.root.collider );
}
}
function FindClosestEnemy (): GameObject {
var moblist : GameObject[];
moblist = GameObject.FindGameObjectsWithTag("Player");
var closest: GameObject;
var distance = Mathf.Infinity;
var position = transform.position;
for (var mobcheck : GameObject in moblist) {
var diff = (mobcheck.transform.position - position);
var curDistance = diff.sqrMagnitude;
if (curDistance < distance) {
closest = mobcheck;
distance = curDistance;
}
}
return closest;
}
you pasted my suggested code in, but you left your projectile stuff outside of the conditional statement.
that is what I meant when I wrote “instantiate and prepare projectile”
else{
// Rotate towards target
var targetPoint = target.transform.position;
var targetRotation = Quaternion.LookRotation (targetPoint - transform.position, Vector3.up);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 5.0);
// If we are almost rotated towards target - fire one clip of ammo
var forward = transform.TransformDirection(Vector3.forward);
var targetDir = target.transform.position - transform.position;
if (Vector3.Angle(forward, targetDir) < shootAngleDistance firingInterval <= 0)
{
firingInterval = 0.5;
//instantiate and prepare projectile
var instantiatedProjectile : Rigidbody = Instantiate(projectile, transform.Find("spawnPoint").transform.position, transform.rotation );
instantiatedProjectile.velocity =
transform.TransformDirection( Vector3( 0, 0, speed ) );
Physics.IgnoreCollision( instantiatedProjectile. collider,
transform.root.collider );
}
if (firingInterval > 0) firingInterval -= Time.deltaTime;
}