C#:Unity:Having trouble reference Rigidbody2d from different script - c#

My scene has a main character, a balloon and a tether. I have a spring joint 2d connected to the balloon and I want to be able to change the connected body to the object the player clicks on. So far I have the following 2 scripts, one for the balloon and one for the connecting body:
Balloon:
using UnityEngine;
using System.Collections;
public class BalloonTethering : MonoBehaviour {
public SpringJoint2D theSpringJoint;
public Rigidbody2D theTether;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
theSpringJoint.connectedBody = theTether;
}
}
Connecting Body:
using UnityEngine;
using System.Collections;
public class TetherAny : MonoBehaviour {
public GameObject mainBalloon;
public Rigidbody2D iAmATether = new Rigidbody2D();
// Use this for initialization
void Start () {
mainBalloon.GetComponents<BalloonTethering>();
iAmATether = this.gameObject.GetComponents<Rigidbody2D>();
}
// Update is called once per frame
void Update () {
}
void OnMouseDown(){
BalloonTethering.theTether = iAmATether;
}
}
I keep getting the following two errors on the TetherAny script:
(12,17): error CS0029: Cannot implicitly convert type 'UnityEngine.Rigidbody2D[]' to 'UnityEngine.Rigidbody2D'
(21,34): error CS0120: An object reference is required to access non-static member 'BalloonTethering.theTether'
If anyone could tell me where I'm going wrong it would be much appreciated :)
Thank you!

From the first error line I can tell that GetComponents() will return multiple Rigidbody2D object, not only one.
http://docs.unity3d.com/ScriptReference/Component.GetComponents.html
http://msdn.microsoft.com/en-us/library/aa288453%28v=vs.71%29.aspx
Use these two links to understand what is actually happening.
On the second one.. You are trying to access a member of a class of which you don't have the object to (that's not how you access other objects members)
http://msdn.microsoft.com/en-us/library/x9afc042.aspx
It seems to me that you should learn how to program the basics first, honestly. But that's just my opinion.

(12,17): error CS0029: Cannot implicitly convert type 'UnityEngine.Rigidbody2D[]' to 'UnityEngine.Rigidbody2D'
GetComponents returns a LIST of Rigidbodies. You cannot assign an entire list to one object. You need to use GetComponent, not GetComponents. Singular. The '[]' after Rigidbody2D in the error denotes that it is a list, not a single object.
(21,34): error CS0120: An object reference is required to access non-static member 'BalloonTethering.theTether'
This is because you never tell it what BalloonTethering you want it to reference. You need to use GetComponent() on the balloon object. There are other problems here, I'm surprised you aren't getting more errors. As soon as you attempt to access any of these variables there will be problems! I'll fix up the first script to get you on your way
using UnityEngine;
using System.Collections;
public class BalloonTethering : MonoBehaviour {
public SpringJoint2D theSpringJoint;
public Rigidbody2D theTether;
// Use this for initialization
void Start () {
theSpringJoint = this.gameObject.GetComponent<SpringJoint2D>();
}
// Update is called once per frame
void Update () {
}
}
You'll need to assign an object to theTether if you want anything to happen when you make it the connectedBody

Related

Operator `<=' cannot be applied to operands of type `VictoryCountdown' and `int'

