• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
Question by vycanis1801 · Sep 30, 2020 at 03:26 AM · scripting problemupdate problem

Why is my transform null in Update?

Here's a snippet of code that passes transform data to a projectile:

   private void OnTriggerEnter2D(Collider2D collider)
         {
             // Check that the collision is with the player and that it
             // ignores any collider that is considered a trigger.
             if(collider.gameObject.tag == "Player")
             {
                 // The player character will multiple box colliders,
                 // but we only want to interact with the players hurt box here.
                 if(!collider.isTrigger)
                 {
                     moveSpeed = 0;
                     
                     // If true, the player is further right on the x axis then the skunk. Else, it is to the left.
                     if(playerCharacter.transform.position.x > transform.position.x)
                     {
                         // If true, the skunk is facing the player. Else, it's facing away.
                         if(transform.right.x == transform.localScale.x)
                         {
                             Flip();
                             facingRight = false;
                         }
     
                         else 
                         {
                             facingRight = false; // In case it was previously true
                         }
                     }
     
                     else
                     {
                         // If true the skunk is facing the player. Else, it's facing away.
                         if(transform.right.x != transform.localScale.x)
                         {
                             Flip();
                             facingRight = true;  
                         }  
     
                         else
                         {
                             facingRight = true;
                         }
                     }
                     Debug.Log(playerCharacter.gameObject.transform.position);
                     skunkProjectile.FireProjectile(projectileSpawnPoint, playerCharacter.gameObject.transform);
                     
                 }
             }
         }

And here is the code that is suppose to receive that information:

 public class SkunkProjectile : Projectile
 {
     private int xVelocity;
     private bool fireLeft;
 
     private Transform fireDirection;
 
     /**
         The fire projectile class creates an instance of a projectile and sets 
         the game object that fires the weapon.
         @param spawnPosition (Transform) - The position the projectile spawns at in local space.
         @param projectileLauncher (GameObject) - The game object that fires the projectile.
     */
     virtual public void FireProjectile(Transform spawnPosition, Transform fireDirection)
     {
         Instantiate(this, 
             new Vector3(spawnPosition.position.x, spawnPosition.position.y, spawnPosition.position.z), 
             new Quaternion(0.0f,0.0f,0.0f,0.0f));
 
         this.fireDirection = fireDirection;
     }
 
     // Start is called on the frame when a script is enabled just before any of the Update methods are called the first time.
     private  void Start()
     {
         xVelocity = 2;
         rb = GetComponent<Rigidbody2D>();
         Destroy(gameObject, 2.0f);
     }
     
     // Update is called every frame, if the MonoBehaviour is enabled.
     private void Update()
     {
         rb.velocity = new Vector2(fireDirection.position.x, 0.0f); 
     } 
 }

So why is it that when the code isn't getting the new fireDirection on the next frame? When this code fires, I get a NullReferenceException no mater how many times i trigger the script.

Comment

People who like this

0 Show 0
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image

Answer by vycanis1801 · Sep 30, 2020 at 08:36 AM

So, I found something that seems to work, but I feel like my code is starting to get a bit spaghetti is there a clearer solution for this. I'll post all relevant code.

PlayerCharacter:

     using UnityEngine;
     using UnityEngine.UI;
     using UnityEngine.SceneManagement;
     
     [RequireComponent(typeof(Rigidbody2D), typeof(PlayerController), typeof(Collider2D))]
     public class PlayerCharacter : MonoBehaviour
     {
         // Required components
         private Collider2D collider2d;
         private Rigidbody2D rb;
         private PlayerController playerController;
     
         // Serialized components/variables
         [Tooltip("Used to calculate the amount of push back happens when the player is damaged.")]
         [SerializeField] private float hurtForce = 1f;
     
         [Tooltip("Players default health")]
         [SerializeField] private int health;
     
         [Tooltip("Player health UI element")]
         [SerializeField] private Text healthAmount;
     
         /**
             The rigid body is used in determining whether or not the player is infornt or behind an enemy.!--
             GetRBPosition allows another script to access this information.!--
             @return rb (RigidBody2D) - physics object used to get the players location
         */
         public Vector2 GetRBPosition() { return rb.position; }
     
         // Awake is called when the script instance is being loaded.
         private void Awake()
         {
             collider2d = GetComponent<Collider2D>();
             rb = GetComponent<Rigidbody2D>();
             playerController = GetComponent<PlayerController>();
         }
     
         // Sent when an incoming collider makes contact with this object's collider (2D physics only)
         private void OnCollisionEnter2D(Collision2D collision)
         {
             if(collision.gameObject.tag == "Enemy")
             {
                 Enemy enemy = collision.gameObject.GetComponent<Enemy>();
     
                 // Get the velocity state of the player controller. If the player is falling,
                 // "kill" the enemy. Otherwise take damage from the enemy.
                 if(playerController.getState() == VelocityState.falling)
                 {
                     enemy.SetDeathTrigger(); // This kills the enemy. It also assumes that all enemies have one health.
                     playerController.Jump();
                 }
     
                 else
                 {
                     // Determine which direction to push the player when they are in the hurt state
                     if(collision.gameObject.transform.position.x > transform.position.x)
                     {
                         rb.velocity = new Vector2(-hurtForce, rb.velocity.y);
                         playerController.updateState(VelocityState.hurt);
                         TakeDamage();
                     } 
                     else
                     {
                         rb.velocity = new Vector2(hurtForce, rb.velocity.y);
                         playerController.updateState(VelocityState.hurt);
                         TakeDamage();
                     }
                 }
             }
         }
     
         public void TakeDamage()
         {
             health--;
             // Uncomment when UI is ready.
             // healthAmount.text = health.ToString();
             
             // Reset the level if player dies. 
             if(health <= 0)
             {
                 SceneManager.LoadScene(SceneManager.GetActiveScene().name);
             }
         }
     }
     

