Save and displaying high score with variable across classes unity - variables

I need to get the variable score from my other class and set it as a UserPrefs key. it doesnt seem to be setting as i have a GUI label ingame which shos "None" if there is no UserPrefs key "Highscore".
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading;
public class Player : MonoBehaviour {
public Vector2 jumpForce = new Vector2(0, 300);
private Rigidbody2D rb2d;
Generator SwagScript;
GameObject generator;
// Use this for initialization
void Start () {
rb2d = gameObject.GetComponent<Rigidbody2D>();
generator = GameObject.FindGameObjectWithTag("Generator");
SwagScript = generator.GetComponent<Generator>();
}
// Update is called once per frame
void Update () {
if (Input.GetKeyUp("space"))
{
rb2d.velocity = Vector2.zero;
rb2d.AddForce(jumpForce);
}
Vector2 screenPosition = Camera.main.WorldToScreenPoint(transform.position);
if (screenPosition.y > Screen.height || screenPosition.y < 0)
{
Die();
}
}
void OnCollisionEnter2D(Collision2D other)
{
Die();
}
void Die()
{
if (PlayerPrefs.HasKey("HighScore"))
{
if (PlayerPrefs.GetInt("Highscore") < SwagScript.score)
{
PlayerPrefs.SetInt("HighScore", SwagScript.score);
}
else
{
PlayerPrefs.SetInt("HighScore", SwagScript.score);
}
}
Application.LoadLevel(Application.loadedLevel);
}
}

Unless you're creating the Highscore playerpref somewhere else, the Die() method won't never create it, since the if (PlayerPrefs.HasKey("HighScore")) will always return false.
Just remove that if.

Related

Trying to make Unending Boundaries In a Runner Game

Trying to make a runner game. I don't want my character to fall off the edge of the map. How do I make the character always center of the path? I want to make so that my character is always center of the path as it is being instantiated and to never fall off the map.
public class GroundTile : MonoBehaviour
{
GroundSpawner groundSpawner;
// Start is called before the first frame update
private void Start()
{
groundSpawner = GameObject.FindObjectOfType<GroundSpawner>();
}
private void OnTriggerExit (Collider other)
{
groundSpawner.SpawnTile();
Destroy(gameObject, 2);
}
// Update is called once per frame
void Update()
{
}
}
public class GroundSpawner : MonoBehaviour
{
public GameObject groundTile;
Vector3 nextSpawnPoint;
// Start is called before the first frame update
public void SpawnTile()
{
GameObject temp = Instantiate(groundTile, nextSpawnPoint, Quaternion.identity);
nextSpawnPoint = temp.transform.GetChild(1).transform.position;
}
private void Start()
{
for (int i = 0; i < 10; i++)
{
SpawnTile();
}
}
}
I tried so many methods.

Unity Editor - Displaying GUI lines between two points using switch case