using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class VictoryCountdown : MonoBehaviour
{
public float victoryCountdown = 300.0f;
public Text startText;
void Update()
{
victoryCountdown -= Time.deltaTime;
startText.text = "Survive until dawn!: " + (victoryCountdown).ToString("0");
}
}
/////////// 2nd Script below ///////////////////
using UnityEngine;
public class VictoryManager : MonoBehaviour
{
public VictoryCountdown victoryCountdown;
Animator anim;
void Awake()
{
anim = GetComponent<Animator>();
}
void Update()
{
if (victoryCountdown <= 0)
{
anim.SetTrigger("Victory");
}
}
}
Hello, I'm a beginning student so this may be an obvious error. I need to create a countdown timer to end a game. I believe that I have everything working, but ran into this issue at the final hour.
The first script creates a timer and then counts down to 0. The second script triggers the victory screen animation. Unity is returning the error:
Operator <=' cannot be applied to operands of typeVictoryCountdown'
and `int
I made some progress, but hit this hurdle and was hoping someone more experienced could tell me what I have done wrong.
You have a problematic naming convention. Also, you are trying to compare the
VictoryCountDown object with an int and that's not possible.
you can easily fix it like this. But it'll look like a mess...
if (victoryCountdown.victoryCountdown <= 0)
{
anim.SetTrigger("Victory");
}
It looks like you are defining an object of type VictoryCountdown, and you are naming that object victoryCountdown. Your comparison isn't accessing the class variable victoryCountdown, but the object. To get the variable, you have to do something like victoryCountdown.victoryCountdown, where you are accessing the variable through an instance of the class (though I would recommend changing the name of the class instance to avoid this confusion).
I would also note that the variable you want is a float and 0 is an int, so that comparison might not work as well (I'm not as familiar with how C# handles this kind of type disparity)

Variables in script do not show in Inspector (Unity)

I'm trying to learn how to use Unity and following online tutorials but I am currently having a problem that I don't understand how to fix.
I have a Sprite in my scene and I have attached a script to it however in the Inspector it shows the script is there but I cannot see the variables inside? I had this problem previously and it sorted itself out.
What is the cause of this problem/how do I fix it?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpaceShip : MonoBehaviour {
public float speed = 30;
public GameObject theBullet;
private void FixedUpdate()
{
float horzMove = Input.GetAxisRaw("Horizontal");
GetComponent<Rigidbody2D>().velocity = new Vector2(horzMove, 0) *
speed;
}
// Update is called once per frame
void Update () {
if (Input.GetButtonDown("Jump"))
{
Instantiate(theBullet, transform.position, Quaternion.identity);
}
}
}
Edit: The problem was solved by reimporting.
You either need to declare the variables as Public or [SerializeField] for member variables to appear in the inspector. Note that by declaring something as public allows access to the variable from outside the class (from other scripts/classes for example). By default, private is assigned to member variables.
Example:
public class testscript : MonoBehaviour
{
public int foo; // shows up in inspector
[SerializeField] private int bar; // also shows up while still being private
void Start()
{
}
}
Not is a problem, You forget to do something surely.
It is common at first with Unity.
Start again.
In the scene create a new GameObject and add you script.
If the inspector shows not variable:
The varible do not is public (false, if is public in you script)
There is some syntax error in the script!
or
You were not adding the correct script to the GameObject.
There are not many secrets to that, if all is well enough that the variable is public and this outside of a method of the script so that it is seen in the inspector.
One tip, do not use a GetComponent or Instantiate inside a FixedUpdate or Update because they are expensive, save the Rigidbody2D in a variable in the Start and then use it.
Sorry for my English and good luck.

CS0120 Cant set layer mask from different script

I'm making a game where i want to change which objects my player can collide with by changing the layer mask, but every time I try to change the variable in a different script it throws this error
Error CS0120: An object reference is required to access non-static
member `RaycastController.jumpableCollisionMask'
The code for where i create the variable:
using UnityEngine;
using System.Collections;
[RequireComponent (typeof (BoxCollider2D))]
public class RaycastController : MonoBehaviour {
public LayerMask collisionMask;
public LayerMask jumpableCollisionMask;
The code for where i set the variable
using UnityEngine;
using System.Collections;
public class PlayerChanger : MonoBehaviour {
public float numberOfPlayersPerLevel;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown (KeyCode.E)){
RaycastController.jumpableCollisionMask = 11;
}
}
}
I have tried using a setter but i couldn't get it to work. Thanks in advance and have a nice day =).
jumpableCollisionMask = 11
not
RaycastController.jumpableCollisionMask = 11
Note that you likely have another problem:
You set layer masks (which are just int) like this:
int layerMaskDogs = 1 << LayerMask.NameToLayer("Dogs");
int layerMaskFruits = 1 << LayerMask.NameToLayer("Fruits");
ok?
Never use "= 11" or any number or other value. In Unity it is now only possible to use the form 1<<LayerMask.NameToLayer("Blah")
Finally note you are using public to declare the LayerMask. That can be a bit confusing -- you only do that if you want to set it in the editor. If that's what you want to do, fine. But if you don't need to do that, just use private.
Finally note that you have this is TWO DIFFERENT SCRIPTS!!! This is the most basic problem in Unity. Fortunately it is easily solved:
-- add a public variable to your SECOND script
public class PlayerChanger : MonoBehaviour {
public RaycastController myRC;
-- IN THE INSPECTOR take your "RaycastController" and drag it to that public variable
-- Now use it like this
public class PlayerChanger : MonoBehaviour {
public RaycastController myRC;
...
...
...
//whenever you need to use it...
myRC.jumpableCollisionMask = 11;
Please read the literally 1000s of QA on this! Example, How to access a variable from another script in another gameobject through GetComponent?

Access script from another script not working

I am trying to access a function, with a bool parameter, from one script to another and just can't get it to work. I have been looking around to try to understand what i am doing wrong.
Here is the script i am calling:
public class MainScript : MonoBehaviour {
public void ManageBoxCollider2D (bool shouldColliderBeEnabled) {
print (">>>>>>>>>>>>>>>>ManageBoxCollider2D: " + shouldColliderBeEnabled);
}
}
I am trying to call it from this script:
public class Sidebar1_Script : MainScript {
public MainScript mainScript;
void Start () {
mainScript.ManageBoxCollider2D (true);
}
}
There is a lot of other stuff in the scripts as well but this is what matters for this question
In the "Sidebar1_Script" I am trying to access "ManageBoxCollider2D" in "MainScript" but it does not work.
I do get the following message:
Object reference not set to an instance of an object
...which i do understand but can't figure out what i am doing wrong.
I would appreciate some help how to do this.
Thanks
It's because unity doesn't know what script that is. If you see in the inspector you're gonna find that public variable MainScript is still empty, also you can't assign scripts in the inspector (I don't know why though, when you drag it there it won't fit in).
Instead change your Sidebar1_Script like this:
public GameObject obj;
void Start () {
MainScript main = obj.gameObject.GetComponent<MainScript>();
main.ManageBoxCollider2D(true);
}
And then assign the game object of obj in the inspector (drag the game object to the public variable).

NullReferenceException in Unity (C#)

I'm trying to add a Quest-object to a Person. It succeeds for one and gives a nullreferenceexception for the other, what am I doing wrong here?
P.S. The player and requestor are set in the Unity inspector.
public class GameCreator : MonoBehaviour {
private Quest quest;
public Player player;
public Requestor requestor;
void Start() {
quest = createQuest();
requestor.thisPerson.SetQuest(quest); //this is the problem
player.thisPerson.SetQuest(quest);
}
}
public class Player : MonoBehaviour {
public Person thisPerson;
void Start() {
thisPerson = new Person("Name");
}
}
public class Requestor: MonoBehaviour {
public Person thisPerson;
void Start() {
thisPerson = new Person("Name");
}
}
public class Person {
public Quest quest;
void SetQuest(Quest quest) {
this.quest = quest;
}
}
Any suggestions why this is going wrong?
Move your variable initialization in to Awake(), see the documentation for the following (paraphrased):
Awake is used to initialize any variables or game state before the
game starts.... and use Start to pass any information back and forth.
The way your GameCreator.Start() is written you are reliant on the arbitrary order in which Unity calls your scripts. GameCreator could be the first object called, in which case none of your other scripts have initialized their values.
Other possible errors:
You don't explicitly instantiate requestor, I'm going to assume this was done in Unity's Inspector.
You didn't include `createQuest()' which could be returning null.
As Jordak said, your Start methods can run in any possible order, so you can't rely on Start of some component in the other. You have several ways to address this issue:
You can move the basic initialization code to Awake(). However, this only allows you two levels of initialization, and can be insufficient in the future.
You can adjust script priority in the project settings. However, this is not really C# way, as this makes your code rely on logic that is not obvious from it.
Instead of initializing thisPerson field in the class initialization, create a public property to access it. (Public fields are bad practice in C# anyway). In this property, you can check if the field is null before returning it, and if it is, initialize it.

Categories