I am trying make an infinite level generator that gets level parts I give to it and mix's them up to make infinite long an unique levels for me. but the problem is that When I Typed [SerializeField] private Player player; it said No namespace called "Player" which is odd because There are other code's were Player player is used and it works.Maybe I am just dumb but anyway here is my code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LevelGenerator : MonoBehaviour {
private const float PLAYER_DISTANCE_SPAWN_LEVEL_PART = 200f;
[SerializeField] private Transform levelPart_Start;
[SerializeField] private List<Transform> levelPartList;
[SerializeField] private Player player;
private Vector3 lastEndPosition;
private void Awake() {
lastEndPosition = levelPart_Start.Find("EndPosition").position;
int startingSpawnLevelParts = 5;
for (int i = 0; i < startingSpawnLevelParts; i++) {
SpawnLevelPart();
}
}
private void Update() {
if (Vector3.Distance(player.GetPosition(), lastEndPosition) < PLAYER_DISTANCE_SPAWN_LEVEL_PART) {
SpawnLevelPart();
}
}
private void SpawnLevelPart() {
Transform chosenLevelPart = levelPartList[Random.Range(0, levelPartList.Count)];
Transform lastLevelPartTransform = SpawnLevelPart(chosenLevelPart, lastEndPosition);
lastEndPosition = lastLevelPartTransform.Find("EndPosition").position;
}
private Transform SpawnLevelPart(Transform levelPart, Vector3 spawnPosition) {
Transform levelPartTransform = Instantiate(levelPart, spawnPosition, Quaternion.identity);
return levelPartTransform;
}
}
I have tried to make in into a game object but then I got even more errors
No namespace called "Player"
It makes me think that the problem is in the Using.
In some parts of your code it accepts it because you are using it or it is in the same namespace.
Assuming it is called like this, try adding the using as follows
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Player; (it can change but should be like this)
Related
I have a couple of problems with object pooling in Unity with my 2D game, cannon balls don't want to stop when there is a collision with the wall, and 1 of them bursts shoot and the other 9 shoot together connected with each other, my cannon is static object on scene. Can someone help or give me some hint about it.
Here is my code, 3 scripts:
ObjectPooling.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjectPooling : MonoBehaviour
{
public static ObjectPooling instance;
[SerializeField] public GameObject objectToPool;
private List<GameObject> cannonBalls = new List<GameObject>();
private int numberOfObjects = 20;
private void Awake()
{
instance = this;
}
// Start is called before the first frame update
void Start()
{
for (int i = 0; i < numberOfObjects; i++)
{
GameObject gameObject = Instantiate(objectToPool);
gameObject.SetActive(false);
cannonBalls.Add(gameObject);
}
}
// Update is called once per frame
void Update()
{
}
public GameObject GetCannonBallObject()
{
for (int i = 0; i < cannonBalls.Count; i++)
{
if (!cannonBalls[i].activeInHierarchy)
{
return cannonBalls[i];
}
}
return null;
}
}
Cannon.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Cannon : MonoBehaviour
{
[SerializeField] private Rigidbody2D rb;
[SerializeField] private GameObject cannonBall;
[SerializeField] private Transform cannonBallPosition;
void Start()
{
}
private void Update()
{
Fire();
}
private void Fire()
{
cannonBall = ObjectPooling.instance.GetCannonBallObject();
if(cannonBall != null)
{
cannonBall.transform.position = cannonBallPosition.position;
cannonBall.SetActive(true);
}
}
}
CannonBall.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CannonBall : MonoBehaviour
{
private float speed = 10f;
[SerializeField] private Rigidbody2D rb;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
rb.velocity = Vector2.left * speed;
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("FloorAndWall"))
{
// Destroy(this.gameObject);
gameObject.SetActive(false);
}
}
}
Why is you cannonball static? Have your tried not having it marked as static? Also, this problem has nothing to do with object pooling. Make sure that when your objects are enabled, all the components are active. Finally, when working with rigidbodies, you should handle them inside FixedUpdate(), and not inside Update().
I get an error, Assets\scripts\Skins.cs(9,12): error CS0116: A namespace cannot directly contain members such as fields or methods on the Internet they write what it means incorrectly placed brackets, but I don’t see any errors
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public GameObject choise1;
public GameObject choise2;
public GameObject choise3;
public int skin = 1;
public class Skins : MonoBehaviour {
void Choise () {
if (Input.GetMouseDown(choise1)){
choise2.SetActive (false);
}
}
}
GameObject and that int skin need to be under Skins class, like Choise
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Skins : MonoBehaviour {
public GameObject choise1;
public GameObject choise2;
public GameObject choise3;
public int skin = 1;
void Choise () {
if (Input.GetMouseDown(choise1)){
choise2.SetActive (false);
}
}
}
If you still have some problems here, because I don't know what are u trying to do with that choiseX, maybe you need to create them.
I mean, maybe u are trying to write something like this
void Choise () {
var GameObject choise1 = new GameObject();
var GameObject choise2 = new GameObject();
var GameObject choise3 = new GameObject();
int skin = 1;
if (Input.GetMouseDown(choise1)){
choise2.SetActive (false);
}
}
In Unity I have 2 GameObjects, a sphere and a capsule.
And I have a script attached to each.
Capsule script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CapsuleMesh : MonoBehaviour
{
public Mesh capsuleMesh;
void Awake()
{
capsuleMesh = GetComponent<MeshFilter>().mesh;
Debug.Log(capsuleMesh);
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
Sphere script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChangeMesh : MonoBehaviour
{
Mesh mesh;
void Awake()
{
mesh = GetComponent<MeshFilter>().mesh;
Debug.Log(mesh);
}
// Start is called before the first frame update
void Start()
{
mesh = capsuleMesh;
}
// Update is called once per frame
void Update()
{
}
}
The mesh = capsuleMesh here is giving me an error about "the name capsuleMesh does not exist in the current context".
I thought that making capsuleMesh public in the other script would make THIS script be able to access it without issue.
What am I doing wrong?
capsuleMesh is a class variable defined in the CapsuleMesh class. It's not a global variable you can use everywhere. You need a reference to the instance of the CapsuleMesh class to retrieve the mesh stored in the capsuleMesh variable.
I've reworked your both scripts to make them work. I've spotted a flaw in your scripts. I guess ChangeMesh is meant to change the mesh of the gameObject? If so, you need to assign a new value to the meshFilter.mesh. Assigning a new reference to the mesh class variable is not enough (it would be pretty long to explain why)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CapsuleMesh : MonoBehaviour
{
public Mesh Mesh
{
get ; private set;
}
void Awake()
{
Mesh = GetComponent<MeshFilter>().mesh;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChangeMesh : MonoBehaviour
{
// Drag & drop in the inspector the gameObject holding the `CapsuleMesh` component
public CapsuleMesh CapsuleMesh;
private MeshFilter meshFilter;
void Awake()
{
meshFilter = GetComponent<MeshFilter>();
}
void Start()
{
meshFilter.mesh = CapsuleMesh.Mesh;
}
}
In the top of script:
public Vector3[] positionsList;
List<Vector3> positions = new List<Vector3>();
In Update: I'm updating the List but i also want to update the array so i can watch the vector3 positions in the inspector while the game is running.
var position = GenerateRandomPositions(objects[0]);
if (!positions.Contains(position))
{
positions.Add(position);
}
Simply make the List public, the inspector can handle it.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ListInInspectorTest : MonoBehaviour {
public List<Vector3> superawesomeListOfVector3s;
void Update () {
if(superawesomeListOfVector3s.Count < 10) {
superawesomeListOfVector3s.Add(Random.insideUnitSphere);
}
}
}
If it is important that the variable is private or protected to other code. you could add the [SerializeField] tag above the variable that you want to see in the inspector. source (https://unity3d.com/learn/tutorials/topics/tips/show-private-variables-inspector)
How can I instantiate a list of GameObject in Unity3D using c#?
I fill the list with prefabs manually in inspector window.
Below is the code I've written in Deck.cs, but I get "Object reference is not set to an instance of an object". If you have a solution with an array, that will be appreciated as well.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
namespace Assets
{
class Deck:MonoBehaviour
{
public List<GameObject> deck;
public void Fill()
{
GameObject c1 = Instantiate(deck[0]);
GameObject c2 = Instantiate(deck[1]);
GameObject c3 = Instantiate(deck[2]);
GameObject c4 = Instantiate(deck[3]);
GameObject c5 = Instantiate(deck[4]);
GameObject c6 = Instantiate(deck[5]);
}
}
}
I also tried doing it with an array and I get 'The object you want to instantiate is null'
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
namespace Assets
{
class Deck:MonoBehaviour
{
public GameObject card1;
public GameObject card2;
public GameObject card3;
public GameObject card4;
public GameObject card5;
public GameObject card6;
public GameObject[] deck;
public void Start ()
{
deck = new GameObject[5];
GameObject c1 = Instantiate(card1) as GameObject;
GameObject c2 = Instantiate(card2) as GameObject;
GameObject c3 = Instantiate(card3) as GameObject;
GameObject c4 = Instantiate(card4) as GameObject;
GameObject c5 = Instantiate(card5) as GameObject;
GameObject c6 = Instantiate(card6) as GameObject;
}
}
}
Well considering your comments and that the first script your provided works perfectly without any error (as it should: there's no reason it should return an error), I feel like you are very new to Unity.
Therefore I'd recommend you to look to the Unity tutorials before anything else (they are quite well made and will help you understand the basics of the engine). You can find the Roll-a-ball tutorial here.
About your question:
1- In the first script, the Fill() method isn't called anywhere, you have to do something like this:
private void Start()
{
Fill();
}
2- This Start() method comes from the MonoBehaviour parent class (as well as the Update() method which is called every frame) and is called once at the beginning of the scene. Look to this chart to understand how unity flow is made.
3- Using a List<GameObject> or a GameObject[] all depends on your situation: if the size of the collection is going to change, go for a list. Otherwise array is advised.
4- Considering your script my guess is it should look like this:
namespace Assets
{
class Deck : MonoBehaviour
{
[SerializeField]
private GameObject[] deck;
private GameObject[] instanciatedObjects;
private void Start()
{
Fill();
}
public void Fill()
{
instanciatedObjects = new GameObject[deck.Length];
for (int i = 0; i < deck.Lenght; i++)
{
instanciatedObjects[i] = Instanciate(deck[i]) as GameObject;
}
}
}
}
You can of course still use lists if needed :)
EDIT:
If you want to use a list you simply have to:
change private GameObject[] instanciatedObjects; to private List<GameObject> instanciatedObjects;
replace instanciatedObjects = new GameObject[deck.Length]; by instanciatedObjects = new List<GameObject>();
replace instanciatedObjects[i] = Instanciated(deck[i]) as GameObject; by instanciateObjects.Add(Instanciated(deck[i]) as GameObject);
Hope this helps,
Use foreach to loop over your List with prefabs, like this:
public List<GameObject> Deck = new List<GameObject>(); // im assuming Deck is your list with prefabs?
public List<GameObject> CreatedCards = new List<GameObject>();
void Start()
{
Fill();
}
public void Fill()
{
foreach(GameObject _go in Deck)
{
GameObject _newCard = (GameObject)Instantiate(_go);
CreatedCards.Add(_newCard);
}
}
Also it's a good habit to name your lists with capital letter.