Search Unity

Getting weaponDamage to apply to projectile

Discussion in 'Scripting' started by derekmklinger, Sep 25, 2018.

  1. derekmklinger

    derekmklinger

    Joined:
    Jul 20, 2018
    Posts:
    3
    Hello! Just a heads up, this is my first post, my first big gaming project, and I'm still relatively new to scripting. I have been stuck on this for a couple weeks now, and I feel like it's something simple I'm over looking. I'm trying to make a weapon system where the weapon and the projectile each have their own damage values that work together. I got the projectile damaging players with it's own damage value, but I can't get the ProjectileSettings script to pull the weaponDamage value from the RangedWeaponSettings script in order for the two to add and work together.

    I've tried so many different variants of code and locations to place the text, but line 59. in the ProjectileSettings script is the one I'm having troubles with (The code I left in there always comes back with the error "NullReferenceException: Object reference not set to an instance of an object" because the weaponDamage isn't being applied the way I'm doing it, but I can't figure out why). Any help would be much appreciated!

    Thank you!



    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityStandardAssets.CrossPlatformInput;
    5.  
    6. public class RangedWeaponSettings : MonoBehaviour
    7. {
    8.     public Transform Bullet;
    9.     public Transform Spawn;
    10.  
    11.     public int TotalProjectiles = 30;
    12.     public int CurrentProjectiles;
    13.     public float shootForce = 1000f;
    14.     public int weaponDamage = 10;
    15.  
    16.     bool isShooting = false;
    17.     float camDis;
    18.  
    19.     ProjectileSettings projectile;
    20.  
    21.     // Use this for initialization
    22.     void Start()
    23.     {
    24.         CurrentProjectiles = TotalProjectiles;
    25.         projectile = GetComponent<ProjectileSettings>();
    26.     }
    27.  
    28.  
    29.     // Update is called once per frame
    30.     void Update()
    31.     {
    32.         ShootRequest();
    33.     }
    34.  
    35.     void FixedUpdate()
    36.     {
    37.         Shoot();
    38.     }
    39.  
    40.  
    41.  
    42.  
    43.     void ShootRequest()
    44.     {
    45.         camDis = Camera.main.transform.position.y - Spawn.position.y; //setting camera distance
    46.  
    47.         Vector3 aimPos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, camDis)); //setting aim position
    48.  
    49.         if (CrossPlatformInputManager.GetButtonUp("Fire1")) //cross platform attack input
    50.         {
    51.             isShooting = true;
    52.         }
    53.  
    54.     }
    55.  
    56.  
    57.  
    58.     void Shoot()
    59.     {
    60.         if (isShooting && CurrentProjectiles > 0) //spawns projectiles if ammo is above 0 and the cross platform attack input was triggered
    61.         {
    62.             Vector3 aimPos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, camDis)); //fires projectile towards mouse position
    63.  
    64.             var pel = Instantiate(Bullet, Spawn.position, Spawn.rotation); //spawns projectile
    65.             pel.GetComponent<Rigidbody2D>().AddForce(new Vector2(aimPos.x - Spawn.position.x, aimPos.y - Spawn.position.y).normalized * shootForce); //projectile force added
    66.  
    67.             CurrentProjectiles -= 1;
    68.             isShooting = false;
    69.         }
    70.     }
    71. }


    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class ProjectileSettings : MonoBehaviour
    6. {
    7.     public int projectileDamage = 5;
    8.     public int totalDamage;
    9.     public float decayTimer = 2f;
    10.     private Vector3 dir = new Vector3();
    11.  
    12.     Rigidbody2D rigidBody;
    13.     CapsuleCollider2D capsule;
    14.     RangedWeaponSettings weapon;
    15.  
    16.  
    17.  
    18.  
    19.  
    20.     // Use this for initialization
    21.     void Start()
    22.     {
    23.         rigidBody = GetComponent<Rigidbody2D>();
    24.         capsule = GetComponent<CapsuleCollider2D>();
    25.         weapon = GetComponent<RangedWeaponSettings>();
    26.     }
    27.  
    28.  
    29.  
    30.  
    31.  
    32.     // Update is called once per frame
    33.     void Update()
    34.     {
    35.         if (rigidBody) //When the rigidbody2D is still present, the projectile flies in the direction of its velocity
    36.         {
    37.             Direction();
    38.         }
    39.     }
    40.  
    41.  
    42.  
    43.  
    44.  
    45.     void Direction() //keeps projectile pointing in direction of velocity
    46.     {
    47.         Vector2 dir = rigidBody.velocity;
    48.         float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
    49.         transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
    50.     }
    51.  
    52.     void OnCollisionEnter2D(Collision2D collision) //function for when the projectile collides with something
    53.     {
    54.         var hit = collision.gameObject;
    55.         var currentHealth = hit.GetComponent<PlayerHealth>(); //finds currentHealth if the gameobject the projectile hits has the PlayerHealth script on it
    56.        
    57.         if (currentHealth != null) //if player still has health above 0
    58.         {
    59.             totalDamage = (weapon.weaponDamage + projectileDamage); //can't get this to work
    60.             currentHealth.TakeDamage(totalDamage);
    61.         }
    62.  
    63.         Destroy(rigidBody);
    64.         Destroy(capsule);
    65.         StartCoroutine(Decay());
    66.     }
    67.  
    68.     IEnumerator Decay() //CoRoutine allows WaitForSeconds feature for projectile decay
    69.     {
    70.         yield return new WaitForSeconds(decayTimer);
    71.         Destroy(gameObject);
    72.     }
    73. }
     
  2. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    From what I see. Line 25 in projectilesettings is failing. And that’s why you always get a null ref.

    I would assume that the weaponrangedsettings script is not attached to the projectilesettings GameObject.
    So it’s your job to tell line 25 where the script is located. Right now you are telling it that is located on itself.
     
    derekmklinger likes this.
  3. derekmklinger

    derekmklinger

    Joined:
    Jul 20, 2018
    Posts:
    3
    That makes sense, thank you for the response! I'll start looking into that. Currently the system is set up where the Weapon Prefab has a child called Spawner. This is the location where the Projectile Prefabs (public Transform bullet) spawn from. The weapon and the projectile do not have any other connection aside from Weapon prefab instantiates Bullet prefab (the projectile is not a child of the weapon).

    I may need to figure out a different system entirely because I want this to be a multiplayer shooter eventually (I know that I have a lot of fixing to do already), but I don't want the projectiles pulling values from all Weapon prefabs.
     
  4. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    Ok, so you have totalDamage variable. I would create another variable called "weaponDamage", but set it to private
    line 59 would then look like
    totalDamage = (weaponDamage + projectileDamage);

    then you need a new function
    here is the code
    Code (CSharp):
    1. private int weaponDamage;
    2.    
    3.     public void SetWeaponDamage(int setTo)
    4.     {
    5.         weaponDamage = setTo;
    6.     }
    then in the spawning section change it up a bit
    Code (CSharp):
    1. void Shoot()
    2.     {
    3.         if (isShooting && CurrentProjectiles > 0) //spawns projectiles if ammo is above 0 and the cross platform attack input was triggered
    4.         {
    5.             Vector3 aimPos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, camDis)); //fires projectile towards mouse position
    6.             GameObject pel = (GameObject)Instantiate(Bullet, Spawn.position, Spawn.rotation); //spawns projectile
    7.             pel.SetWeaponDamage(weaponDamage);
    8.             pel.GetComponent<Rigidbody2D>().AddForce(new Vector2(aimPos.x - Spawn.position.x, aimPos.y - Spawn.position.y).normalized * shootForce); //projectile force added
    9.             CurrentProjectiles -= 1;
    10.             isShooting = false;
    11.         }
    12.     }
    and you should be all good
     
  5. derekmklinger

    derekmklinger

    Joined:
    Jul 20, 2018
    Posts:
    3
    Hey! That helped so much, thank you! I was able to take what you said and everything worked perfect except for:

    "pel.SetWeaponDamage(weaponDamage);"

    It still wasn't making a connection properly to the ProjectileSettings script, so I took that line and specifically added a reference to it.

    "pel.GetComponent<ProjectileSettings>().SetWeaponDamage(weaponDamage);"

    I went to test it out between two players with different weapon and projectile values and they added up perfectly! It may not be the best way about it but it works! that's all I can ask for for now.

    Thank you so much for your help johne5!
     
  6. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    good catch on the GetComponent<ProjectileSettings>()
    i missed that part.
    Glad to hear you got it working.
     
    derekmklinger likes this.