How i use array of vector3 to list in inspector all vector3 in list? - c#

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)

Related

I'm trying to add multiple camera switches to a vehicle in Unity and I am not sure how to code it

My project is from the "Create with Unity" tutorial unit 1 with a simple vehicle moving down a road. I originally had 1 camera which worked, but when I changed the code to work with multiple cameras I couldn't get the compiler to work.
The 3 cameras are supposed to display different angles of the tank while controlling the vehicle. I assume something is wrong with how I wrote the FollowPlayer.cs "void LateUpdate()" method, but I don't know how to make it work. It all went wrong when I changedthe FollowPlayer class from 1 cam to 3 cams.
The picture shows the unity visuals and all relevant class coding is below.
I'm new to unity and c#, so any help would be appreciated!
MY CAM SWITCH CLASS
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CamSwitch : MonoBehaviour
{
public GameObject cam1;
public GameObject cam2;
public GameObject cam3;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if(Input.GetButtonDown("Switch1"))
{
cam1.SetActive(true);
cam2.SetActive(false);
cam3.SetActive(false);
}
if (Input.GetButtonDown("Switch2"))
{
cam1.SetActive(false);
cam2.SetActive(true);
cam3.SetActive(false);
}
if (Input.GetButtonDown("Switch3"))
{
cam1.SetActive(false);
cam2.SetActive(false);
cam3.SetActive(true);
}
}
}
THE CLASS I THINK I MESSED UP
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FollowPlayer : MonoBehaviour
{
public GameObject player;
public Vector3 offset1= new Vector3(0, 5, -7);
public Vector3 offset2 = new Vector3(0, 3.83, -7);
public Vector3 offset3 = new Vector3(0, 7.68, -11.8);
public GameObject cam1;
public GameObject cam2;
public GameObject cam3;
cam1.SetActive(true)
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void LateUpdate()
{
if (cam1.SetActive(true))
{
transform.position = player.transform.position + offset1;
}
if (cam2.SetActive(true))
{
transform.position = player.transform.position + offset2;
}
if (cam3.SetActive(true))
{
transform.position = player.transform.position + offset3;
}
}
}
First: remove the line cam1.SetActive(true) under public GameObject cam3;. Its missing a semicolon and it must be placed in a function scope anyway, not in class declaration scope.
Second: this statement (and the other two) if (cam1.SetActive(true)) cant work because SetActive does not return a bool value. You probably wanted if (cam1.activeSelf).
You may spend some time improving your knowledge C# coding basics in Unity

Unity Says There is No Namespace called "Player"

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)

Why the waypoints list and the agents list are empty?

