A field initializer cannot reference the non-static field, method, or property when i try to access a list - unityscript

I try to make 2d Minecraft but when i try to access the list, This Error Happen:
"A field initializer cannot reference the non-static field, method, or property"
The Script:
[SerializeField] Generator Generator;
GameObject[] terrain = Generator.terrain;
public void show()
{
foreach (GameObject g in terrain)
{
Vector3 pos = new Vector3(transform.position.x,transform.position.y,0);
Instantiate(grass, pos, Quaternion.identity);
}
}
I want to access the list and use the Game Object Inside it.

Related

I need help i keep geting this unity error? Assets\ScoreTextScript.cs(10,10): error CS0426: The type name 'Text' does not exist in the type 'Text'

So this is my code. Im trying to make it so the coins collected add to the score in the UI.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ScoreTextScript : MonoBehaviour
{
Text.Text
coinAmount;
//Use this for initialization
void Start ()
{
text = GetComponent<Text>();
}
//Update is called once per frame
void Update ()
{
text.Text = coinAmount;
}
}
The Text is the error but I don't know how to fix it.
I need help immediately
I think you don't understand how variables work in unity.
First you are declaring a Text.text called coinAmount
In Unity when you are declaring a variable you first have to set the access modifier.
The 2 main are: private and public.
private means your variable will only be accessible in the class you declared it.
public means you can access it from any other class if you make a reference to that script.
Then you need to put the type of your variable.
Here you used Text.text and that's not a type for a variable.
You can set to int, string, etc... If you want to use a Text component in unity do like this:
private Text coinAmount;
Since it's a private variable you can't drag it in the editor. If you want to be able to place a Text component by hand in the editor you can either do:
public Text coinAmount;
//or
[SerializeField] private Text coinAmount; //I'll let you search about SerializeField
In your Start method you are assigning text variable to the Text component this object hold. But text does not exist. If you declare a variable in a method it will only be accessible in this method.
So, what you want is:
private void Start(){
coinAmount = GetComponent<Text>();
}
And lastly i see you want to assign your text to the variable we created earlier. That's useless. You need to create a new variable of type int and assign it to the text value of coinAmount.
To do so:
We will create a new variable right under coinAmount.
public int coinNumber;
And in update we can use it:
private void Update(){
coinAmount.text = coinNumber.ToString(); //.ToString() is used when you want to convert something to a string (which is a type of variable).
}
And there we go everything should work correctly !
The whole code:
private Text coinAmount;
public int coinNumber;
private void Start(){
coinAmount = GetComponent<Text>();
}
private void Update(){
coinAmount.text = coinNumber.ToString(); //.ToString() is used when you want to convert something to a string (which is a type of variable).
}
Hope it helped ! Have a nice day !

Debugger shows not existing properties of an object

I am using Svg .Net lib. Here is my method code
public void X()
{
Svg.SvgDocument svgDocument = SvgDocument.Open(Path);
foreach (var child in svgDocument.Children)
{
foreach (var step in child.Children)
{
if (step.ID.StartsWith("node"))
{
var el = step.Children[2];
var id = el.Content;
}
}
}
}
And here is what I can see in a debugger:
My question is how I can see Bounds property if object does not have it?
Thanks!
The debugger always shows the properties of the actual (dynamic) instance of the object, not the static type of the variable you're referring to. It tries to give you as much information about the object as possible. If you check the third column in the watch window, it tells you the static type of the variable (SvgElement) and its dynamic type (SvgText) in braces. Expanding a variable shows the properties and fields of the dynamic type.

Shared_ptr seems to work on copy, not on original object

I got 2 classes that represent Player and I want to keep in one of them pointer to another one.
So inside my view::Player I create pointer to logic::Player
namespace view {
class Player {
std::shared_ptr<logic::Player> m_player;
//logic::Player* m_player;
public:
void create(logic::Player& player) {
m_player = std::make_shared<logic::Player>(player);
//m_player = &player;
}
};
}
view::Player is created in view::GameState and simply initialised like this
m_playerOneView.create(m_game.getActivePlayer());
m_game is logic::Game object
logic::Game has std::vector<logic::Player>, and public method that returns active one
logic::Player& logic::Game::getActivePlayer() {
return m_players[m_activePlayer];
}
And finnaly
namespace logic {
class Player {
std::string m_name;
int position;
};
}
Now I need original object of logic::Player pointed by std::shared_ptr in my view::Player class. I could simply do that by changing that to raw pointer and it works then (2 commented lines do what I want to achieve basicly). But when I try to do this on std::shared_ptr, I seem to work on copy of logic::Player, because when I update his position for example, it changes everywhere in the game but not in view::Player. How to do that using std::shared_ptr then?

Single instance of an object

