Unity: getting NullReferenceException using javascript - unity3d

I'm a newby in Unity and I'm following the first Unity tutorial. When i try to run my first script i get this error:
NullReferenceException: Object reference not set to an instance of an object
Here is my script:
#pragma strict
private var rb:Rigidbody;
private var player:GameObject;
function start() {
player = GameObject.Find("Player");
rb = player.GetComponent(Rigidbody);
}
function FixedUpdate() {
var moveHorizontal:float = Input.GetAxis("Horizontal");
var moveVertical:float = Input.GetAxis("Vertical");
var movement:Vector3 = new Vector3(moveHorizontal , 0.0f , moveVertical);
rb.AddForce(movement);
}
I have no idea what am I doing wrong.
UPDATE:
Here is my scene:
UPDATE:
I've put print in both functions, and it seems like start is not being called at all, and that is why my variable is not being initialized. Any idea?

I would remove the declaration
private var rb:Rigidbody;
because it seems that your script is trying to access the declared Rigidbody (that stills not initialized, so it's null), and not the object's real one.
Side note: seems that, from Unity 5.3.3, you have to do:
player.GetComponent.<Rigidbody>();
(from here)

It seems your gameobject doesn't have Rigidbody component attached to it and variable rb is null after rb = GetComponent(Rigidbody);

You should take advantage of "Unity way" to reference variables. I mean, your player and rb attributes must be public and you just drag into it your gameobject from hierarchy to your attribute on inspector.
If you still want to do it private, for some good reason, just change player = GameObject.Find("Player"); for player = GameObject.FindWithTag("Player"); and your null reference probably will be solved.

So finally after a few hours, I got it. The problem was that start function should be upper case Start. Since it was lowercase, it wasn't called and rb was not initialized.
And here is the final script:
#pragma strict
private var rb:Rigidbody;
function Start() {
rb = GetComponent(Rigidbody);
}
function FixedUpdate() {
var moveHorizontal:float = Input.GetAxis("Horizontal");
var moveVertical:float = Input.GetAxis("Vertical");
var movement:Vector3 = new Vector3(moveHorizontal , 0.0f , moveVertical);
rb.AddForce(movement);
}

Related

Unity ParticleSystem collidesWith

I am trying to change collidesWith paramater of an particle system inside of a script but i am getting this error:
Error CS1612 Cannot modify the return
value of 'ParticleSystem.collision'
because it is not a variable
My Code:
GameObject ammo; //Game object with ParticleSystem on it
public LayerMask desiredLayers;
private void Start()
{
ammo.GetComponent<ParticleSystem>().collision.collidesWith = desiredLayers;
}
Now my question is what is the correct way to change the layers of a particle system collide with.
Okay i figure it out, apparently ParticleSystem is a property.
And Unity have something special for ParticleSystem which uses Pointers so following code solved my problem:
var collidesWith = ammo.GetComponent<ParticleSystem>().collision.collidesWith;
collidesWith = desiredLayers;

How to create a projectile Script in Unity

so recently my friends and I are trying to make a game for fun. Currently, I hit a wall and not sure how to do this. I am trying to create a simple base script where I have the character move and attack with right click. If it hits the ground, it will move there and and if in range of a target, it will send a projectile. So the game is creating the projectile but its not actually moving. Can anyone tell me what I should probably do. At first, I thought to just make it all one script but now I am thinking it be best to make another script for the projectile.
void Update()
{
if (Input.GetMouseButtonDown(1))
{
RaycastHit hit;
if(Physics.Raycast (Camera.main.ScreenPointToRay(Input.mousePosition), out hit) && hit.transform.tag == "Minion")
{
if(Vector3.Distance(this.transform.position, hit.point) <= atkRange)
{
GameObject proj = Instantiate(bullet) as GameObject;
proj.transform.position = Vector3.MoveTowards(this.transform.position, target, atkSpd);
}
}
else if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, speed))
{
agent.destination = hit.point;
}
}
}
So this is what I originally had. I am pretty sure I did something wrong here. Also I am not sure if I should have another script for the projectile itself or if it is not necessary. Thank you for any help or tips on what to do.
For starters, I'd advize using a Rigidbody component and letting physics handle movement but if you'd like to use Vector3.MoveTowards, it'll be a bit of work:
Vector3.MoveTowards is something that needs to be called every frame. I'm guessing bullet is your prefab so you'll want to make a new script for the movement and place it on that prefab:
public class MoveToTarget : MonoBehaviour
{
private float _speed;
private Vector3 _target;
public void StartMovingTowards(Vector3 target, float speed)
{
_target = target;
_speed = speed;
}
public void FixedUpdate()
{
// Speed will be 0 before StartMovingTowards is called so this will do nothing
transform.position = Vector3.MoveTowards(transform.postion, _target, _speed);
}
}
After you've attached this to your prefab, make sure you grab a reference and get it started when you instantiate a copy of your prefab:
GameObject proj = Instantiate(bullet) as GameObject;
var movement = proj.GetComponent<MoveToTarget>();
movement.StartMovingTowards(target, atkSpd);
If you instead go the physics route, add a Rigidbody component to your bullet prefab, and get a reference to that instead of making the MoveToTarget script:
GameObject proj = Instantiate(bullet) as GameObject;
var body = proj.GetComponent<Rigidbody>();
Then you can just apply a force and let physics take over:
body.AddForce(target - transform.position, ForceMode.Impulse);
Don't set the position like you currently are
proj.transform.position = Vector3.MoveTowards(this.transform.position, target, atkSpd);
Instead, add either a characterController or a rigidbody and use rb.addVelocity.

