I listened to the youtube unity tutorial https://www.youtube.com/watch?v=gCqOnchV4V0&t=2491s, in which it talked about defining singleton (at 59:29) like this:
public class GameManager : MonoBehaviour
{
public static GameManager Instance { get; private set; }
int scoreCount=0;
//...
}
//when using the instance:
class Player : MonoBehaviour
{
//...
GameManager.Instance.scoreCount++;
//...
}
This method works in the first small unity game I made. However, when I use it the second time I failed to create an instance. Thus I decided to test it again.
using System;
namespace ConsoleApp1
{
class classiii
{
static void Main(string[] args)
{
string input = Console.ReadLine();
int result = Int32.Parse(input);
Console.WriteLine(Program.Instance.A(result));
Console.ReadLine();
}
}
class Program
{
public static Program Instance { get; private set; }
int firstNum = 5;
public int A(int tmp)
{
return firstNum + tmp;
}
}
}
So why is this not working? Why is it working in the first unity project?
Related
I'm trying to cut down on how much duplication I have on my code, so I decided to make one of my classes a static class since I decided that its data should really be shared with everyone. Here's the static method below:
// A static class, that holds all object's coordinates, and methods to return & update their values.
internal static class Coordinate
{
private static int[,] PlayerCoordinate { get; set; }
public static int[,] GateCoordinate { get; }
public static int[,] FountainCoordinate { get; }
static Coordinate() // FIRST VALUE IS X (column), SECOND VALUE IS Y (row).
{
PlayerCoordinate = new int[,] { { 0, 0 } };
GateCoordinate = PlayerCoordinate; // Just starts off in the same place as player.
FountainCoordinate = new int[,] { { 2, 0 } };
}
// A static method, that sends the data of all object coordinates, deconstructed into seperate ints.
public static int PlayerColumn() { return PlayerCoordinate[0, 0]; }
public static int PlayerRow() { return PlayerCoordinate[0, 1]; }
public static int GateColumn() { return GateCoordinate[0, 0]; }
public static int GateRow() { return GateCoordinate[0, 1]; }
public static int FountainColumn() { return FountainCoordinate[0, 0]; }
public static int FountainRow() { return FountainCoordinate[0, 1]; }
// Updates the coordinates of the player.
public static void UpdatePlayerCoordinate(int column, int row) { PlayerCoordinate = new int[,] { { column, row } }; }
}
The main issue comes in from my GameManager class. On the console, the beginning section should print out "You are the room at (Column=0, Row=0), but it prints this instead:
Here is the code for my GameManager class:
internal class GameManager
{
private bool IsGameOver;
private Player Player;
private Updater Updater;
// Don't need to call Fountain or Coordinate since they're static
public GameManager()
{
IsGameOver = false;
Player = new();
Updater = new();
}
public void RunGame()
{
while (!IsGameOver)
{
Console.WriteLine("----------------------------------------------------------");
Updater.DisplayPlayerPosition(); // This is the main line that I'm having issues with as of right now. All other functions past this are another problem.
Updater.DisplayPlayerSenses();
string playerInput = Player.GetInput();
Updater.MovePlayer(playerInput);
IsGameOver = Updater.CheckForWin();
}
}
}
And just to make sure, here is the code from my updater class, with the specific method that I'm having issues with:
internal class Updater
{
// No fields
// Default constructor
// Gets the text to show the player his current position.
public void DisplayPlayerPosition() // This is the method that I'm having issues with.
{
Console.WriteLine($"You are in the room at (Column={Coordinate.PlayerColumn}, Row={Coordinate.PlayerRow})");
}
...
I'm fairly new to the static keyword so I believe that I may be missing smth. I personally believe that it's because the class itself hasn't been initialized (like I haven't called the constructor for the Coordinate class, and apparently you can't call a static constructor anyways), but that's just me. If I could get any help, I'd greatly appreciate it!
PlayerColumn() and PlayerRow() are methods, but you are accesing them in the WriteLine statement as if they are properties.
Update your WriteLine to:
Console.WriteLine($"You are in the room at (Column={Coordinate.PlayerColumn()}, Row={Coordinate.PlayerRow()})");
I want to create public Scene[] levels; and manually assign my levels to the array, then loop through it and generate level selection buttons, but it won't show up in the inspector.
Is there any workaround?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class True : MonoBehaviour
{
// Start is called before the first frame update
public static int money;
[SerializeField]
public SceneManager[] scenes;
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public void nextscencefirst()
{
SceneManager.LoadScene("Level2");
money++;
}
}
SceneManager is a built-in static class to control scenes during runtime. We can go to any scene by calling LoadScene method from that class. Also SceneManager cannot be seen in Inspector since it cannot be serialized class.
A reminder: Your scenes should be listed on build settings for these to work.
There are three ways to do what you want to do:
Method 1. Create a string list that holds names of scenes
public List<string> sceneNameList = new List<string>;
Method 2. Create a list of indices of scenes that added in build settings.
public List<int> sceneBuildIndexList = new List<int>
If the names of scenes are long or somehow difficult or you want to use sceneBuildIndex value it would be good to create a class and reach scenes from it
[System.Serializable]
public class SceneData
{
public int sceneBuildIndex;
public string sceneKey;
//public void LoadScene() //Maybe
}
public List<SceneData> sceneDataList = new List<SceneData>();
public SceneData GetSceneData(string key)
{
for (int i = 0; i < sceneDataList.Count; i++)
{
if (sceneDataList[i].sceneKey == key)
{
return sceneDataList[i];
}
}
return null;
}
Method 3: In Unity most classes are created from UnityEngine.Object, so it may let you assign scene from the Inspector.
[System.Serializable]
public class SceneData
{
public UnityEngine.Object scene;
public string key;
public void LoadScene()
{
if (scene == null)
{
Debug.LogError("Scene is not assigned");
return;
}
string pathToScene = AssetDatabase.GetAssetPath(scene);
SceneManager.LoadScene(pathToScene); //If the scene is not set in BuildSettings it will throw an error.
}
}
public List<SceneData> sceneDataList = new List<SceneData>();
public SceneData GetSceneData(string key)
{
for (int i = 0; i < sceneDataList.Count; i++)
{
if (sceneDataList[i].key == key)
{
return sceneDataList[i];
}
}
return null;
}
private void Awake()
{
SceneData data = GetSceneData("Level1");
if (data != null)
{
data.LoadScene();
}
}
Basically I am using Unity and it used c#. I want to program procedurally. Can I mimick this with static namespaces and static classes, so that I can use the static namespaces as "header files", so I dont have to instantiate a bunch of singletons. How is this performance wise?
For example:
namespace Balls
{
public static Ball [] balls;
public static class Balls
{
public static void UpdateBalls (){}
}
}
Another file:
using static Balls;
namespace Player
{
public static class Player
{
public static bool PlayerAlive;
public static Vector3 position;
public static void UpdatePlayer ()
{
for (int i=0; i<balls.Length; i++)
{
if (position == balls[i].position)
{
PlayerAlive = false;
}
}
}
}
}
Another file:
using static Balls;
using static Player;
namespace Main
{
public static class Main
{
public static void MainUpdate ()
{
if (PlayerAlive)
{
UpdateBalls ();
UpdatePlayer ();
}
}
}
}
Here is the code I am using:
public enum TargetingOptions
{
NoTarget,
AllCreatures,
EnemyCreatures,
YourCreatures,
AllCharacters,
EnemyCharacters,
YourCharacters
}
public enum Faction
{
Fog,
Imperial,
Monster,
Pirate
}
public class CardAsset : ScriptableObject
{
public CharacterAsset characterAsset;
[TextArea(2, 3)]
public string Description;
public Sprite CardImage;
public int ManaCost;
[Header("Faction")]
public Faction faction;
[Header("Creature Info")]
public int MaxHealth;
public int Attack;
public int AttacksForOneTurn = 1;
public bool Charge;
public string CreatureScriptName;
public int specialCreatureAmount;
[Header("SpellInfo")]
public string SpellScriptName;
public int specialSpellAmount;
public TargetingOptions Targets;
}
what I am trying to do is create a different "hand" of cards depending on faction. to do this I have created a separate "hand" script for each of the factions, but I want to create a "handmultiple" script that will choose which "hand faction" script to head to.
So if in unity "pirate" is chosen, then all that will appear would be the associated scripts (ignoring fog, imperial and pirate scripts)
Does that make sense?
thank you!
enter code here using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using DG.Tweening;
public class HandVisualImperial : MonoBehaviour
{
public AreaPosition owner;
public bool TakeCardsOpenly = true;
public SameDistanceChildren slots;
[Header("Transform References")]
public Transform DrawPreviewSpot;
public Transform DeckTransform;
public Transform OtherCardDrawSourceTransform;
public Transform PlayPreviewSpot;
private List<GameObject> CardsInHand = new List<GameObject>();
public void AddCard(GameObject card)
{
CardsInHand.Insert(0, card);
card.transform.SetParent(slots.transform);
PlaceCardsOnNewSlots();
UpdatePlacementOfSlots();
}
public void RemoveCard(GameObject card)
{
CardsInHand.Remove(card);
PlaceCardsOnNewSlots();
UpdatePlacementOfSlots();
}
So I think I have it figured out:
Have a whole bunch more work to do before testing it unfortunately.. but I believe I have it done now... Thank you all for the help!!!
public class HandVisualMultiple : MonoBehaviour
{
Faction factiontype;
public HandVisualFog fog;
public HandVisualImperial imperial;
public HandVisualMonster monster;
public HandVisualPirate pirate;
void Start()
{
fog = GetComponent<HandVisualFog>();
imperial = GetComponent<HandVisualImperial>();
monster = GetComponent<HandVisualMonster>();
pirate = GetComponent<HandVisualPirate>();
if (factiontype == Faction.Fog)
{
fog.enabled = true;
imperial.enabled = false;
monster.enabled = false;
pirate.enabled = false;
}
else if (factiontype == Faction.Imperial)
{
fog.enabled = false;
imperial.enabled = true;
monster.enabled = false;
pirate.enabled = false;
}
else if (factiontype == Faction.Monster)
{
fog.enabled = false;
imperial.enabled = false;
monster.enabled = true;
pirate.enabled = false;
}
else if (factiontype == Faction.Pirate)
{
fog.enabled = false;
imperial.enabled = false;
monster.enabled = false;
pirate.enabled = true;
}
}
}
It's not the answer for your question, but an experienced game developer advice.
Try to use Polimorfism. A single main class. "class Creature" and then a lot of child classes class ImperialCreature:Creature, class PirateCreature:Creature and then set the parameters to each of them.
And later you can set another sub classes. for instance: class JackSparrow:PirateCreature ... and on...
The enum is similar to an array, so if you do (int)Faction.Fog it will return 0 since it's the first item. You could have an array or list with your scripts in the same order as your enum and call them by casting the enum to an int
im trying to use this method to make my characters but i get the error:
inconsistent accessibility:return type'consoleapplication1.Enemigo' is less accesible than
method 'consoleapplication1.poringbuilder.makeporing()'
its the first time i get this error and i really dont know what to do,i have tried alot of different ways but i get the same mistake plz help >.<
namespace ConsoleApplication1
{
public static class PoringBuilder
{
public static Enemigo MakePoring()
{
return new Enemigo(15, 0, 30,15, false, false,"Poring");
}
}
this is another class
namespace ConsoleApplication1
{
class Enemigo:Personaje
{
public Enemigo(int Damage, int Defensa, int HP,int MP, bool Evade, bool Counter, string Nombre)
: base(Damage, Defensa, HP,MP, Evade, Counter, Nombre)
{
}
}
}
this is the parent of all my classes
namespace ConsoleApplication1
{
class Personaje
{
public int Damage;
public int Defensa;
public int HP;
public int MP;
public bool Evade;
public bool Counter;
public string Nombre;
//public Personaje() { }
public Personaje(int Damage, int Defensa, int HP,int MP, bool Evade, bool Counter, string Nombre)
{
this.Damage = Damage;
this.Defensa = Defensa;
this.HP = HP;
this.MP = MP;
this.Evade = Evade;
this.Counter = Counter;
this.Nombre = Nombre;
}
}
}
and im using it on the main program like this
List<Enemigo> EnemigosNoob = new List<Enemigo>();
EnemigosNoob.Add(PoringBuilder.MakePoring());
i hope im precise enough >.< i tried making it public and its not solving anything >.<
Your MakePoring method is public, while your Enemigo class is not.
You need to declare the Enemigo class as public:
public class Enemigo
Your class Enemigo is private in the namespace. You need to declare it as public.