I created a WaypointsClass class :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using System;
using UnityEngine.AI;
[Serializable]
public class WaypointsClass
{
public List<Transform> points = new List<Transform>();
public List<NavMeshAgent> agents = new List<NavMeshAgent>();
}
Then created WaypointsAI script :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WaypointsAI : MonoBehaviour
{
public WaypointsClass waypoints;
public float distanceToContinue;
private float currentDistanceToPoint;
private int lastPointIndex;
private int goalPointIndex;
void Start()
{
//Firstly check if the waypoints are set up correctly
if (waypoints.points.Count < 1)
{
Debug.LogError("Set up the waypoints for this gameObject!");
}
else
{
//Now set up the path
lastPointIndex = 0; //Start from the index 0
waypoints.agents[0].transform.position = waypoints.points[0].position;
if (waypoints.points.Count > 1)
{
goalPointIndex = 1; //Go to the [1] waypoint
}
else
{
goalPointIndex = 0;
}
}
}
void FixedUpdate()
{
for (int i = 0; i < waypoints.agents.Count; i++)
{
//Calculate the distance and check if it should move to the next waypoint.
currentDistanceToPoint = Vector3.Distance(waypoints.agents[i].transform.position, waypoints.points[goalPointIndex].position);
if (currentDistanceToPoint <= distanceToContinue)
{
//Save the old index, totally useless in this implementation though
lastPointIndex = goalPointIndex;
//Increase goal index to change the goal waypoint to the next, (Or maybe random one?)
goalPointIndex++;
if (goalPointIndex >= waypoints.points.Count)
goalPointIndex = 0;
}
//Now move towards the current waypoint, Change this to fit your code with navMesh anyway I think I did a lot for you anyway
waypoints.agents[i].transform.LookAt(waypoints.points[goalPointIndex].position);
waypoints.agents[i].transform.Translate(Vector3.forward * Time.deltaTime * 10);
}
}
}
Then added for each group of agents and waypoints a script. Red and Blue :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class RedWaypoints : MonoBehaviour
{
public GameObject[] redWaypoints;
public NavMeshAgent redAgent;
// Start is called before the first frame update
void Start()
{
redWaypoints = GameObject.FindGameObjectsWithTag("Red_Waypoint");
WaypointsClass wpc = new WaypointsClass();
foreach (GameObject point in redWaypoints)
{
wpc.points.Add(point.transform);
}
wpc.agents.Add(redAgent);
}
// Update is called once per frame
void Update()
{
}
}
And blue :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class BlueWaypoints : MonoBehaviour
{
public GameObject[] blueWaypoints;
public NavMeshAgent blueAgent;
// Start is called before the first frame update
void Start()
{
blueWaypoints = GameObject.FindGameObjectsWithTag("Blue_Waypoint");
WaypointsClass wpc = new WaypointsClass();
foreach (GameObject point in blueWaypoints)
{
wpc.points.Add(point.transform);
}
wpc.agents.Add(blueAgent);
}
// Update is called once per frame
void Update()
{
}
}
Then I created in the Hierarchy and in the Scene group of red waypoints and red character and group of blue waypoints with blue character :
What I want to do the main goal is to move the blue character between the blue waypoints and move the red character between the red waypoints using the same WaypointsAI script. And if the blue group will have 5 character then move the 5 character between the blue waypoints same if the red group will have 50 characters they will move between the red waypoints.
The first problem for now is that the lists points and agents are empty in the WaypointsAI script.
I added a break point to this line :
if (waypoints.points.Count < 1)
And both lists are empty.
I tried to move the code in the Start() in both scripts RedWaypoints and BlueWaypoints to the Awake() and it does a new instance for the WaypointsClass class but when it's getting to the WaypointsAI scripts the lists are empty. I can't figure out why.
Even simpler in this screenshot I have two characters the one in t pose and the droid with the blue circle in the middle. and I want each one to move between other waypoints. one can move up the stairs and back the other move to the window and back :
Your problem : you cant access to the instance of class created in another script.
If i have understood your problem... I suggest you to use Static Class and Static list so you could access from anyscripts:
public static class Waypoints
{
public static List<Transform> Redpoints = new List<Transform>();
public static List<NavMeshAgent> Redagents = new List<NavMeshAgent>();
public static List<Transform> Bluepoints = new List<Transform>();
public static List<NavMeshAgent> Blueagents = new List<NavMeshAgent>();
}
public class RedWaypoints : MonoBehaviour
{
public GameObject[] redWaypoints;
public NavMeshAgent redAgent;
// Start is called before the first frame update
void Start()
{
redWaypoints = GameObject.FindGameObjectsWithTag("Red_Waypoint");
foreach (GameObject point in redWaypoints)
{
Waypoints.Redpoints.Add(point.transform);
}
Waypoints.Redagents.Add(redAgent);
}
:
:
}
public class BlueWaypoints : MonoBehaviour
{
public GameObject[] blueWaypoints;
public NavMeshAgent blueAgent;
// Start is called before the first frame update
void Start()
{
blueWaypoints = GameObject.FindGameObjectsWithTag("Blue_Waypoint");
foreach (GameObject point in blueWaypoints)
{
Waypoints.Bluepoints.Add(point.transform);
}
Waypoints.Blueagents.Add(blueAgent);
}
:
:
}
From another Script, if you want to access first Red point item, you just type Waypoints.Redpoints[0] and for your First Red agent you just type Waypoints.Redagents[0] and same thing for blue side
In WaypointsAI you dont need to declare public WaypointsClass waypoints;

Change Sprite array to GameObject array in Unity

[EDIT]: current inspector output image
I'm beginning with unity and I want to convert this public array of sprites into a public array of gameobjects. How would I do this?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Obstacle : MonoBehaviour, IRecyle
{
public Sprite[] sprites;
public void Restart()
{
var renderer = GetComponent<SpriteRenderer>();
renderer.sprite = sprites[Random.Range(0, sprites.Length)];
}
public void Shutdown()
{
}
}
if you have prefabs with the sprites you want to use try to change your code:
this:
public Sprite[] sprites;
to this:
public GameObject[] spriteGameObjects;`
and also this:
renderer.sprite = sprites[Random.Range(0, sprites.Length)];
to this:
renderer.sprite = spritesGameObjects[Random.Range(0, spritesGameObjects.Length)]
.GetComponent<SpriteRenderer>().sprite;
I don't have access to Unity right now, so I haven't checked if it's working, but I think it should.
Kindly let me know if this helps or not.

Instantiating a list of gameobjects in Unity C#

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.

Categories