I am trying to implement an editor script that would display GUI lines between any two points in the editor. I have three empty game objects as Vector3 points (A, B and C), and for example, if button #1 is pressed, a value of integer "switchCase" will be set to 1, and according to the switch case statement, it will display a line between point A and point B. If button #2 is pressed, "switchCase" is set to 2, and it will display lines between point A and B, and between point B and C, and so on.
The problem I have is that when I press the buttons - nothing happens in the editor. I can see that the value of "switchCase" is changing correctly in the inspector, but the lines are not showing.
If I input the value straight in the inspector, it works as it should, but my goal is to have the value changing when the button is pressed, rather that me changing the value in the inspector manually.
Hopefully my question makes sense. Any help will be appreciated!
Here is the Editor script:
using UnityEngine;
using System.Collections;
using UnityEditor;
using System.Collections.Generic;
using UnityEditor.AnimatedValues;
using System.Linq;
[CustomEditor(typeof(LineTest))]
public class LineTestInspector : Editor
{
public LineTest myScript;
public void OnSceneGUI()
{
Handles.color = Color.red;
switch (myScript.switchCase)
{
case 1:
GameObject posAobj = GameObject.Find("PointA");
GameObject posBobj = GameObject.Find("PointB");
myScript.posA = posAobj.transform.position;
myScript.posB = posBobj.transform.position;
Handles.DrawLine(myScript.posA, myScript.posB);
break;
case 2:
GameObject posCobj = GameObject.Find("PointC");
myScript.posC = posCobj.transform.position;
Handles.DrawLine(myScript.posA, myScript.posB);
Handles.DrawLine(myScript.posB, myScript.posC);
break;
}
public override void OnInspectorGUI()
{
DrawDefaultInspector();
if (GUILayout.Button("Draw First Line"))
{
myScript.switchCase= 1;
Debug.Log("Switch - 1");
}
if (GUILayout.Button("Draw Second Line"))
{
myScript.switchCase = 2;
Debug.Log("Switch - 2");
}
if (GUILayout.Button("Reset switchCase"))
{
myScript.switchCase = 0;
Debug.Log("Switch - 0");
}
}
}
And the Mono script:
using System.Collections;
using System;
using System.Collections.Generic;
using UnityEngine;
public class LineTest : MonoBehaviour {
public Vector3 posA;
public Vector3 posB;
public Vector3 posC;
public int switchCase;
}
You have to call EditorUtility.SetDirty(myScript); for the Editor to update after changing the values.
Your code should look like this:
public override void OnInspectorGUI()
{
DrawDefaultInspector();
if (GUILayout.Button("Draw First Line"))
{
myScript.switchCase = 1;
Debug.Log("Switch - 1");
EditorUtility.SetDirty(myScript);
}
if (GUILayout.Button("Draw Second Line"))
{
myScript.switchCase = 2;
Debug.Log("Switch - 2");
EditorUtility.SetDirty(myScript);
}
if (GUILayout.Button("Reset switchCase"))
{
myScript.switchCase = 0;
Debug.Log("Switch - 0");
EditorUtility.SetDirty(myScript);
}
}

Some rows are collapsed in DataGrid, I am getting issue in KeyBoard navigation

I am using DataGrid, run time i make visible collapse some rows.
Suppose my 4th row's visibility is collapse, and my focus is on 3rd row, when i try to move on 5th row with the help of Down-Arrow key, it is not working. Same way if my focus on 5th row and want to move on 3rd row with Up-Arrow key, it is also not working.
Now, what should i do?
This is actually a bug in .Net, there is a bug report here.
One workaround is to use Attached behavior to handle the up and down selection. The following example requires the IsSynchronizedWithCurrentItem to be set to true for the DataGrid.
Note! make sure you change the while condition to the appropriate way to determine if the item is collapsed.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Media;
namespace DataGridGroupingTest
{
class DataGridKeyboardNavigationAttachedBehavior
{
public static readonly DependencyProperty
KeyboardKey
= DependencyProperty.RegisterAttached(
"IsKeyboardNavigationEnabled",
typeof(bool),
typeof(DataGridKeyboardNavigationAttachedBehavior),
new PropertyMetadata(
false,
OnIsKeyboardNavigationEnabledChanged));
public static bool GetIsKeyboardNavigationEnabled(DependencyObject depObj)
{
return (bool)depObj.GetValue(KeyboardKey);
}
public static void SetIsKeyboardNavigationEnabled(DependencyObject depObj, bool value)
{
depObj.SetValue(KeyboardKey, value);
}
private static void OnIsKeyboardNavigationEnabledChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
{
DataGrid dataGrid = depObj as DataGrid;
if (dataGrid != null)
{
dataGrid.PreviewKeyDown += dataGrid_PreviewKeyDown;
dataGrid.IsSynchronizedWithCurrentItem = true;
}
}
static void dataGrid_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
DataGrid dataGrid = sender as DataGrid;
if (dataGrid != null && dataGrid.CurrentCell != null)
{
if (e.Key == System.Windows.Input.Key.Down || e.Key == System.Windows.Input.Key.Up)
{
ICollectionView view = CollectionViewSource.GetDefaultView(dataGrid.Items);
int loopCount = 0;
do
{
if (e.Key == System.Windows.Input.Key.Down)
{
view.MoveCurrentToNext();
if (view.IsCurrentAfterLast)
{
view.MoveCurrentToFirst();
loopCount++;
}
}
if (e.Key == System.Windows.Input.Key.Up)
{
view.MoveCurrentToPrevious();
if (view.IsCurrentBeforeFirst)
{
view.MoveCurrentToLast();
loopCount++;
}
}
} while (((Person)view.CurrentItem).Boss != null && !((Person)view.CurrentItem).Boss.IsExpanded && loopCount < 2);
// We have to move the cell selection aswell.
dataGrid.CurrentCell = new DataGridCellInfo(view.CurrentItem, dataGrid.CurrentCell.Column);
e.Handled = true;
return;
}
}
}
}
}

Application crashes when launching an event only in MonoTouch 4.0.1

I have an application working under MonoTouch 3.2.6;
the same application, under MonoTouch 4.0.1, crashes when launching any touch event.
Reading another question, at source, I understand that the problem lies in an object collected from the GC, but I can't see which one is. The application starts and loads dinamically the TabBar, but clicking on any TabItem crashes the app. The files main.cs and TabDelegate.cs are listed below: Main.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using System.Drawing;
using IPadApp.Classes;
using AggiornamentiCL;
namespace VSViewer
{
public class Application
{
static void Main (string[] args)
{
UIApplication.Main (args);
}
}
// The name AppDelegate is referenced in the MainWindow.xib file.
public partial class AppDelegate : UIApplicationDelegate
{
public static UITabBar tabmain ;
public static UIViewController ctrMain;
public static Home ctrHome;
public static UIView viewMain;
public static WrapperMenu MenuManager;
public static WrapperValueStories ValueStoriesManager;
public static WrapperBibliography BibliographyManager;
public static WrapperStakeHolder StakeHolderManager;
public static Aggiornamento AggiornamentoManager;
public static string RegionId = "";
public static string RegionName= "";
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
// Reperisco il RegionName dai settings
RegionName= NSUserDefaults.StandardUserDefaults.StringForKey("regione");
// Inizializzo le variabili
tabmain = tabMain;
ctrMain = ctrmain;
viewMain = viewContent;
ctrHome = new Home(String.Empty, RegionName);
// Inizializzo i manager
MenuManager= new WrapperMenu();
ValueStoriesManager= new WrapperValueStories(ref viewMain);
BibliographyManager = new WrapperBibliography();
StakeHolderManager = new WrapperStakeHolder();
AggiornamentoManager = new Aggiornamento(ctrMain);
// Imposto i delegati
tabmain.Delegate = new TabDelegate(viewMain,
ctrMain,
MenuManager,
ValueStoriesManager,
BibliographyManager,
StakeHolderManager,
AggiornamentoManager);
// Reperisco il Root Menu
MenuManager.GetRootMenu(ref tabmain);
if(string.IsNullOrEmpty(RegionName) || String.IsNullOrEmpty(Utils.GetRegionIDByName(RegionName)))
MenuManager.SoloRegioni(ref tabmain,false);
else
{
RegionId = Utils.GetRegionIDByName(RegionName);
Utils.LoadSplash(viewMain,"",RegionName);
}
// If you have defined a view, add it here:
window.AddSubview (ctrMain.View);
window.MakeKeyAndVisible ();
Thread tAggiornaDati = new Thread(new ThreadStart( Aggiornamento.AggiornaDati));
tAggiornaDati.Start();
return true;
}
}
}
TabDelegate.cs:
using System;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using IPadApp.Classes;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
namespace VSViewer
{
public class TabDelegate : UITabBarDelegate
{
private WrapperMenu MenuManager;
private WrapperValueStories ValueStoriesManager;
private WrapperBibliography BibliographyManager;
private WrapperStakeHolder StakeHolderManager;
private Aggiornamento AggiornamentoManager;
private UIView viewMain;
//private UIViewController ctrmain;
private NodeAction previousAction ;
private int previousNode=0;
public TabDelegate (UIView pviewMain,
UIViewController pctrMain,
WrapperMenu pMenuManager,
WrapperValueStories pValueStoriesManager,
WrapperBibliography pBibliographyManager,
WrapperStakeHolder pStakeHolderManager,
Aggiornamento pAggiornamento)
{
viewMain = pviewMain;
MenuManager = pMenuManager;
ValueStoriesManager = pValueStoriesManager;
BibliographyManager= pBibliographyManager;
StakeHolderManager = pStakeHolderManager;
AggiornamentoManager = pAggiornamento;
}
private int GetSelectedTabBarIndex (UITabBar tabbar, UITabBarItem item)
{
for (int i = 0; i < tabbar.Items.Count (); i++) {
if (item == tabbar.Items[i])
return i;
}
return -1;
}
public override void ItemSelected (UITabBar tabbar, UITabBarItem item)
{
int itemSelectedIndex = GetSelectedTabBarIndex (tabbar, item);
MerqurioMenuNode currentNode = MenuManager.GetCurrentNodeByPos (itemSelectedIndex);
if (!(previousAction==currentNode.Action && previousNode == currentNode.MenuID) ||
currentNode.Action== NodeAction.OpenSubMenu)
{
// Rimuovo tutte le immagini della VS che sto abbandonando
if (previousAction== NodeAction.OpenValueStory) ValueStoriesManager.RemoveAllSlides();
// Detacho la View dell'azione precedente
foreach (UIView subView in this.viewMain.Subviews)
{
subView.RemoveFromSuperview ();
subView.Dispose();
}
// Mostro la view corretta
switch (currentNode.Action) {
case NodeAction.OpenSubMenu:
MenuManager.GetMenuByNodeId (ref tabbar, itemSelectedIndex);
// Imposto la breadcrumb
if (currentNode.ParentMenuID==0 && currentNode.Direction== NodeDirection.Forward) Breadcrumb.SetMolecola(currentNode.ViewLabel);
else if (currentNode.ParentMenuID==0 &&currentNode.Direction== NodeDirection.Backward) Breadcrumb.SetMolecola("");
Breadcrumb.UpdateBreadcrumb(currentNode.ViewLabel, AppDelegate.RegionName);
// Mostro la Splash
Utils.LoadSplash(viewMain,currentNode.ViewLabel,AppDelegate.RegionName);
break;
case NodeAction.OpenValueStory:
ValueStoriesManager.ShowValueStory (currentNode, AppDelegate.RegionId);
break;
case NodeAction.OpenBibliography:
BibliographyManager.ShowBibliography(viewMain,currentNode.FileName);
break;
case NodeAction.OpenStakeHolder:
StakeHolderManager.ShowStakeHolder(viewMain);
break;
case NodeAction.OpenRegion:
Regioni ctrRegioni = new Regioni();
this.viewMain.AddSubview(ctrRegioni.View);
break;
case NodeAction.OpenSimulator1:
Simulator_1 ctrSimulator1 = new Simulator_1();
this.viewMain.AddSubview(ctrSimulator1.View);
break;
case NodeAction.OpenSimulator2:
Simulator_2 ctrSimulator2 = new Simulator_2();
this.viewMain.AddSubview(ctrSimulator2.View);
break;
case NodeAction.OpenAggiornamento:
this.viewMain.AddSubview(AggiornamentoManager.View);
break;
default:
break;
}
}
// Aggiorno i contatori
previousAction = currentNode.Action;
previousNode = currentNode.MenuID;
}
}
}
Please help.. I can't found either the old file for MonoTouch 3.2.6...
When I look at your Main.cs file you have a pattern, except one of the things is reversed.
**tabmain = tabMain**;
ctrMain = ctrmain;
viewMain = viewContent;
I think you probably meant tabMain = tabmain;

Duck type testing with C# 4 for dynamic objects

I'm wanting to have a simple duck typing example in C# using dynamic objects. It would seem to me, that a dynamic object should have HasValue/HasProperty/HasMethod methods with a single string parameter for the name of the value, property, or method you are looking for before trying to run against it. I'm trying to avoid try/catch blocks, and deeper reflection if possible. It just seems to be a common practice for duck typing in dynamic languages (JS, Ruby, Python etc.) that is to test for a property/method before trying to use it, then falling back to a default, or throwing a controlled exception. The example below is basically what I want to accomplish.
If the methods described above don't exist, does anyone have premade extension methods for dynamic that will do this?
Example: In JavaScript I can test for a method on an object fairly easily.
//JavaScript
function quack(duck) {
if (duck && typeof duck.quack === "function") {
return duck.quack();
}
return null; //nothing to return, not a duck
}
How would I do the same in C#?
//C# 4
dynamic Quack(dynamic duck)
{
//how do I test that the duck is not null,
//and has a quack method?
//if it doesn't quack, return null
}
If you have control over all of the object types that you will be using dynamically, another option would be to force them to inherit from a subclass of the DynamicObject class that is tailored to not fail when a method that does not exist is invoked:
A quick and dirty version would look like this:
public class DynamicAnimal : DynamicObject
{
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
bool success = base.TryInvokeMember(binder, args, out result);
// If the method didn't exist, ensure the result is null
if (!success) result = null;
// Always return true to avoid Exceptions being raised
return true;
}
}
You could then do the following:
public class Duck : DynamicAnimal
{
public string Quack()
{
return "QUACK!";
}
}
public class Cow : DynamicAnimal
{
public string Moo()
{
return "Mooooo!";
}
}
class Program
{
static void Main(string[] args)
{
var duck = new Duck();
var cow = new Cow();
Console.WriteLine("Can a duck quack?");
Console.WriteLine(DoQuack(duck));
Console.WriteLine("Can a cow quack?");
Console.WriteLine(DoQuack(cow));
Console.ReadKey();
}
public static string DoQuack(dynamic animal)
{
string result = animal.Quack();
return result ?? "... silence ...";
}
}
And your output would be:
Can a duck quack?
QUACK!
Can a cow quack?
... silence ...
Edit: I should note that this is the tip of the iceberg if you are able to use this approach and build on DynamicObject. You could write methods like bool HasMember(string memberName) if you so desired.
Try this:
using System.Linq;
using System.Reflection;
//...
public dynamic Quack(dynamic duck, int i)
{
Object obj = duck as Object;
if (duck != null)
{
//check if object has method Quack()
MethodInfo method = obj.GetType().GetMethods().
FirstOrDefault(x => x.Name == "Quack");
//if yes
if (method != null)
{
//invoke and return value
return method.Invoke((object)duck, null);
}
}
return null;
}
Or this (uses only dynamic):
public static dynamic Quack(dynamic duck)
{
try
{
//invoke and return value
return duck.Quack();
}
//thrown if method call failed
catch (RuntimeBinderException)
{
return null;
}
}
Implementation of the HasProperty method for every IDynamicMetaObjectProvider WITHOUT throwing RuntimeBinderException.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Dynamic;
using Microsoft.CSharp.RuntimeBinder;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
namespace DynamicCheckPropertyExistence
{
class Program
{
static void Main(string[] args)
{
dynamic testDynamicObject = new ExpandoObject();
testDynamicObject.Name = "Testovaci vlastnost";
Console.WriteLine(HasProperty(testDynamicObject, "Name"));
Console.WriteLine(HasProperty(testDynamicObject, "Id"));
Console.ReadLine();
}
private static bool HasProperty(IDynamicMetaObjectProvider dynamicProvider, string name)
{
var defaultBinder = Binder.GetMember(CSharpBinderFlags.None, name, typeof(Program),
new[]
{
CSharpArgumentInfo.Create(
CSharpArgumentInfoFlags.None, null)
}) as GetMemberBinder;
var callSite = CallSite<Func<CallSite, object, object>>.Create(new NoThrowGetBinderMember(name, false, defaultBinder));
var result = callSite.Target(callSite, dynamicProvider);
if (Object.ReferenceEquals(result, NoThrowExpressionVisitor.DUMMY_RESULT))
{
return false;
}
return true;
}
}
class NoThrowGetBinderMember : GetMemberBinder
{
private GetMemberBinder m_innerBinder;
public NoThrowGetBinderMember(string name, bool ignoreCase, GetMemberBinder innerBinder) : base(name, ignoreCase)
{
m_innerBinder = innerBinder;
}
public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
{
var retMetaObject = m_innerBinder.Bind(target, new DynamicMetaObject[] {});
var noThrowVisitor = new NoThrowExpressionVisitor();
var resultExpression = noThrowVisitor.Visit(retMetaObject.Expression);
var finalMetaObject = new DynamicMetaObject(resultExpression, retMetaObject.Restrictions);
return finalMetaObject;
}
}
class NoThrowExpressionVisitor : ExpressionVisitor
{
public static readonly object DUMMY_RESULT = new DummyBindingResult();
public NoThrowExpressionVisitor()
{
}
protected override Expression VisitConditional(ConditionalExpression node)
{
if (node.IfFalse.NodeType != ExpressionType.Throw)
{
return base.VisitConditional(node);
}
Expression<Func<Object>> dummyFalseResult = () => DUMMY_RESULT;
var invokeDummyFalseResult = Expression.Invoke(dummyFalseResult, null);
return Expression.Condition(node.Test, node.IfTrue, invokeDummyFalseResult);
}
private class DummyBindingResult {}
}
}
impromptu-interface seems to be a nice Interface mapper for dynamic objects... It's a bit more work than I was hoping for, but seems to be the cleanest implementation of the examples presented... Keeping Simon's answer as correct, since it is still the closest to what I wanted, but the Impromptu interface methods are really nice.
The shortest path would be to invoke it, and handle the exception if the method does not exist. I come from Python where such method is common in duck-typing, but I don't know if it is widely used in C#4...
I haven't tested myself since I don't have VC 2010 on my machine
dynamic Quack(dynamic duck)
{
try
{
return duck.Quack();
}
catch (RuntimeBinderException)
{ return null; }
}
Have not see a correct answer here, MS provides an example now with casting to a dictionary
dynamic employee = new ExpandoObject();
employee.Name = "John Smith";
employee.Age = 33;
foreach (var property in (IDictionary<String, Object>)employee)
{
Console.WriteLine(property.Key + ": " + property.Value);
}
// This code example produces the following output:
// Name: John Smith
// Age: 33