I am attempting to do a RouteQuery but it only allows for async calls. Unfortunately when the return is hit it hasn't finished the QueryAsync()
Is there a standard way around this?
Usually I would just start a timer and wait for a property to populate but that is way to ghetto. There has to be a solution for this.
private bool wayPointHit(GeoCoordinate geo)
{
RouteQuery query = new RouteQuery();
List<GeoCoordinate> coords = new List<GeoCoordinate>();
coords.Add(new GeoCoordinate(curLocation.Latitude, curLocation.Longitude));
coords.Add(geo);
query.Waypoints = coords;
bool hit = false;
query.QueryCompleted += (sender, args) =>
{
var rt = args.Result;
if (rt.LengthInMeters <= 20)
{
hit = true;
}
};
query.QueryAsync();
return hit;
}
Related
I use WebSocketSharp to write a client, in Start I add the ChangeColor method to the OnMessage event, and the method is executed but not to the end, it does not change the color of the object, although it should. I tried to call the method in Update on button click and it worked correctly. What is the problem?
The server sends correct data, I checked
WebSocket ws;
private Renderer objectRenderer;
private Color matColor;
private string reciveData;
private void Start()
{
objectRenderer = GetComponent<Renderer>();
ws = new WebSocket("ws://127.0.0.1:8080");
ws.Connect();
ws.OnMessage += (sender, e) =>
{
reciveData = e.Data;
ChangeColor(e.Data); // its dosent work!
};
}
void Update()
{
if (ws == null)
return;
// its work
// if (Input.GetKeyDown(KeyCode.Space))
// {
// ChangeColor(reciveData);
// objectRenderer.material.color = matColor;
// }
}
public void ChangeColor(string data)
{
string[] colors = data.Split(',');
matColor = new Color()
{
r = float.Parse(colors[0]) / 255.0f,
g = float.Parse(colors[1]) / 255.0f,
b = float.Parse(colors[2]) / 255.0f,
a = float.Parse(colors[3]) / 255.0f
};
objectRenderer.material.color = matColor;
}
It does not work, because the WebSocketSharp callbacks run on a worker thread. Unity does not allow to interact with your objectRenderer in any other thread than the main thread.
You can cache the data as you did and process it in update method (which is called in main thread).
Use a boolean to tell the Update method to call your ChangeColour method.
WebSocket ws;
private Renderer objectRenderer;
private Color matColor;
private string reciveData;
private bool newDataToBeProcessed;
private void Start()
{
objectRenderer = GetComponent<Renderer>();
ws = new WebSocket("ws://127.0.0.1:8080");
ws.Connect();
ws.OnMessage += (sender, e) =>
{
reciveData = e.Data;
newDataToBeProcessed = true;
};
}
void Update()
{
if (ws == null)
return;
if (newDataToBeProcessed == true)
{
newDataToBeProcessed = false;
ChangeColor(reciveData);
objectRenderer.material.color = matColor;
}
}
public void ChangeColor(string data)
{
string[] colors = data.Split(',');
matColor = new Color()
{
r = float.Parse(colors[0]) / 255.0f,
g = float.Parse(colors[1]) / 255.0f,
b = float.Parse(colors[2]) / 255.0f,
a = float.Parse(colors[3]) / 255.0f
};
objectRenderer.material.color = matColor;
}
How can I stop the NoAnsweredQuestion.Count when I click on a button...
Problem:
When I click on the reset button, the NoAnsweredQuestion.Count is still counting go to the maximum limit
Random:
private void SetcurrentQuestion()
{
int randomQuestionIndex = Random.Range(0, NoAnsweredQuestion.Count);
currentQuestion = NoAnsweredQuestion[randomQuestionIndex];
factText.text = currentQuestion.fact;
correctAnswerText.text = currentQuestion.answered;
}
This is my limit:
public void ContinueTransition()
{
if (NoAnsweredQuestion.Count == 10)
{
FinalScore.SetActive(true);
}
else
{
StartCoroutine(TransitiontoNextQuestion());
updatequestion();
}
}
Reset button:
public void Restart()
{
var form = new WWWForm();
var www = new WWW(restartBegGrammarIAQ, form);
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
Time.timeScale = 1f;
GameIsPaused = false;
}
Add NoAnsweredQuestion.Clear() in your restart method and it should work
I'm in the process of porting my Xamarin.Android app to Xamarin.iOS, I can't make my progress bar update, where am I going wrong?
The values are set in updateProgressBar() correctly and progressBarValue in this example is set as 0.25 as expected, but the UIProgressView is not updated on the screen. progressBar is a UIProgressView on the storyboard.
public BackgroundWorker backgroundWorker { get; private set; }
private float progressBarValue { get; set; }
public override void ViewDidAppear(bool animated)
{
base.ViewDidAppear(animated);
startBackgroundWorker();
}
private void startBackgroundWorker()
{
if (backgroundWorker == null || backgroundWorker.CancellationPending) backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += (s, e) =>
{
//do stuff
backgroundWorker.ReportProgress(25);
//do stuff
};
backgroundWorker.RunWorkerCompleted += (s, e) => { //do stuff };
backgroundWorker.ProgressChanged += (s, e) => { updateProgressBar(e.ProgressPercentage); };
backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.RunWorkerAsync();
}
private void updateProgressBar(float v)
{
if (v > 0){
float value = v / 100;
progressBarValue = progressBarValue + value;
if (progressBarValue > 1) progressBarValue = 1;
progressBar.Progress = progressBarValue;
}
}
I also tried using SetProgress(progressBarValue,true)
private void updateProgressBar(float v)
{
if (v > 0){
float value = v / 100;
progressBarValue = progressBarValue + value;
if (progressBarValue > 1) progressBarValue = 1;
progressBar.SetProgress(progressBarValue,true);
}
}
and using InvokeOnMainThread
private void updateProgressBar(float v)
{
if (v > 0){
float value = v / 100;
progressBarValue = progressBarValue + value;
if (progressBarValue > 1) progressBarValue = 1;
InvokeOnMainThread ( () => {
// manipulate UI controls
progressBar.SetProgress(progressBarValue,true);
});
}
}
you need to be sure your UI updates are running on the main thread
InvokeOnMainThread ( () => {
// manipulate UI controls
progressBar.SetProgress(progressBarValue,true);
});
As is often the case, my problem was not related to my code in the question, or the question at all, I copied it into a new solution and it worked fine.
Incase anyone finds this in the future and has made the same mistake:
My problem was that I had set UIProgressView.TintColor to an invalid value elsewhere in my code so the ProgressView was updating all along but it just wasn't visible.
progressView.TintColor = iOSHelpers.GetColor(GenericHelpers.colorPrimaryGreenRGBA);
iOSHelpers
public static UIColor GetColor(int[] rgba)
{
if (rgba.Length == 4)
return UIColor.FromRGBA(rgba[0], rgba[1], rgba[2], rgba[3]);
else return UIColor.Black;
}
GenericHelpers
public static int[] colorPrimaryGreenRGBA = { 140, 185, 50, 1 };
Once I had changed thecolorPrimaryGreenRGBA values to floats and divided the RGB channels by 255 in the GetColor method it was then a visible color.
Hi there i am trying to make a question answer game. ( Whoever presses joystick button first answers the question first )
So far i ' ve used SharpDX , threading since i cant handle the button press event via SharpDX
My problem is i cant get it worked . I dont know the reason but let me explain my code.
On my page load i ' ve initialized 2 different threads ;
//Initializing the constants
private bool q = true;
private Thread th1;
private Thread th2;
private Guid joy1Guid = Guid.Empty;
private Guid joy2Guid = Guid.Empty;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
var directInput = new DirectInput();
foreach (var deviceInstance in directInput.GetDevices())
{
if (deviceInstance.Subtype == 258)
{
//My joysticks connected to pc via usb.
if (joy1Guid == Guid.Empty)
joy1Guid = deviceInstance.InstanceGuid;
else if (joy2Guid == Guid.Empty)
joy2Guid = deviceInstance.InstanceGuid;
}
}
th1 = new Thread(Joy1Start);
th2 = new Thread(Joy2Start);
th1.IsBackground = true;
th2.IsBackground = true;
}
Below my Thread methods
private void Joy1Start()
{
var directInput = new DirectInput();
var joystick = new Joystick(directInput, joy1Guid);
joystick.Properties.BufferSize = 128;
joystick.Acquire();
while (q)
{
joystick.Poll();
var state = joystick.GetCurrentState();
var counter = 0;
foreach (bool isPressed in state.Buttons)
{
if (isPressed)
{
Action a1 = () => textBox1.Text = "JOY1";
textBox1.Invoke(a1);
th1.Abort();
th2.Abort();
q = false;
break;
}
counter++;
}
}
}
private void Joy2Start()
{
var directInput = new DirectInput();
var joystick = new Joystick(directInput, joy2Guid);
joystick.Properties.BufferSize = 128;
joystick.Acquire();
while (q)
{
joystick.Poll();
var state = joystick.GetCurrentState();
var counter = 0;
foreach (bool isPressed in state.Buttons)
{
if (isPressed)
{
Action a2 = () => textBox1.Text = "JOY2";
textBox1.Invoke(a2);
th1.Abort();
q = false;
break;
}
counter++;
}
}
}
I am firing thread starts with a button
private void button1_Click(object sender, EventArgs e)
{
th1.Start();
th2.Start();
}
So the problem is i can't get any response if i work with two threads.
When i only start th1 or th2 it works like a charm.
Can you please show me where is the wrong part of this algorithm ?
I have made a little Blackjack game, and I'd like to make the computer wait between each card he pulls, however using System.Threading.Thread.Sleep(int x) does not make the program wait between cards, but makes it wait for x * amount of cards..
I also know that using Thread.Sleep is not a good way, so I'd rather learn a better way as I am creating this program entirely for educative purposes.
I'll add the code underneath which decides whether or not a card should be drawn, and the method that draws the card.
private void ComputerTurn()
{
drawCard.Enabled = false;
finishTurn.Enabled = false;
while (computerTotalScore <= 11)
{
ComputerDrawCard();
}
drawAgain = true;
while (drawAgain)
{
ComputerDrawCard();
if (totalScore <= 21)
{
if (computerTotalScore > totalScore)
{
drawAgain = false;
}
else
{
drawAgain = true;
}
}
else
{
if (computerTotalScore > 16)
{
drawAgain = false;
}
else
{
drawAgain = true;
}
}
}
DecideWinner();
}
public void ComputerDrawCard()
{
cardAlreadyPulled = true;
while (cardAlreadyPulled)
{
cardType = random.Next(0, 4);
cardNumber = random.Next(0, 13);
if (!pulledCards[cardType, cardNumber])
{
cardAlreadyPulled = false;
pulledCards[cardType, cardNumber] = true;
}
}
ComputerUpdateCardPictures();
computerScore = cardScores[cardNumber];
if (computerScore == 1)
{
if (computerTotalScore <= 10)
{
computerScore = 11;
}
else
{
computerScore = 1;
}
}
computerTotalScore += computerScore;
txtComputerCurrentScore.Text = computerScore.ToString();
txtComputerTotalScore.Text = computerTotalScore.ToString();
System.Threading.Thread.Sleep(random.Next(250, 750));
}
There are multiple ways to achieve something like this. I believe what you're attempting to do is simulate a human taking time to do things. I recommend using a combination of expected wait times and a timer to achieve what you want.
class Example
{
public Example()
{
// create a stalled timer
_pulse = new Timer(this.TakeAction);
}
TimeSpan _drawdelay = TimeSpan.FromSeconds(2);
DateTime _lastAction = DateTime.MinValue;
Timer _pulse;
public void Start()
{
// start the timer by asking it to call the worker method ever 0.5 seconds
_pulse.Change(0, 500);
}
public void Stop()
{
// stop the timer by setting the next pulse to infinitely in the future
_pulse.Change(Timeout.Infinite, Timeout.Infinite);
}
void TakeAction(object x)
{
lock (_pulse)
{
DateTime now = DateTime.Now;
if(now - _lastAction > _drawdelay)
{
// do work ...
_lastAction = now;
}
}
}
}
That said, the above code will run into issues if the work being done takes longer than 500 milliseconds to complete. Add thread safety as necessary.
I would add a last time drawn and time between draws members. Then before drawing a card, get the time between now and the last time pulled. If the time is greater than the allowed time between the draws its cool to draw.
private DateTime _lastWrite = DateTime.Now;
private TimeSpan _delay = TimeSpan.FromMilliseconds(100);
public void ComputerDrawCard() {
var now = DateTime.Now;
if (now - _lastWrite < _delay)
return;
_lastWrite = now;
draw card...
}
Here's a gist of an example working correctly.