Weapon range/damage with a projectile
Currently I have a GunBaseClass that my projectile weapons inherit from. However, I am wondering how I can set the range of a gun on the gun itself instead of the projectile. Currently the projectile has a rigidbody with a velocity, and will destroy itself after x amount of time, so to set the range I have to fiddle with these numbers. Also, the same goes for weapon damage... this again has to be set on the projectile (and so the projectile has to inherit from the GunBaseClass).
I want it so that my projectile is simply an object that hits the enemy, but has no stats of its own, as all of these should be on the weapon, and so that the projectile doesn't need to inherit from the GunBaseClass. How could I do this? Thanks in advance for the help! I'll update on here if I fix the issue
Gun Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ProjectileGun : GunBaseClass {
public Transform muzzleTip;
public Light muzzleFlashLight;
private float lastShot = 0.0f;
void Update()
{
if (JoystickFire.instance.Fire && Time.time > fireRate + lastShot) {
Shoot ();
muzzleFlashLight.enabled = true;
}
else
{
muzzleFlashLight.enabled = false;
}
}
void Shoot()
{
GameObject bullet = ObjectPooler.SharedInstance.GetPooledObject ("Player Bullet");
if (bullet != null)
{
bullet.transform.position = muzzleTip.position;
bullet.transform.rotation = transform.rotation;
bullet.SetActive (true);
Debug.Log("Shot Fired");
}
lastShot = Time.time;
}
}
Projectile Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Projectile : ProjectileGun { //gunDamage needs fixing as it currently has to be set on the projectile, not the gun
public float timer = 0.5f; //range = speed * timer (**Set in inspector**)
public float speed = 60f; //range = speed * timer (**Set in inspector**)
void OnEnable()
{
Invoke ("Die", timer);
}
void Update()
{
transform.position += transform.forward * speed * Time.deltaTime;
}
void OnBecameInvisible ()
{
gameObject.SetActive (false);
}
void OnCollisionEnter(Collision enemy)
{
if (enemy.gameObject.tag == "Enemy")
{
EnemyBaseClass sn = enemy.gameObject.GetComponent<EnemyBaseClass> ();
sn.enemyCurrentHealth -= Random.Range (minGunDamage, maxGunDamage) /*- sn.enemyArmorRating*/;
Debug.Log ("Enemy Current Health: " + sn.enemyCurrentHealth);
gameObject.SetActive (false);
}
}
void Die()
{
gameObject.SetActive(false);
}
}
Answer by alankemp · May 15, 2017 at 03:46 PM
You could move the timer and speed public variables from the projectile to the gun class so you can set them there in Unity.
Add an initialization function in your projectile class that takes the time to live and speed as parameters and saves them into private variables in the projectile class.
When you spawn the bullet, call the initialization function passing the timer and speed values.
As an aside,
class Projectile : ProjectileGun
This is a bit strange, why are your projectiles derived from your guns? You should inherit from a class when the new class is a more specialized type of the base class.
Thanks for the reply, but I'm not too sure on how to initialize variable in another script using a method. I don't expect the code written for me, but what is this called so I can give it a search?
Also, the whole reason I asked the question is because I didn't like the fact that my projectile class was having to inherit from the Projectile Gun just so I could apply the same variables :)
You could change your projectile class to derive from $$anonymous$$onoBehaviour like this:
class Projectile : $$anonymous$$onoBehaviour
$$anonymous$$ove the public speed and timer variables from the projectile class to the gun class.
Then add two private variables to the projectile class and write a new function in the projectile class to initialise it:
private float $$anonymous$$yTimer;
private float $$anonymous$$ySpeed;
void Initialize(float timer, float speed)
{
$$anonymous$$yTimer = timer;
$$anonymous$$ySpeed = speed;
}
In your gun class shoot function, inside the if (bullet != null), you can call this new function:
if (bullet != null)
{
bullet.Initialize(timer, speed);
bullet.transform.position = muzzleTip.position;
bullet.transform.rotation = transform.rotation;
bullet.SetActive (true);
Debug.Log("Shot Fired");
}
You will need to change the places in the projectile script that use the old variable names to use these new ones ($$anonymous$$yTimer and $$anonymous$$ySpeed), or rename them to something else that makes sense to you.
Now you have the speed and the timer in the gun class where it belong, and each new projectile you create will get told those values.