I'm trying to implement a singleton-like object with C++11. I got this example from another user.
It creates an object with the constructor and the copy constructor private and default, as well as an instance() function to return static object.
As I understand this should prevent the creation of two instances of this object. But as you can see in my main.cpp, I create two instances and it compiles and runs.
Is my object creation wrong or what? I don't get it.
object.hpp:
#ifndef OBJECT_H
#define OBJECT_H
#include <iostream>
using namespace std;
class Object
{
private:
Object() = default;
Object(const Object&) = delete;
public:
// Singleton in C++11
static Object& instance() { static Object z; return z; }
};
#endif // OBJECT_H
main.cpp:
#include "object.hpp"
int main()
{
Object* object = new Object();
object->instance();
Object* object2 = new Object();
object->instance();
return 0;
}
When I try to compile your code, I get a proper error from the compiler:
main.cpp: error: calling a private constructor of class 'Object'
Object* ob1= new Object() ;
So I would not be able to create two objects using new.
First your code in main won't compile. Object default constructor is private, so you won't be able to do :
Object* object = new Object();
Second, as instance() is static (means not related to any instance) there is no need to call it from an object, the class name suffices :
Object& theInstance = Object::instance();
Finally, the code of instance is :
static Object& instance()
{
static Object z;
return z;
}
It's OK. A static variable in a C++ function means that the object is instanciated once : when the function is ran for the first time. Then z won't be destroyed at the end of the function (contrary to other so-called local variables) and will be re-used for next calls of instance.
So at first call of instance :
z is created
z z is returned
At next calls :
z is returned
A singleton is a class which implies only one instance will be created. You can verify the objects are the same with :
Object& a = Object::instance();
Object& b = Object::instance();
std::cout << &a << std::endl;
std::cout << &b << std::endl;
a and b should have the same memory adress.
This is the expected behaviour of a singleton : if the object construction function (instance) is called several times, the same instance will be returned.
So as you said, instance actually prevents the creation of two Object. Maybe you expected you program to return some error on the second call of instance. If you wan't this behaviour, you'll have to make it yourself using expections or returning NULL. Yet, The code you wrote shows the classic way singletons are done in C++.

Linq - How can i use "this" inside of a "select new" statement

Edited:
I'm querying some XML into objects recursively. Each object has a list of sub objects, and should refer to it's parent if it has one.
Example XML:
<object attribute1="text" attribute2="text"/>
<object attribute1="text" attribute2="text">
<object attribute1="text" attribute2="text">
<object attribute1="text" attribute2="text">
</object>
Example Linq:
private static List<MyObject> ParseMyObjects(XElement node, MyObject p)
{
List<MyObject> myobjs = (from x in node.Elements("object")
select new MyObject {
attribute1 = x.Attribute("attribute1 ").Value,
attribute2 = x.Attribute("attribute2 ").Value,
subObjects = ParseMyObjects(x, this), // the "this" key word can't refer to the MyObject being created in the query, but is there some other way of doing this?
parent= p
}).ToList();
return myobjs;
}
To accomplish this currently, I am recursively traversing the MyObjects list AFTER it has been queried and setting each parent (the "parent" line above is excluded).
I would simply prefer a more elegant solution of using the newly instantiated object within the Linq query if possible. Any ideas?
Edit:
To clarify (as BrokenGlass did in a comment), the this that the code comment is referring to is the instance of MyObject that is being created within the query
this can't work in a method marked static ever. There is no instance because the method is static.
I would simply prefer a more elegant solution of using the newly instantiated object within the Linq query if possible. Any ideas?
Just use XObject.Parent as in
parent = x.Parent
If you want the Parent member of the created MyObject instance to point to the instance itself, there are two ways to achieve this without adding code that iterates over the list after the Linq query:
1) Add a constructor that sets it up for you, e.g. the default constructor
public MyObject() {
this.Parent = this;
}
2) Add a fluent-interface style method for setting the parent, and invoke it in the query:
/* in class MyObject */
public MyObject WithSelfAsParent() {
this.Parent = this;
return this;
}
/* updated linq query */
List<MyObject> myobjs = (from x in node.Elements("object")
select new MyObject {
attribute1 = x.Attribute("attribute1 ").Value,
attribute2 = x.Attribute("attribute2 ").Value,
subObjects = ParseMyObjects(x),
}.WithSelfAsParent()).ToList();
Whether these are better than explicitly looping over the list is of course a matter of taste. I would probably just keep it simple and choose the loop, unless the assumption that the parent pointer is equal to this by default is obvious in the context of your MyObject class, which makes setting it in the default constructor the natural choice.
The solution for me was to harness the set of the subObjects property on MyObject.
class MyObject {
....
private List<MyObject> _subObjects = new List<MyObject>();
public List<MyObject> subObjects
{
get { return _subObjects ; }
set
{
_subObjects = value;
if(_subObjects != null)
{
foreach(MyObject o in _subObjects )
{
o.parent = this;
}
}
}
}
....
}
If anyone does know of a way to reference the newly created/selected object within the Linq syntax, I will mark your answer as the corrrect one.

Resources