Walker boys tutorial... NullPointerException error - unity3d

I am seeing the Walker boys tutorial, Im on the Project #2, where you make a ship that destroys asteroids... and there's a part where the bullet must call a function from other object... (here's the video http://vimeo.com/19463502) I do everything that is here but I get this error:
"NullReferenceException: Object reference not set to an instance of an object
scriptBullet.OnTriggerEnter (UnityEngine.Collider other) (at Assets/scriptBullet.js:39)
and that line of code is :
sceneManager.transform.GetComponent(scriptsceneManager).AddScore();
scriptsceneManager.js
var gameTime : float = 60;
static var score : int = 0;
function Update ()
{
print("score : " +score);
}
public function AddScore()
{
score +=1;
}

From what i can see (it's been a while since i did the walkerboy tutorials) there are only 2 reason why you can get a NullPointerException here.
The SceneManager has not been initialised in scriptBullet.js. If you are finding the GameObject by Tag make sure you have the tag assigned and is spelled correctly in the script. I always forget to assign tags until it's no late.
The scriptsceneManager hasn't been added to the SceneManager object. This results in the GetComponent call returning null.
If you are using Monodevelop, remember if you hit the attach button, you can attach UnityEditor to monodevelop, then you can use breakpoints to find out where the NullPointer is coming from.
https://docs.unity3d.com/Documentation/Manual/Debugger.html
Hope this helps.

Related

#Unity3D - Attach an object to another using a face of the last object as a target and deleting the last one detected

Let's say that I have three simple box-like objects and I want to make different compositions by adding to the first object, already present in the scene, another one and then the other in whatever order i want by pressing a specific key on the keyboard (let's say W key for the Object 2 and S key for the Object 3).
For example:
After that I would like to delete the last present object every time I want by pressing Q key.
For example, I press W,W,S,W,S (Obj2, Obj2, Obj3, Obj2, Obj3).
After, I press Q three times (obtaining the composition Obj2, Obj2 because i destroyed the last three with Q).
And after that I press W one time (obtaining Obj2, Obj2, Obj2).
The modular part is made by a script put in an Empty GameObject(which is inside the Objects 1, 2 and 3.
public class Placement : MonoBehaviour
{
public GameObject shape1, shape2, shape3;
public Counter count;
void Start()
{
count = FindObjectOfType<Counter>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.W))
{
count.Array[count.i] = Instantiate(shape3, transform.position, transform.rotation);
this.enabled = false;
}
if (Input.GetKeyDown(KeyCode.S))
{
count.Array[count.i] = Instantiate(shape2, transform.position, transform.rotation);
this.enabled = false;
}
if (Input.GetKeyDown(KeyCode.Alpha6))
{
Destroy(count.Array[count.i]);
count.i = count.i - 1;
}
}
Then I used a counter and a GameObject array to "save" each clone put in the scene in another generic script always present in the scene.
public class Counter : MonoBehaviour
{
public int i = 0;
public GameObject[] Array = new GameObject[50];
public void Update()
{
if (Input.GetKeyDown(KeyCode.W))
{
i = i + 1;
}
if (Input.GetKeyDown(KeyCode.S))
{
i = i + 1;
}
}
}
The problems are:
The first script is "reloaded" each time because it's inside every instantiated object I put in the scene, so I have to use an external single script where I save every counter and/or GameObject reference I need;
If I remove this.enabled = false; from every Instantiate process the script partially works but it creates too many clones of the same object(because it's using every Empty GameObject in the scene as reference to where to put the clones and not just the last one present);
By creating too many clones(even if I press W/S one single time), if I try to destroy the last one, it will destroy many others and if I try to put others after the destroying process, it will clone the object in every position available and not the last one.
I'm starting to lose my mind in a dumb process.... :')
Use one empty game object as ObjectSpawnManager to manage your object spawn/despawn behaviour, put the first script to this object, so that you don't need put the same script on multiple instances.
Remove the Update part of Counter script, add public UpdateCounter method, and call it from ObjectSpawnManager script when the corresponding key down.
Since you have stated a few problems and no specific questions, I am going to propose to you an approach that should work and implement what you ask for. If you want clarification on a specific question, feel free to ask.
As you have stated yourself, it makes more sense to have a single script manage the whole process of placing objects. Attach this script, let's call it SpawnManagerScript to an empty GameObject e.g. SpawnManager in the scene.
I would also suggest you to use a List instead of an array if you are not sure how many objects will be there at some point in time. If you do want to limit the number of objects to 50 (looking at your code), an array is totally fine.
Assuming you were able to figure out the correct positioning of the objects upon spawning already, I won't go into detail regarding that.
If I understood you correctly, what's left to do now is the following:
Spawning GameObject:
Differentiate the user input (e.g. S & W) in your SpawnManagerScript. For each type of object you could have a public field in your SpawnManagerScript class which references e.g. a Prefab or template GameObject in the scene. You can use the template object for cloning on user input. Add this clone to the List or array of objects and position it correctly.
Deleting GameObject:
Again, detect your desired input key for deletion in the script. Grab the last element in the List or the last added element in the array from the respective container. Destroy it or set it to inactive. Remove the entry from the container.

