I'm currently working on a thesis for high school in Germany. My topic is to figure out how we can make traffic intersections more efficient through automation. For this, I'm building a small simulation in Unity3D and right now I'm working on the script and settings for the car. In order to compare multiple settings, I would like to export some data in order to analyze it with NumPy and Matplotlib. But to do so I have to export the data out of Unity.
Right now the car is driving through some waypoints and I would like to get the time when the car is reaching those points.
So now I only have to save them outside of Unity in a format so I could easily import it inside of my jupyter notebook in order to analyze it.
So how would I do this? I know this might be a simple question but most guides are for game objects or characters. So they've saved it for a different purpose.
Update:
Thanks for the help. I got it fixed and now it is writing into a txt file.
Code
Is there a possibility that Unity is creating a new txt file every single time when I run the script. I'm not quite sure if this is even possible at all since I'm technical starting the whole system again and there is no information from last time. As an example that now it's called data1.txt and the next time I'm starting the code it is now saving it into data2.txt.
This is the current output just for some reference.
Data.txt
void FixedUpdate()
{
speed = Engine.currentSpeed;
time = Time.time;
node = Engine.node;
xPos = Auto.transform.position.x;
zPos = Auto.transform.position.z;
if (IsRunning == true)
{
StartCoroutine(Wait());
}
}
public IEnumerator Wait()
{
IsRunning = false;
yield return new WaitForSeconds(WaitTimer);
Output();
IsRunning = true;
}
void Output()
{
print("[" + motorTorque + "," + maxSpeed + "," + steerAngle + "," + node + "," + time + "," + speed + "," + xPos + "," + zPos + "]");
StreamWriter writer = File.AppendText(#"C:\Users\kaykl\Documents\Schule\Info\Data\CarControle\data.txt");
writer.WriteLine("[" + motorTorque + "," + maxSpeed + "," + steerAngle + "," + node + "," + time + "," + speed + "," + xPos + "," + zPos + "]");
writer.Close();
if (IsRunning == true)
{
StartCoroutine(Wait());
}
if (node == 0 && cancel == false)
{
cancel = true;
}
else if (node == 0 && cancel == true)
{
writer.Close();
}
}
An easy way will be save what you need to a file:
https://forum.unity3d.com/threads/how-to-write-a-file.8864/
And for coding a different file every time, just include a time-stamp in the filename.
And alternative will be to use Unity Analytics:
https://unity3d.com/unity/features/analytics
It comes with some nice graphs that could be useful when presenting your thesis.
Good luck!
Related
I'm new to c# and don't completely understand for loops. I am working on a text-based wizard game recommended by brackeys on youtube. At the start of the game, you are asked to chose your spell, let's say "bugs(costs 13mana, deals 2dmg)" you have 3 spell slots and 10hp. When it's time to attack calculations are done etc to reduce the enemy's(frog(10hp)) hp. So after the frog attacks, I want to start over the battle(loop) for me to attack again and the frog to attack again. And the game will be over when either I or the enemy has 0hp. I know for sure I'm coding right but the way I'm using classes and functions are too much and I bet there are simpler ways to do it but I just don't know.
I'm not sure this project is too big for a beginner but yea lol. I was thinking of using a for loop but I don't completely understand how it works.
When I run it only loops the part that asked which spell you want to use and minuses your mana and spell slots. It only loops that and doest attack Also, I'm kinda new to this site so I don't know the proper way of laying out my work.
class Wizard
{
//Wiz Profile
public string name;
public int myHp = 10;
public int myMana = 20;
public string userAttack;
public string favoriteSpell;
private int spellSlots;
private float xp;
public static int Count;
/////////////////////////
//Spells Profile
public int bugsDmg = 2;
public int bugsMana = 13;
public int rottingFodderDmg = 3;
public int rottingFodderMana = 10;
public int owlDmg = 5;
public int owlMana = 10;
//////////////////////////////////////////
//Enemies Profile
public int frogHp = 10;
//Here is where I attempted to make the loop
public void Gameover()
{
while(myHp > 0){
Gameactive();
}
}
//I don't use this I just got this in brackets tutorial I will use it when
getting user name and spell not really sure of to use functions taking stuff
in the brackets
public Wizard(string _name, string _favoriteSpell)
{
name = _name;
favoriteSpell = _favoriteSpell;
spellSlots = 3;
xp = 0f;
Count++;
}
//This is done after the spell calculation is done
public void Battle()
{
userAttack = Console.ReadLine();
if((userAttack == "Bugs") || (userAttack == "bugs"))
{
CastSpell();
frogHp =frogHp - bugsDmg;
Console.WriteLine("You casted " + userAttack + ". Dealth " + bugsDmg + "
damage!");
Thread.Sleep(5000);
Console.WriteLine("----------------------------------------");
Console.WriteLine("Frog hp: " + frogHp +"hp" + " Your hp: " + myHp + "hp Your
mana: " + myMana + "mana");
Console.WriteLine("Spell Slots: " + spellSlots + " slots left");
Console.WriteLine("----------------------------------------");
Thread.Sleep(3000);
}
if( (userAttack == " Rotting Fodder") || (userAttack == "rottingfodder") ||
(userAttack == "rotting fodder"))
{
CastSpell();
frogHp =frogHp - rottingFodderDmg;
Console.WriteLine("You casted " + userAttack + ". Dealth " + rottingFodderDmg +
" damage!");
Thread.Sleep(5000);
Console.WriteLine("----------------------------------------");
Console.WriteLine("Frog hp: " + frogHp +"hp" + " Your hp: " + myHp + "hp Your
mana: " + myMana + "mana");
Console.WriteLine("Spell Slots: " + spellSlots + " slots left");
Console.WriteLine("----------------------------------------");
Thread.Sleep(3000);
}
}
//This is called when an enemy(the frog) attacks
public void Enemyattack()
{
myHp = myHp - rottingFodderDmg;
Console.WriteLine("You got hit with rotting fodder");
Thread.Sleep(2000);
Console.WriteLine("Dealth" + rottingFodderDmg + " damage!");
Thread.Sleep(3000);
Console.WriteLine("----------------------------------------");
Console.WriteLine("Frog hp: " + frogHp +"hp Your hp: " + myHp + "hp Your
mana: " + myMana + "mana");
Console.WriteLine("Spell Slots: " + spellSlots + " slots left");
Console.WriteLine("----------------------------------------");
}
//This is the calculation that happens when a player chooses a spell
public void CastSpell(){
if((userAttack == "Bugs") || (userAttack == "bugs"))
{
myMana = myMana - bugsMana;
spellSlots--;
Console.WriteLine("-15 mana, -1 Spell Slot");
Thread.Sleep(5000);
}
if( (userAttack == " Rotting Fodder") || (userAttack == "rottingfodder") ||
(userAttack == "rotting fodder"))
{
myMana = myMana - rottingFodderMana;
spellSlots--;
Console.WriteLine("-15 mana, -1 Spell Slot");
Thread.Sleep(5000);
}
Gameover();
}
public void Meditate(){
Console.WriteLine(name + " meditates to regain spell slots.");
spellSlots = 2;
}
////////////////I assumed by making this into a func. I will be able to loop the part
///that takes user input then to attack again
public void Gameactive()
{
Console.WriteLine("Select Your Spell to attack: \nBugs(costs 15 mana) Rotting
Fodder(costs 4 mana)");
Battle();
Thread.Sleep(5000);
Console.WriteLine("Standby Phase...");
Thread.Sleep(2);
Console.WriteLine("Frog is attacking...");
Thread.Sleep(2000);
Enemyattack();
}
}
class Program
{
static void Main(string[] args)
{
Console.Title = "WizardMadness";
//Making a new wizard
string userName;
string userGender;
string userFavoriteSpell;
Wizard player1 = new Wizard(/*userName*/"Aaron", "Bugs" /*userFavoriteSpell*/);
Console.WriteLine(Wizard.Count + " wizard created.");
Console.WriteLine("Time to go into battle");
Thread.Sleep(3000);
Console.WriteLine("You ran into a Frog!");
Thread.Sleep(2000);
Console.WriteLine("--------------------------------------------------");
Console.WriteLine("Frog hp: 10hp Your hp: 10hp Your mana: 20mana\nSpell Slots:
3 slots available");
Console.WriteLine("--------------------------------------------------");
Thread.Sleep(5000);
player1.Gameactive();
Welcome to programming! There are a few things you can do to up your code and clean it up a little.
Use .ToLower() for your if statements
Consider using a DO WHILE loop for your game state
You can NEST your if statements
if
{
if
{
}
else if
{
}
else
{
}
}
Using libraries will clean up your code, separating your methods and functions can really help you trouble shoot and debug as well. Making your "main" 30 lines instead of 300
Learn what an if statement actually does. Think of it like this, your program runs top to bottom, so once it goes through that statement it is done, unless there is a loop to reprompt and make it go through it again, but once that statement is cleared, it will not be seen again ( you can nest your if statements in your do while loops)
Hope this helps! Not complete answers, but programming is about logic, and once you figure it out it will click, good luck!
I am a newbie and I am stuck in this problem. I can the players stats, scores and names but I can't make the scoreboard work properly. I have worked 2 days trying to figure it out now I am asking you guys.
I have top 10 scoreboard but I cant make the placement. Higher score should have higher placement.
This is my code:
int PlayerCount = PlayerSystem.Players.Count;
if(PlayerCount == 1)
{
Score[0].text = PlayerSystem.Players[0].Name + ": " + PlayerSystem.Players[0].Score.ToString();
}
if (PlayerCount == 2)
{
if(PlayerSystem.Players[0].Score > PlayerSystem.Players[1].Score)
{
Score[0].text = PlayerSystem.Players[0].Name + ": " + PlayerSystem.Players[0].Score.ToString();
Score[1].text = PlayerSystem.Players[1].Name + ": " + PlayerSystem.Players[1].Score.ToString();
}
else if(PlayerSystem.Players[1].Score > PlayerSystem.Players[0].Score)
{
Score[1].text = PlayerSystem.Players[0].Name + ": " + PlayerSystem.Players[0].Score.ToString();
Score[0].text = PlayerSystem.Players[1].Name + ": " + PlayerSystem.Players[1].Score.ToString();
}
}
I commented over 200 lines of code because it didnt worked. But I hope you get the idea. Thank you if you readed my post. I really apreciate it if you help me how to do it. Thank you.
First sort the player score.
using System.Linq;
....
List<Player> Players = PlayerSystem.Players.OrderByDescending(p=>p.Score).ToList();
Then assign the scores in a loop to your GUI.
for(int i=0; i<10; ++i)
{
var player = PlayerSystem.Players[i];
Score[i].text = player.Name + ": " + player.Score;
}
I'm using MathNet Symbolics to handle the symbolic algebra portion of a program I'm working on. The general use is create a pair of symbolic formulas, and then divide those two formulas. This works quite well most of the time. However, sometimes, it does not want to do more complex simplification. For example:
(512*r*t*w + 2048*r*t^2*w)
-----------------------------------------------------------------------
(512*r*t*w + 512*r^2*t*w + 3072*r*t^2*w + 3072*r^2*t^2*w + 1024*r*t^3*w)
With some work, I've been able to have it eliminate w from the equation, as it is in all terms top and bottom:
(512*r*t + 2048*r*t^2)
--------------------------------------------------------------
(512*r*t + 512*r^2*t + 3072*r*t^2 + 3072*r^2*t^2 + 1024*r*t^3)
However, I cannot figure out how to make it find common terms:
(512*r*t)*(1 + 4*t)
--------------------------------------
(512*r*t)(1 + r + 6*t + 6*r*t + 2*t^2)
And eliminate these terms:
(1 + 4*t)
-----------------------------
(1 + r + 6*t + 6*r*t + 2*t^2)
I've been using Wolfram Alpha as my gold standard for checking my work. The code from LinqPad I've been working on most of the afternoon, that gets my the elimination of w:
var h1 = MathNet.Symbolics.Infix.ParseOrUndefined("(1/8)*r*t*w + (1/2)*r*t^2*w");
var h2 = MathNet.Symbolics.Infix.ParseOrUndefined("(1/8)*r*t*w + (1/8)*r^2*t*w + (3/4)*r*t^2*w + (3/4)*r^2*t^2*w + (1/4)*r*t^3*w");
Infix.Print(Rational.Expand(h1/h2)).Dump(); //Prints (512*r*t*w + 2048*r*t^2*w)/(512*r*t*w + 512*r^2*t*w + 3072*r*t^2*w + 3072*r^2*t^2*w + 1024*r*t^3*w)
var tot = Rational.Expand(h1 / h2);
var simplified = true;
do
{
simplified=false;
foreach (var v in Rational.Variables(tot))
{
var result = Polynomial.Divide(v, h1, h2);
if (!result.Item1.Equals(MathNet.Symbolics.Expression.Zero))
{
simplified = true;
tot = result.Item1;
break;
}
}
}while(simplified);
tot = Rational.Expand(tot);
Infix.Print(tot).Dump(); //Prints (512*r*t + 2048*r*t^2)/(512*r*t + 512*r^2*t + 3072*r*t^2 + 3072*r^2*t^2 + 1024*r*t^3)
Can someone give me pointers to how to proceed with MathNet? I've tried various combinations of functions from Rational and Polynomial, and have not been able to move past this point.
I've just published a new Math.NET Symbolics release v0.6.0 which includes a new Rational.Reduce routine that removes such common simple factors (also executed as part of Rational.Expand):
var h1 = Infix.ParseOrThrow("(1/8)*r*t*w + (1/2)*r*t^2*w");
var h2 = Infix.ParseOrThrow("(1/8)*r*t*w + (1/8)*r^2*t*w + (3/4)*r*t^2*w + (3/4)*r^2*t^2*w + (1/4)*r*t^3*w");
var q1 = h1/h2;
Infix.Print(q1);
// returns: ((1/8)*r*t*w + (1/2)*r*t^2*w)/((1/8)*r*t*w + (1/8)*r^2*t*w + (3/4)*r*t^2*w + (3/4)*r^2*t^2*w + (1/4)*r*t^3*w)
var q2 = Rational.Expand(q1);
Infix.Print(q2);
// returns: (1 + 4*t)/(1 + r + 6*t + 6*r*t + 2*t^2)
Unfortunately quite a few of the univariate polynomial and rational routines like the new square-free factorization do not have a multivariate counterpart yet. Univariate routines expect one symbol parameter, while multivariate ones expect a symbol set.
I'm working on a project where I need to develop a fractional calculator.
I want to add something extra to it, such as having a working out box that displays how the user got their answer.
For example, say I enter 1 1/2 + 1 1/2 into the calculate and press "Calculate", it would then display the answer and how it got the answer such as:
= 3/2 + 3/2
= ((3 × 2) + (3 × 2)) / (2 × 2)
= (6 + 6) / 4
= 12/4
= 3/1
= 3
Here is my basic, crappy looking, program: http://gyazo.com/1dc27b531873c48cdb198baa40b3af9a
I want it to display the working out in the 'Calculations' box below.
How am I able to do this?
Your question is missing some details, so here is a simple answer to begin with.
(I guess your GUI is winforms, and you have a trigger for the calculate OnClick)
To add text into your "Calculations" textbox the code you need is (for your example):
private void calculateButton_Click(object sender, EventArgs e)
{
int common_den = denumerator1*denumerator2;
int new_enumerator1 = enumerator1 * denumerator2;
int new_enumerator2 = enumerator2 * denumerator1;
string myCalculations = " = " + enumerator1.ToString() + "/" + denumerator1.ToString() + " + " + enumerator2.ToString() + "/" + denumerator2.ToString();
string myCalculations += " = " + new_enumerator1.ToString() + "/" + common_den.ToString() + " + " + new_enumerator2.ToString() + "/" + common_den.ToString();
string myCalculations += " = " + (new_enumerator1 + new_enumerator2).ToString() + "/" + common_den.ToString();
calculationsTextBox.Text = myCalculations;
}
If you are looking for the code that will build the calculation string - you need to ask for it explicitly
i have created a marksheet program in c# 2005, its working fine it is taking input and showing the output by using the below code. now if i want that the output of this program is also copied in a new file located in my C or any drive. what should i do? i tried IO.StreamWriter but its not working.
using(System.IO.TextWriter writer = System.IO.File.CreateText(#"C:\1.txt"))
{
Console.WriteLine("\t\tMarksheet - Prislogix Public School");
Console.Write("\n\nStudent Name : " + name);
Console.Write("\nClass : " + cls);
Console.Write("\nRoll Number : " + roll);
Console.Write("\n\nSubject\t\tObtained Marks\t\tTotal Marks");
Console.Write("\n\nChemistry\t\t" + chem + "\t\t75");
Console.Write("\nEnglish\t\t\t" + eng + "\t\t100");
Console.Write("\nCalculus\t\t\t" + urd + "\t\t100");
Console.Write("\nDiscrete\t\t\t" + sin + "\t\t75");
Console.Write("\nMathematics\t\t" + mat + "\t\t100");
Console.Write("\nPhysics\t\t\t" + phy + "\t\t75");
Console.Write("\nComputer\t\t" + comp + "\t\t100");
Console.Write("\nMethods\t\t" + isl + "\t\t50");
float tot = chem + eng + urd + sin + mat + phy + comp + isl;
Console.Write("\n\n\t\t\tTotal Obtained Marks : " + tot + "\tOut Of 625");
float per;
per = (tot / 625) * 100;
Console.Write("\n\t\t\tPercentage : " + per + "%");
if (per < 49 && per > 40)
{
Console.Write("\n\t\t\tFAILED!");
}
if (per <= 59 && per >= 50)
{
Console.Write("\n\t\t\tGrade : C");
}
if (per <= 69 && per >= 60)
{
Console.Write("\n\t\t\tGrade : B");
}
if (per <= 79 && per >= 70)
{
Console.Write("\n\t\t\tGrade : A");
}
if (per <= 89 && per >= 80)
{
Console.Write("\n\t\t\tGrade : A+");
}
if (per <= 100 && per >= 90)
{
Console.Write("\n\t\t\tGrade : A-ONE");
}
}
}
Console.ReadLine();
StreamWriter does work. It's a shame you haven't shown us your attempt at using it.
The simplest way of creating a StreamWriter to write to a file is to use File.CreateText. Then you should be able to use StreamWriter.Write in the same way as Console.Write. Don't forget to use a using statement:
using (TextWriter writer = File.CreateText("..."))
{
// Write stuff here
}
That makes sure the writer will be disposed at the end of the using statement, which will flush and close the file.
If you want to write to both the console and the file, you may want a "tee" TextWriter which writes to two outputs... or you could just look at the file after running the program.
One thing to note: in Windows, the normal line ending is \r\n rather than just \n. If the problem was just that all the output looked like it was on one line in Notepad, that's probably the issue. Consider using WriteLine instead of Write, to write out the platform default line terminator at the end of the line.
If all of this fails, please tell us what's going wrong with rather more detail than "it's not working".
Change all calls to Console.Write so that they write to a StringBuilder instance instead. After the printing is done you can do the following:
Console.Write(stringBuilder.ToString());
System.IO.File.WriteAllText("your path here", stringBuilder.ToString());
This will probably be the easiest fix. It will still write the output to the Console, but it will also write to the file you want.