Unity C# Getting info from Switch cases and using it in unity - c#

Im making a game for school and Im trying to get this data from the switch:
public void planets()
{
switch(PlanetType)
{
case planetType.Desert:
Debug.Log("Desert");
maxFuel = 500;
break;
case planetType.Ruined:
Debug.Log("Ruined");
maxFuel = 1500;
break;
case planetType.Lush:
Debug.Log("Lush");
maxFuel = 3000;
break;
}
}
per scene for that specific planet as the maxFuel in the slider in that scene
I have the enum and that stuff, but for some reason in Unity, it only takes the input max fuel in unity and doesnt want to take the max fuel from the switchcase. Any quick fixes?

Related

How to simplify animation transaction

In 2D scene, I have 3 idle states and 3 walk states (each idle/walk state has 3 direction sub state).
I know I can make transactions in animator.
My question is, how to simplify transaction? For example, idle_front state has 5 transactions to other states (idle_back, idle_right, walk_front, walk_back, walk_right), now if I want to add an attack state, also with 3 direction sub state, the transaction lines makes me crazy.
My solution
I have tried using animator.Play() to play animation, but when switch to attack state, there is a problem.
The invocation of idle state play is in FixedUpdate() event function, after response to the attack key press event (to play attack animation), only little frames of attack is played, it is soon replaced by idle animation.
How can I implement similar effect of a trigger, to play the whole attack animation? Or is there any way to simplify transactions, and continue to use a trigger?
Example code is here
private void FixedUpdate()
{
if (moveInput.y == 0)
{
switch (moveInput.x)
{
case < 0:
animator.SetInteger(Direction, (int) MovingDirection.Left);
animator.Play("player_walk_right");
spriteRenderer.flipX = true;
break;
case > 0:
animator.SetInteger(Direction, (int) MovingDirection.Right);
animator.Play("player_walk_right");
spriteRenderer.flipX = false;
break;
}
}
else
{
switch (moveInput.y)
{
case < 0:
animator.SetInteger(Direction, (int) MovingDirection.Down);
animator.Play("player_walk_front");
break;
case > 0:
animator.SetInteger(Direction, (int) MovingDirection.Up);
animator.Play("player_walk_back");
break;
}
}
}
void OnFire()
{
switch (animator.GetInteger(Direction))
{
case (int) MovingDirection.Up:
animator.Play("player_attack_back");
break;
case (int) MovingDirection.Down:
animator.Play("player_attack_front");
break;
case (int) MovingDirection.Left:
animator.Play("player_attack_right");
spriteRenderer.flipX = true;
break;
case (int) MovingDirection.Right:
animator.Play("player_attack_right");
spriteRenderer.flipX = false;
break;
}
}
You just need to stop moving while the attack animation is playing. To know when the animation is end, one way is using events https://docs.unity3d.com/Manual/AnimationEventsOnImportedClips.html
First you need to add an event near the end of the animation, let's name it OnAttackEnd.
NOTE! To ensure the script can receive the event, the script and the animator must be attached on the same GameObject.
In the script add a boolean field to indicate if attack anim is playing and the OnAttackEnd callback.
bool _isAttackAnimPlaying;
void OnAttackEnd()
=> _isAttackAnimPlaying = false;
In OnFire method, set the boolean field to true, and in FixedUpdate method check the value.
void OnFire()
{
switch (animator.GetInteger(Direction))
{
case (int) MovingDirection.Up:
animator.Play("player_attack_back");
_isAttackAnimPlaying = true;
....
}
}
private void FixedUpdate()
{
if(!_isAttackAnimPlaying)
{
.....
}
}

Question On Sequential Attacks / Finishing Sequence Early