Unable to get new unity particle system code working post update

I used to have the following particle system that worked.
// In the inspector I drag in the leaf particle system.
public ParticleSystem LeafStormParticleSystem;
private IEnumerator activate(float ActivateFor) {
//Change number of particles to 150
LeafStormParticleSystem.maxParticles = 150;
// LeafStormParticleSystem.
var newEmission = LeafStormParticleSystem.emission;
var rate = newEmission.rate;
rate.constantMin = 20;
rate.constantMax = 21;
newEmission.rate = rate;
Now as you can probably tell, this simple increases the number of particles. Now, this used to work and probably doesn't because of the new particle system I keep reading about.
However on this new particle system I have a question and issues getting it to work.
Issue
Correct me if i'm wrong but the particle system is defined as follows
void Start()
{
ParticleSystem ps = GetComponent<ParticleSystem>();
var main = ps.main;
main.startDelay = 5.0f;
main.startLifetime = 2.0f;
}
Now if I have 3 particle systems, how do I specify which one i'm referring to? Since I cant define it as public and drag the particle system to it in the editor anymore?
Issue B
Now i tried following what unity said in their forums and did the following
ParticleSystem ps = GetComponent<ParticleSystem>();
var main = ps.main;
main.maxParticles = 150;
// LeafStormParticleSystem.maxParticles = 150;
do not create your own module instances, get them from a ParticleSystem instance UnityEngine.ParticleSystem+MainModule.set_maxParticle
Any help with Issues A and B will be appreciated.
Thank you
Issue A
Only one ParticleSystem component can be attached to any one GameObject at a time. Sub-ParticleSystems must therefore be attached to separate GameObjects too (generally children of the GameObject holding the first ParticleSystem), which can be dropped directly onto public fields.
public ParticleSystem LeafStormParticleSystem;
void Start ()
{
if (LeafStormParticleSystem != null)
{
var main = LeafStormParticleSystem.main;
main.maxParticles = 150;
}
}
Issue B
Your code looks fine, however a critical part of the error message was missing; NullReferenceException which is telling you that a reference in your code is equal to NULL. In your case, that reference would be the ps variable used to store the ParticleSystem reference, which is either a consequence of not attaching this script to the GameObject holding your ParticleSystem or simply that you have no ParticleSystem attached at all. In either case, make sure both script and ParticleSystem are attached to the same GameObject and check your references like so;
void Start ()
{
ParticleSystem ps = GetComponent<ParticleSystem>();
if (ps != null)
{
var main = ps.main;
main.maxParticles = 150;
}
}

Call function from another script

I'm programming a simple game (the first one I do on my own) in which basically there are two scoring goals, and when a player scores, I want to reset the position for all players to some coordinates.
I have a script attached to the goals, which detects collision with the ball, as follows:
Goal.js
#pragma strict
function OnTriggerEnter2D (hitInfo : Collider2D) {
if (hitInfo.name == "Ball")
{
var wallName = transform.name;
GameManager.Score (wallName);
hitInfo.gameObject.SendMessage ("ResetBall");
//Here I need to call the ResetPlayer function
PlayerControlHS.ResetPlayer();
}
}
The following script is attached to the players
PlayerControlHS.js
#pragma strict
var resetPosX : float;
var resetPosY : float;
//keys
var moveUp : KeyCode;
var moveLeft : KeyCode;
var moveRight : KeyCode;
var speed : int = 4;
function Update () {
if (Input.GetKey(moveUp)) {
rigidbody2D.velocity.y = speed;
}
if (Input.GetKey(moveLeft)) {
rigidbody2D.velocity.x = -speed;
}
else if (Input.GetKey(moveRight)) {
rigidbody2D.velocity.x = speed;
}
else {
rigidbody2D.velocity.x = 0;
}
}
function ResetPlayer () {
Debug.Log("I'm being called");
}
Both the goals and the players have a RigidBody 2D and a collider of some kind, as well as the ball.
I've gotten to get the function called as it is right now, but if I try to modify the position coordinates of a player, I enter a loop of death errors that when I fix one, I get another one.
That happens when I put this code in ResetPlayer():
rigidbody2D.position.x = resetPosX;
rigidbody2D.position.y = resetPosY;
Mostly, the errors are because I need an object of type PlayerControlHS to access those fields. I've tried adding a variable of that type (and referencing it to each player) but it doesn't work because it tells me I need an object to access that variable... I don't know how to initialize it if I make it static.
How could I get it working?
EDIT: I'm thinking the best approach would be sending a message just like the ResetBall one, but it doesn't work (I think because the function is called from ball, object of another type and it can't find the function). This way, the function ResetPlayer could stop being static. But I'm not sure if this is right, since I can't get it without compile errors.
EDIT2: It worked, even though I had to put it one liner
hitInfo.gameObject.GetComponent(PlayerControlHS).ResetPlayer();
Because Unity was telling me that I needed to put a semicolon here (I don't understand :S):
PlayerControlHS playerScript ; = hitInfo.gameObject.getComponent(PlayerControlHS);
But I still can't get to modify the variables of the position...
I have tried fixing it but I get an error saying that "I need an instance of type UnityEngine.Component to access non static member 'rigidBody2D' in a variable declaration I made
static var test : PlayerControlHS = rigidbody2D.GetComponent(PlayerControlHS);
And the code I'm trying in ResetPlayer:
test.GetComponent(PlayerControlHS).rigidbody2D.position.x = test.GetComponent(PlayerControlHS).resetPosX;
test.GetComponent(PlayerControlHS).rigidbody2D.position.y = test.GetComponent(PlayerControlHS).resetPosY;
Try changing this line:
PlayerControlHS.ResetPlayer();
To this:
PlayerControlHS playerScript = hitInfo.gameObject.getComponent(PlayerControlHS);
playerScript.ResetPlayer();
That is how you call a function from another script.
EDIT 1:
Sorry I got mixed up with C# even though you are using javascript, I figured out why you got that error. There's a slight difference in variable declaration.
Change the above code to this:
var playerScript:PlayerControlHS = hitInfo.gameObject.GetComponent(PlayerControlHS);
playerScript.ResetPlayer();
As for resetting the player's position, the script is inside the player game object is it not? Then you can just simplify it like this:
function ResetPlayer () {
rigidbody2D.position.x = resetPosX;
rigidbody2D.position.y = resetPosY;
}
Really sorry for that :(

CharacterController and Normal rigidbody Box Collider Collision issues

I am having collision issues in various different cases. I will mention each of them and will wait for your help.
Case 1:
I have an object moving with characterController attached and moving through this plugin: http://u3d.as/content/hedgehog-team/...ck-buttons/2Uo
The objects to which the characterController collides are rigidbody with box colliders attached. Most of the times the collision works perfectly with natural collision effects such as falling of crates etc and OnCollisionEnter of the objects with rigidbody and box collider is called without any problem. But sometimes, this stops. There is no collision with objects no falling and OnCollisionEnter is not called.
I try debugging and searched on google but nothing helpful Found.
Case 2:
I have an object moving with characterController attached and moving with its "SimpleMove" function.
In this case none of the collision happen, no falling, no natural effect and no calling of OnCollisionEnter on objects which have rigidbody and box collider attached.
Please help fix this errors, I have been trying to fix these since 4 days but no luck, finally I am posting here. Will wait your replies.
Thanks. Have a great day!
Does the CharacterController have a RigidBody attached with 'isKinematic' checked?
Add this script to your object :
#pragma strict
var layerMask : LayerMask; //make sure we aren't in this layer
var skinWidth : float = 0.1; //probably doesn't need to be changed
private var minimumExtent : float;
private var partialExtent : float;
private var sqrMinimumExtent : float;
private var previousPosition : Vector3;
private var myRigidbody : Rigidbody;
//initialize values
function Awake() {
myRigidbody = rigidbody;
previousPosition = myRigidbody.position;
minimumExtent = Mathf.Min(Mathf.Min(collider.bounds.extents.x, collider.bounds.extents.y), collider.bounds.extents.z);
partialExtent = minimumExtent*(1.0 - skinWidth);
sqrMinimumExtent = minimumExtent*minimumExtent;
}
function FixedUpdate() {
//have we moved more than our minimum extent?
var movementThisStep : Vector3 = myRigidbody.position - previousPosition;
var movementSqrMagnitude : float = movementThisStep.sqrMagnitude;
if (movementSqrMagnitude > sqrMinimumExtent) {
var movementMagnitude : float = Mathf.Sqrt(movementSqrMagnitude);
var hitInfo : RaycastHit;
//check for obstructions we might have missed
if (Physics.Raycast(previousPosition, movementThisStep, hitInfo, movementMagnitude, layerMask.value))
myRigidbody.position = hitInfo.point - (movementThisStep/movementMagnitude)*partialExtent;
}
previousPosition = myRigidbody.position;
}
And don't forget to specify which layer you want to detect.
Good luck !