Enemy:

 using UnityEngine;
 
 /// <summary>
 /// This is the base class for enemy behavior that should be applicable to all enemies in the game.
 /// This class handles basic enemy movement that can be refined in child classes if desired.
 ///</summary>
 [RequireComponent(typeof(Rigidbody2D), typeof(Animator))]
 public class Enemy : MonoBehaviour
 {
     public float moveSpeed;
     // Required components
     protected Rigidbody2D rigidBody2D;
     protected Animator animator;
     protected bool facingRight = true;
     [Tooltip("A reference to the player's character. It should be some Joe prefab.")]
     protected GameObject playerCharacter;
 
     // Seralized fields
     // Increases speed by the factor set in the editor.
     [SerializeField] private float movementMultiplier = 1f;
 
     protected Vector3 movement;
 
     /**
         Used to update the enemies animator component.
     */
     public void SetDeathTrigger()
     {
         animator.SetTrigger("death");
     }
 
     /**
         Flip is a function that "flips" an enemies sprite
         by inverting it's x-scale.
     */
     protected void Flip()
     {
         transform.localScale = 
             new Vector3(-transform.localScale.x, transform.localScale.y, transform.localScale.z); 
     }
 
     // Awake is called when the script instance is being loaded.
     public void Awake() 
     {
         rigidBody2D = GetComponent<Rigidbody2D>();
         animator = GetComponent<Animator>();
         playerCharacter = GameObject.FindGameObjectWithTag("Player");
     }
 
     private void Death()
     {
         Destroy(this.gameObject);
     }
 
     // Flip the sprite if it collides with platforms/walls, and invert its speed.
     private void OnCollisionEnter2D(Collision2D collider)
     {
         if(collider.gameObject.tag == "Platforms" || collider.gameObject.tag == "Enemy")
         {
             Flip();
             moveSpeed = -moveSpeed;
         }
     }
 }