I'm working on a top down game where when you press the attack button multiple times there's a 3 hit sequence. I have the 3 hit sequence working just fine, but I have two problems I can't seem to find a solution to through my google fu.
When the sequence is finished, I don't have a good way to transition back to the idle state.
When you press the button once or twice, I'm not sure how I can tell whether you haven't pressed the button again in a long enough time to decide the sequence has been cancelled.
(I'm using a state machine I made for the character controller, and the states don't inherit from monobehavior so I don't have access to coroutines in this attack state)
Here is the code, I would really appreciate some feedback and help.
private string currentAttack = "Attack1";
public AttackingState(Character character, StateMachine stateMachine)
: base(character, stateMachine)
{
}
public override void Action()
{
if (Input.GetKeyDown(KeyCode.Space))
{
switch (currentAttack)
{
case "Attack1":
{
this.character.SetTrigger("Attack2");
this.currentAttack = "Attack2";
break;
}
case "Attack2":
{
this.character.SetTrigger("Attack3");
this.currentAttack = "Attack3";
break;
}
case "Attack3":
{
this.character.SetTrigger("Attack1");
this.currentAttack = "Attack1";
break;
}
default:
break;
}
}
if (Input.GetAxis("Horizontal") != 0 || Input.GetAxis("Vertical") != 0)
{
character.SetTrigger("AttackCancelled");
stateMachine.SetState<WalkingState>(new WalkingState(character, stateMachine));
currentAttack = "Attack1";
}
}
public override void OnStateEnter()
{
base.OnStateEnter();
character.SetTrigger("Attack1");
}
you could track a timestamp since the last press and do something like
// stores the last attack time
private float lastAttackTime;
// whereever you want to assign this value from
// The delay before the attack is reset and starts over from 1
private const float MAX_ATTACK_INTERVAL = 1f;
if (Input.GetKeyDown(KeyCode.Space))
{
// Time.time is the time in seconds since the app was started
if(Time.time - lastAttackTime > MAX_ATTACK_INTERVAL)
{
// start over
// mimics the attack3 since there you start over at 1
currentAttack = "Attack3";
}
lastAttackTime = Time.time;
switch (currentAttack)
{
...
}
}
In general instead of string I would recommend either a simple int or an enum instead.

Why does my Enum parameter goes back to default value?

I have created 4 levels, but I'm stuck in the first two because my enum Level keeps going back to default=level_1.
So I'm stuck between levels 1 and 2. Why does my parameters go back to initial/default value?
This is true as well for any other parameters (int) I've tried.
I have already refreshed the scenes in the build setting.
//the enum parameter I use
enum Level { Level_1, Level_2, Level_3, Level_4 };
Level currentLevel = Level.Level_1;
//the loading next scene function
private void LaodNextScene()
{
switch (currentLevel)
{
case Level.Level_1:
{
print("loading level 2");
currentLevel = Level.Level_2;
SceneManager.LoadScene("Level_2");
break;
}
case Level.Level_2:
{
print("loading level 3");
currentLevel = Level.Level_3;
SceneManager.LoadScene("level_3");
break;
}
case Level.Level_3:
{
print("loading level 4");
currentLevel = Level.Level_4;
SceneManager.LoadScene("level_4");
break;
}
case Level.Level_4:
{
print("loading level 4 again");
SceneManager.LoadScene("level_4");
break;
}
default:
print("invalid level");
break;
}
}
//the loading first scene function
private void LaodFirstScene()
{
currentLevel = Level.Level_1;
SceneManager.LoadScene(currentLevel.ToString());
}
I expect to be able to move forward in my levels, but I'm stuck in the first two:
When I die - level 1 restarts.
When I win - level 1 goes to level 2, however level 2 restarts itself.
Within the switch statement you set currentLevel to the next level, then you load a new scene. I suspect that when the new scene loads currentLevel = Level.Level_1 is called again and resets currentLevel
You can try and replace that line to something like currentLevel = (Level)SceneManager.GetActiveScene().buildIndex;
or you can make a Game Manager that keeps track of the current level with the singleton approach. It's a bit more complicated but probably a more elegant solution.
If you want to know more about singletons:
https://www.youtube.com/watch?v=CPKAgyp8cno
https://www.studica.com/blog/how-to-create-a-singleton-in-unity-3d
https://gamedev.stackexchange.com/questions/116009/in-unity-how-do-i-correctly-implement-the-singleton-pattern

Destroy instantiated prefabs with a same tag, one by one, from last instantiated to first?

I am trying to destroy instantiated prefabs with a same tag, one by one, from last instantiated to first, and I am stuck on how to accomplish this.
The idea is that I want to have a custom editor, which would allow me to instantiate multiple prefabs and then "undo" the last instantiation with two GUI buttons - "Place object" and "Undo", respectively.
As of now, I am able to successfully instantiate prefabs, add the same tag to them, and then destroy them one by one, but they are getting destroyed from first to last instantiated.
The code I have so far:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjectInstantiateControl : MonoBehaviour {
public List<GameObject> prefabList = new List<GameObject>();
[HideInInspector]
public int objectSelectionIndex = 0;
GameObject instance;
public void PlaceObject()
{
switch (objectSelectionIndex)
{
case 1:
Debug.Log("Just received a number 1 from the editor");
GameObject object_A = Resources.Load("Object_A") as GameObject;
instance = Instantiate(object_A, this.transform.position, this.transform.rotation, this.transform);
instance.tag = "UsedObject";
prefabList.Add(instance);
break;
case 2:
Debug.Log("Just received a number 2 from the editor");
GameObject object_B = Resources.Load("Object_B") as GameObject;
instance = Instantiate(object_B, this.transform.position, this.transform.rotation, this.transform);
instance.tag = "UsedObject";
prefabList.Add(instance);
break;
case 3:
Debug.Log("Just received a number 3 from the editor");
GameObject object_C = Resources.Load("Object_C") as GameObject;
instance = Instantiate(object_C, this.transform.position, this.transform.rotation, this.transform);
instance.tag = "UsedObject";
prefabList.Add(instance);
break;
case 4:
Debug.Log("Just received a number 4 from the editor, deleting the object");
prefabList.Remove(GameObject.FindWithTag("UsedObject"));
DestroyImmediate(GameObject.FindWithTag("UsedObject"));
break;
}
}
And the part from the editor script for GUI buttons "Place object" and "Undo" :
GUILayout.BeginHorizontal();
if (GUILayout.Button("Place object", GUILayout.Height(25)))
{
ObjectInstantiateControl myScript = (ObjectInstantiateControl)target;
myScript.objectSelectionIndex = 1;
myScript.PlaceObject()();
}
if (GUILayout.Button("Undo", GUILayout.Height(25)))
{
ObjectInstantiateControl myScript = (ObjectInstantiateControl)target;
myScript.objectSelectionIndex = 4;
myScript.PlaceObject();
}
GUILayout.EndHorizontal();
Really need help on this, any ideas or suggestions are welcome. Thanks in advance ;)
In this case i will choose Queue or LinkList. You can add all game object into it and management it will simple and fine in other way.
https://msdn.microsoft.com/en-us/library/system.collections.queue(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/he2s3bh7(v=vs.110).aspx

C#- Console Program Ideas for Noob [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
So, Im a beginning C# programmer. I know basic syntax and simple things like if statements and loops(methods and classes too). I've only used console apps right now havent bothered with windows forms yet.
So any simple app ideas that introduce new things important for C# programming.
Also, NO tutorials. I want to make all by myself.
I'm a big fan of Halo, and one of the first things I did with C# was write an application that downloaded and parsed my online gaming stats while playing Halo 2. From there, I loaded all of the information into a database and redisplayed it in ASP.NET. In retrospect, the code was horrendous, but it was a fun exercise.
Another exercise was to parse the XML file for my iTunes music library, load it into a database, and (of course) display bits of it in ASP.NET.
Anyway, find ways to work with things you enjoy, be it games, music, television, or whatever.
A simple game might be a good start but those code golf questions can be a bit more advanced.
Why not try to write a 'test your reflexes' game, where you output a letter and time how long it takes for that letter to be keyed in? Then display the response time taken and the best response time to date.
Once i had to learn bash scripting for linux by writing the hangman game, it should be a good example for a console app in c#.
Hint:
start with
while(true)
{
//Game code goes here, use "continue" or "break" according to game logic.
}
One fun way to develop your skills is through code katas and programming contests like Top Coder and Google Code Jam. There are tons of example problems that will make you think, and many come with solutions that you can compare against after you are finished.
Even when you've been a developer for a while, these kind of simple problems allow you to incorporate new practices in your programming style (for instance, a kata is a great way to start learning the principles of TDD). Plus, they make for fun distractions.
I think solving Top-Coder problems will be great practice! It's specially suited since all their problems are console based, and they will make you increase not only your knowledge of c#, but also your problem solving skills and your data structure/algorithms knowledge.
That said, you probably wont learn much about new or more platform specific stuff about C#, such as linq, event handlers, threading, parallel tasks library, etc etc. For that, the best would be to find a good C# book and go through it.
Another way could be making little games. I know its console, but you can actually make games like Snake, Pac-man, hangman, etc, of course, with a little extra imagination, but it still works and games are great learning exercises (and are fun to show to people)
Write something recursive, like a routine that calculates the value of a factorial.
I recently developed a sudoku solver and a 8Queens solver.
I made the sudoku solver in console where the puzzle itself was hard coded in the project. You could try to make it possible to use a textfile as an input. I implemented a brute force algorithm witch works with recursion. It's is nice to develop such a solver and once you're ready there probably will be lots of improvements possible.
The 8Queens solver learned me two things. First I had to made a chessboard, which I did with forms. Learned me about Pens, Brushes and drawing. Also it was a nice practice for recursion which you have to do a lot before you understand it...
I'd suggest writing a command-line tool that does something that maybe can't be done by anything else.
The one thing that springs to mind is something that applies XSL stylesheets to XML files and spits out the output. There's sample code everywhere but no straightforward Windows tool that I've seen.
Potential benefits of this approach are that you end up with a useful tool and you then have the option of making it open-source to get additional input/support.
Well they are all tough to do, so i suggest using the copy paste method with my Blackjack app
remember to reference add system speech synth
using System;
using System.Speech.Synthesis;
namespace Blackjack
{
class Blackjack
{
static string[] playerCards = new string[11];
static string hitOrStay = "";
static int total = 0, count = 1, dealerTotal = 0;
static Random cardRandomizer = new Random();
static void Main(string[] args)
{
using (SpeechSynthesizer synth = new System.Speech.Synthesis.SpeechSynthesizer())
{
Console.Title = "Blackjack";
synth.Speak("Please enter your blackjack table's name followed by a comma then the secondary name (AKA table number)");
string bjtn = Console.ReadLine();
Console.Clear();
Console.Title = bjtn;
}
Start();
}
static void Start()
{
dealerTotal = cardRandomizer.Next(15, 22);
playerCards[0] = Deal();
playerCards[1] = Deal();
do
{
Console.WriteLine("Welcome to Blackjack! You were dealed " + playerCards[0] + " and " + playerCards[1] + ". \nYour total is " + total + ".\nWould you like to hit or stay? h for hit s for stay.");
hitOrStay = Console.ReadLine().ToLower();
}
while (!hitOrStay.Equals("h") && !hitOrStay.Equals("s"));
Game();
}
static void Game()
{
if (hitOrStay.Equals("h"))
{
Hit();
}
else if (hitOrStay.Equals("s"))
{
if (total > dealerTotal && total <= 21)
{
Console.WriteLine("\nCongrats! You won the game! The dealer's total was " + dealerTotal + ".\nWould you like to play again? y/n");
PlayAgain();
}
else if (total < dealerTotal)
{
Console.WriteLine("\nSorry, you lost! The dealer's total was " + dealerTotal + ".\nWould you like to play again? y/n");
PlayAgain();
}
}
Console.ReadLine();
}
static string Deal()
{
string Card = "";
int cards = cardRandomizer.Next(1, 14);
switch (cards)
{
case 1: Card = "Two"; total += 2;
break;
case 2: Card = "Three"; total += 3;
break;
case 3: Card = "Four"; total += 4;
break;
case 4: Card = "Five"; total += 5;
break;
case 5: Card = "Six"; total += 6;
break;
case 6: Card = "Seven"; total += 7;
break;
case 7: Card = "Eight"; total += 8;
break;
case 8: Card = "Nine"; total += 9;
break;
case 9: Card = "Ten"; total += 10;
break;
case 10: Card = "Jack"; total += 10;
break;
case 11: Card = "Queen"; total += 10;
break;
case 12: Card = "King"; total += 10;
break;
case 13: Card = "Ace"; total += 11;
break;
default: Card = "2"; total += 2;
break;
}
return Card;
}
static void Hit()
{
count += 1;
playerCards[count] = Deal();
Console.WriteLine("\nYou were dealed a(n) " + playerCards[count] + ".\nYour new total is " + total + ".");
if (total.Equals(21))
{
Console.WriteLine("\nYou got Blackjack! The dealer's total was " + dealerTotal + ".\nWould you like to play again?");
PlayAgain();
}
else if (total > 21)
{
Console.WriteLine("\nYou busted, therefore you lost. Sorry. The dealer's total was " + dealerTotal + ".\nWould you like to play again? y/n");
PlayAgain();
}
else if (total < 21)
{
do
{
Console.WriteLine("\nWould you like to hit or stay? h for hit s for stay");
hitOrStay = Console.ReadLine().ToLower();
}
while (!hitOrStay.Equals("h") && !hitOrStay.Equals("s"));
Game();
}
}
static void PlayAgain()
{
string playAgain = "";
do
{
playAgain = Console.ReadLine().ToLower();
}
while (!playAgain.Equals("y") && !playAgain.Equals("n"));
if (playAgain.Equals("y"))
{
Console.WriteLine("\nPress enter to restart the game!");
Console.ReadLine();
Console.Clear();
dealerTotal = 0;
count = 1;
total = 0;
Start();
}
else if (playAgain.Equals("n"))
{
using (SpeechSynthesizer synth = new System.Speech.Synthesis.SpeechSynthesizer())
{
synth.Speak("\nPress enter to close Black jack." + dealerTotal);
}
ConsoleKeyInfo info = Console.ReadKey();
if (info.Key == ConsoleKey.Enter)
{
Environment.Exit(0);
}
else
{
Console.Read();
Environment.Exit(0);
}
}
}
}
}

Categories

Resources