Is there a reason why I should use TryGetComponent instead of GetComponent

I recently found out about TryGetComponent and did some research on it. I found out that main difference is that TryGetComponent "does not allocate in the Editor when the requested component does not exist". I don't really know what that means since I am still new to Unity and why would someone request component that does not exist in the first place, so could somebody explain if I should stop using GetComponent, and if so why?
Thanks in advance.
There might be some reasons to use GetComponent without being sure if this component exists. In this case it is necessary to check if the component is actually there or not.
For example, you have an array of game objects (in this case it is RaycastHit2D array and was aquired from Physics2D.GetRayIntersectionAll method). You need to invoke a specific method from every game object that contains a specific component. You can use GetComponent and check if it equals null or not.
RaycastHit2D[] ray = Physics2D.GetRayIntersectionAll(_mainCamera.ScreenPointToRay(Input.mousePosition));
foreach (RaycastHit2D item in ray)
{
var myClass = item.transform.GetComponent<MyClass>();
if (myClass != null )
{
myClass.MyMethod();
}
}
Or you can use TryGetComponent. In this case you do not need to use GetComponent multiple times or create an additional variable. And the code looks cleaner.
RaycastHit2D[] ray = Physics2D.GetRayIntersectionAll(_mainCamera.ScreenPointToRay(Input.mousePosition));
foreach (RaycastHit2D item in ray)
{
if (item.transform.TryGetComponent(out MyClass myClass))
{
myClass.MyMethod();
}
}
TryGetComponent seems to be more useful in some particular cases, but not always.

Assigning script to a variable with a variable (Unity 3D)

So the title is a bit weird but i didnt know how to call it.
I am working on a FPS game and I am trying to make a simple weaponsystem. Every Player can have a primary and a secondary weapon. I am at the moment trying to write a script to change between the assigned primary/secondary weapons.
So at first I am doing this:
var primary : GameObject;
var secondary : GameObject;
So I have some GUI Buttons that when they get clicked they assign the desired weapon to the variables primary/secondary.
An code example:
function assignump45() {
primary = ump;
}
Now I want to write a function to switch between the primary and secondary weapon.
So I tried this:
function switchtoprimary(){
if(Input.GetKeyDown("2")){
primary.inv(); //makes the primary weapon invisible
secondary.vis(); //makes the primary weapon visible
}
}
Of course I get this error:
BCE0019: 'inv' is not a member of 'UnityEngine.GameObject'.
I know that what I wrote is wrong. So I tried to get the script of the primary/secondary weapons so I can disable/activate them:
var primscipt : umpscript = GameObject.Find(ump).GetComponent(umpscript);
This works BUT I can´t write for every weapon this kind of script because I then I need to write several combinations of switching between the weapons and that isn´t possible because i know there is a better solution..
I can´t do a if clause and then assign the primscript because the variable only would be assigned in the if clause..
What I need is something like this (doesn´t work of course^^).
var primscipt : primaryscriptstring = GameObject.Find(primarystring).GetComponent(primaryscriptstring);
So I could assign the variable primaryscriptstring with "umpscript" for example. the variable primarystring does work in this case
Are there any workarounds? I am pretty desperate at the moment :/
You'll probably want to create a Weapon class, and have your primary and secondary vars be Weapons, not GameObjects.
var primary : Weapon;
var secondary : Weapon;
Your Weapon.js file might look something like:
function vis () {
...
}
function inv () {
...
}
Then assuming you want to have every weapon type be an extended class of Weapon, you might create a UMP.js file for example and have its class extend Weapon like so:
#pragma strict
class UMP extends Weapon {
}
UMP then inherits all functions and vars from the Weapon class. So then, elsewhere in your code, the following line would work (assuming there's a GameObject named "UMP" somewhere that has the UMP component attached):
function assignump45() {
var ump : UMP = GameObject.Find("UMP").GetComponent(UMP);
primary = ump;
primary.vis();
}
Alternatively, you might not want to have every weapon type be an extended class, and just have one Weapon class for all weapons, in which case you wouldn't create a UMP.js file, and instead your code might look like:
function assignump45() {
var ump : Weapon = GameObject.Find("UMP").GetComponent(Weapon);
primary = ump;
primary.vis();
}
Instead of
primary.inv();
secondary.vis();
do
primary.SetActive(false);
secondary.SetActive(true);
The SetActive method works for any game object, so you don't have to worry about the specific type of weapon or script. See the Unity docs on this here.

How to call a function of scriptB from scriptA

I have created two scripts one is scrpt_Enemy and other is scrpt_GameManager.
I want to call SubtractLive() function (exist on scrpt_GameManager) from scrpt_Enemy. But it gives error I don't know why. The error is 'SubtractLive' is not a member of 'UnityEngine.Component'.
scrpt_Enemy:
var gameManager : GameObject;
gameManager.GetComponent("scrpt_GameManager").SubtractLive();
scrpt_GameManager:
var lives : int =3;
function SubtractLive(){
lives -= lives;
}
Problem
You were telling Unity that gameManager was of type GameObject. Therefore Unity was freaking out because it doesn't have SubtractLive() under GameObject.
Solution
You can get the correct reference like this:
Create the variable then tell Unity what the type it is.
var gameManager : scrpt_GameManager;
Find the GameObject which has the script attach to it.
gameManager = GameObject.Find("GameManagerGameObject").GetComponent("scrpt_GameManager");
Note that "GameManagerGameObject" is the name of the GameManager in the scene.
Now that you have the reference to the script just call the function like this:
gameManager.SubtractLive();

Trying to access variables from another script in unity (Not Homework)

I am currently playing around in Unity trying to make/test a 2D game. I keep getting the following error when I attempt to access CharacterMotor.playerx from inside camerafollow.js:
An instance of type "CharacterMotor" is required to access non static member "playerx"
Here are my two scripts:
camerafollow.js
#pragma strict
function Start () {
transform.position.x = CharacterMotor.playerx;
}
CharacterMotor.js
#pragma strict
#pragma implicit
#pragma downcast
public var playerx : float = transform.position.x;
You could change playerx to static, but I don't think that's what you want to do (there's probably only one player object, but this would prevent you from ever having multiple CharacterMotors). I think you want/need to retrieve the instance of CharacterMotor that is attached to this gameObject.
#pragma strict
function Start () {
var charMotor : CharacterMotor = gameObject.GetComponent(CharacterMotor);
transform.position.x = charMotor.playerx;
}
An instance of type "CharacterMotor" is required to access non static member "playerx"
The above error message describes precisely what is happening. You are just trying to access a variable without first creating an instance of it. Keep in mind that UnityScript != JavaScript.
To fix this issue, simply change
public var playerx : float = transform.position.x;
to
public static var playerx : float = transform.position.x;
Though this fixes your immediate problem I do not recommend continuing down this path. I suggest that you learn other aspects of the language first (such as classes) so that you can better organize and construct your data.
See: http://forum.unity3d.com/threads/34015-Newbie-guide-to-Unity-Javascript-(long)
CharacterMotor is the type, there can be multiple instantiations of your type in memory at the same time so when you call the type name you are not referencing any instance in memory.
to get an instance of the type that is connected to you current gameobject try this:
var charactorMotor : CharacterMotor = gameObject.getComponent("CharacterMotor");
Now you have access to that instances properties
transform.position.x = characterMotor.playerx;