Skunk (inherits from enemy) :

 using UnityEngine;
 
 /// <summary>
 /// The Skunk class is a child of the enemy class. 
 /// It has the added ability of movement and attacking the
 /// player if they get too close.
 /// </summary>
 public class Skunk : Enemy
 {
     // Serialized fields. (Private memebers accessable by the editor.)
     [Tooltip("This is where your projectile prefab should be inserted")]
     [SerializeField] private SkunkProjectile skunkProjectile;
    
     [Tooltip("A transform that should be a child component of the skunk")]
     [SerializeField] private Transform projectileSpawnPoint;
 
     
 
     // Private memebers
     private float savedMoveSpeed;
 
     /**
         Get facing right is used to inform a caller if this sprite is facing in a x positive direction
         @return facingRight (bool) - return true if facing right. Otherwise false.
     */
     public bool GetFacingRight() { return facingRight; } 
 
     // Sent when another object enters a trigger collider attached to this object (2D physics only).
     private void OnTriggerEnter2D(Collider2D collider)
     {
         // Check that the collision is with the player and that it
         // ignores any collider that is considered a trigger.
         if(collider.gameObject.tag == "Player")
         {
             // The player character will multiple box colliders,
             // but we only want to interact with the players hurt box here.
             if(!collider.isTrigger)
             {
                 moveSpeed = 0;
                 
                 // If true, the player is further right on the x axis then the skunk. Else, it is to the left.
                 if(playerCharacter.transform.position.x > transform.position.x)
                 {
                     // If true, the skunk is facing the player. Else, it's facing away.
                     if(transform.right.x == transform.localScale.x)
                     {
                         Flip();
                         facingRight = false;
                     }
 
                     else 
                     {
                         facingRight = false; // In case it was previously true
                     }
                 }
 
                 else
                 {
                     // If true the skunk is facing the player. Else, it's facing away.
                     if(transform.right.x != transform.localScale.x)
                     {
                         Flip();
                         facingRight = true;  
                     }  
 
                     else
                     {
                         facingRight = true;
                     }
                 }
                 Instantiate(skunkProjectile, new Vector3(projectileSpawnPoint.position.x, projectileSpawnPoint.position.y, projectileSpawnPoint.position.z), new Quaternion(0.0f,0.0f,0.0f,0.0f));
             }
         }
     }
 
     // Sent when another object leaves a trigger collider attached to this object (2D physics only).
     private void OnTriggerExit2D(Collider2D collider)
     {
         if (collider.gameObject.tag == "Player")
         {
             if(!collider.isTrigger)
             {
                 moveSpeed = savedMoveSpeed;
                 // This makes sure that the skunk does move in the wrong direction
                 // after the player has left its attack range
                 if(moveSpeed > 0.0f && transform.localScale.x < 0.0f || 
                    moveSpeed < 0.0f && transform.localScale.x > 0.0f)
                 {
                     moveSpeed = -moveSpeed;
                 }                
             }
         }
     }
 
     // Called once per frame
     private void Update()
     {
         rigidBody2D.velocity = new Vector2(moveSpeed, rigidBody2D.velocity.y);
         // It won't try and update the movement speed if the skunk is stopped.
         if(moveSpeed != 0.0f)
         {
             savedMoveSpeed = moveSpeed;
         }
     }
 }

Projectile:

 using System.Collections;
 using UnityEngine;
 
 /// <summary>
 /// The projectile class is the base class for all projectiles.
 /// It is responsible for when the projectile spawns and when it is destroyed.
 /// Child classes should always be attached to a spcific projectile prefab.
 /// </summary>
 public class Projectile : MonoBehaviour
 {
     // Serialized feilds. (protected memebers accessable by the editor.)
     [Tooltip("This field comes from the projectile base class.")]
     [SerializeField]protected Rigidbody2D rb;
 
     private void OnTriggerEnter2D(Collider2D collision)
     {
         // When player collides with trigger, they take damage, and projectile disappears
         if(collision.gameObject.tag == "Player")
         {
             collision.gameObject.GetComponent<PlayerCharacter>().TakeDamage();
             Destroy(this.gameObject);
         }
     }
 }

Skunk Projectile (inherits from projectile) :

 using UnityEngine;
 
 ///<summary>
 /// The skunk projectile is a child class of projectile.
 /// This class is responsible for calculating the trajectory of
 /// the projectile.
 /// This script should only be used with the SkunkProjectile prefab. 
 /// Which should be at: Assets\Prefabs\Projectiles\SkunkProjectile.prefab 
 ///</summary>
 public class SkunkProjectile : Projectile
 {
     private int xVelocity = 2;
     private bool fireLeft;
 
     private Transform fireDirection;
 
     // Start is called on the frame when a script is enabled just before any of the Update methods are called the first time.
        private  void Start()
 {
     xVelocity = 2;
     rb = GetComponent<Rigidbody2D>();
     PlayerCharacter pc = FindObjectOfType<PlayerCharacter>();
     playerPosition = pc.transform.position;
     Skunk skunk = FindObjectOfType<Skunk>();
     skunkPosition = skunk.transform.position;
     Destroy(gameObject, 2.0f);
 }
 
 // Update is called every frame, if the MonoBehaviour is enabled.
 private void Update()
 {
     Debug.Log(skunkPosition);
     if (playerPosition.x < skunkPosition.x)
     {
         rb.velocity = new Vector2(-2, 0);
     }
     else if(playerPosition.x > skunkPosition.x)
     {
         rb.velocity = new Vector2(2, 0);
     }
 }

All advice will be appreciated ^_^

Comment

People who like this

0 Show 0 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

316 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

PLEAASEE I NEED HELP!!! How to turn Mesh Renderer of cubes on and off by pushing buttons? 1 Answer

I want my script to wait 2 seconds before continue in a condition, in update, using C# 2 Answers

OnCollisionEnter2D not working after update. 0 Answers

Help I've Lost all Hope, A script stopped working on my Player Character Prefab! 0 Answers

I can access the field but it wont update the value? 3 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges