- Home /
Copying lists cross-class not working correctly
So, this is a bit of a big one, but I'm currently working for a hat/vanity system for my game. I want the player to be able to unlock and select the desired hat, currently using a large array of all hats and lists of unlocked hats. The scripts themselves are a bit lengthy, but I'll do my best to slim them down to what's necessary.
TL;DR at bottom.
The GameManagerScript's here:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class GameManagerScript : MonoBehaviour
{
private GameObject player;
private GameObject vanityManager;
public Hat[] hats;
public List<Hat> ownedHats;
public Sprite hat;
void OnEnable() {SceneManager.sceneLoaded += OnSceneLoaded; }
void OnDisable(){SceneManager.sceneLoaded -= OnSceneLoaded;}
private bool newHat;
void addHat(int hat)
{
ownedHats.Add(hats[hat]);
newHat = true;
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
if (scene.buildIndex == 1)
{
vanityManager = GameObject.FindGameObjectWithTag("VanityManager");
GameObject newHatText = GameObject.FindGameObjectWithTag("NewHatText");
newHat = false;
if (coins >= 5)
{
addHat(3);
}
if (coins >= 10)
{
addHat(4);
}
//...etc, for about 10 more or so
if (newHat == true)
{
newHatText.SetActive(true);
}
vanityManager.GetComponent<VanityManagerScript>().ownedHats = ownedHats; //THIS IS THE LINE THAT BREAKS THE CODE
}
}
//DontDestroyOnLoad
private static GameManagerScript gameManager;
void Awake()
{
if (gameManager == null)
{
gameManager = this.gameObject.GetComponent<GameManagerScript>();
GameObject.DontDestroyOnLoad(this);
}
else
{
Destroy(gameObject);
}
}
}
And the VanityManagerScript's here:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class VanityManagerScript : MonoBehaviour
{
public List<Hat> ownedHats;
public GameObject hat;
public Text hatName;
private GameObject gameManager;
private int index = 1;
void SetHat()
{
if(ownedHats[index] == null)
{
Color tempColor = hat.GetComponent<Image>().color;
tempColor.a = 0f;
hat.GetComponent<Image>().color = tempColor;
gameManager.GetComponent<GameManagerScript>().hat = null;
hatName.text = "None";
}
else
{
hat.GetComponent<RectTransform>().sizeDelta = new Vector2((ownedHats[index].hatSprite.bounds.size.x/2) * 100, 66);
gameManager.GetComponent<GameManagerScript>().hat = ownedHats[index].hatSprite;
hat.GetComponent<Image>().sprite = ownedHats[index].hatSprite;
hatName.text = ownedHats[index].hatName;
Color tempColor = hat.GetComponent<Image>().color;
tempColor.a = 1f;
hat.GetComponent<Image>().color = tempColor;
}
}
public void increment()
{
if(index >= ownedHats.Count - 1)
{
index = 1;
}
else
{
index++;
}
SetHat();
}
public void decrement()
{
if (index <= 1)
{
index = ownedHats.Count - 1;
}
else
{
index--;
}
SetHat();
}
private void Start()
{
ownedHats = new List<Hat>();
gameManager = GameObject.FindGameObjectWithTag("GameController");
}
}
Apologies for messy code, I didn't expect to be this alienated by errors...
know I'm working with lists wrong-previously I've stuck to arrays. I tried initializing lists in both places( listName = new List(); I believe ) and it's either produced more errors or stagnated.
TL;DR
The key problem is copying the lists between the two GameObjects without deleting the two. I've tried all solutions I could find on the forums. Just in case, I'm using 2019.3.0a11.
Thanks for your help, I know this is a big one.
Answer by prof · Nov 17, 2019 at 06:36 PM
Before jumping into unity, learn basic coding first. Youtube has plenty tutorals on both c# and general coding.
public class ListHolder : MonoBehaviour{
[SerializeField] private List<GameObject> originList;
public List<GameObject> GetListReference(){
return originList;
}
public List<GameObject> GetListCopy(){
return new List<GameObject>(originList);
}
}
public class ListReceiver : MonoBehaviour{
public GameObject ListHolder;
[SerializeField] private List<GameObject> listReference;
[SerializeField] private List<GameObject> listCopy;
private void Start(){
listReference = ListHolder.GetComponent<ListHolder>().GetListReference();
listCopy = ListHolder.GetComponent<ListHolder>().GetListCopy();
}
}
Lists in c# are refernce type. If you need a copy, create a new list
This is helpful, I'll utilize it in my code. I've been program$$anonymous$$g for about four to five years now and never encountered lists, maybe once or twice in JS and Python; C# not at all. It's an unfamiliar topic to me. I learned all my program$$anonymous$$g from specific classes, so I've been trying to branch out, using more familiar things like Unity Learn and C# 7.0 In a Nutshell. I'd always used arrays up until now, but that's beside the point. I've been trying to $$anonymous$$ch myself what online and in-person classes couldn't.
Here's a piece of advice then. Don't know what class does? Google it. Quick overview of c# by Derek Banas (including lists)
Wow... kinda disappointed with myself... I was initializing the lists in Start and Awake, not upon the creation of the lists. All working now, the C# Survival Guide's been really helpful. Thanks for pointing me in the right direction.
Your answer
Follow this Question
Related Questions
Performance question - Loading large-ish amounts of text data in a mobile game? 1 Answer
Convert list of floats to float array 1 Answer
Using similar to GameObject.FindObjectsWithTag but for tag.contains. 0 Answers
List/Array should handle another List/Array - Upgrade System - Performance 1 Answer
Undo/back system using a List/Array 2 Answers