Unity LookAtMouse function kills movement performance - performance

private void LookAtMouse()
{
if (Physics.Raycast(mainCamera.ScreenPointToRay(mouseLook), out var raycastHit, Mathf.Infinity))
{
_direction = (raycastHit.point - transform.position).normalized;
_direction.y = 0;
transform.forward = _direction;
}
}
whenever I call this function in update it kills my movement. If I don't run this function everything works perfectly. I have tried using transform.LookAt() I tried using transform.Translate() in movement, Rigidbody.MovePosition(), changing anything else doesn't help.
If I comment out the transform.forward = _direction; then everything works perfect. what is it about that that makes my movement run game breakingly slow
I have tried every possible thing I can find online to fix this and nothing has been helping.

As soon as any physics is involved you do not want to set things via Transform as this breaks the physics and collision detection.
You should be using Rigidbody.MoveRotation in combination with Quaternion.LookRotation within FixedUpdate

Try to call it in FixedUpdate
generally, I use Update just for catching Key input because it may be called +1000 time if your device is powerful, in the other hand fixed update is better to do the physics .iv it a try and replay if it didn't help to think in other solution;

Related

How can I switch between scenes without destroying (freeing) the scene I'm leaving?

Hey there in my game there are battles. Currently the battle is a separate scene and when a player walks up to an NPC we have a little transition and then leave the scene and we go to the battle scene. Once the battle scene is completed I want to return to the previous scene we were at with everything exactly the same. I currently have a scene switching singleton called scene_switcher with the current setup
extends Node
var _params = null
func change_scene(next_scene, params = null):
_params = params
# global_data is another singleton I use for storing state and other global data
global_data.previous_scene = get_tree().get_current_scene()
get_tree().change_scene(next_scene)
func return_to_previous_scene(params = null):
_params = params
get_tree().get_current_scene().free()
get_tree().get_root().add_child(global_data.previous_scene)
get_tree().set_current_scene(global_data.previous_scene)
func get_param(name):
if _params != null and _params.has(name):
return _params[name]
return null
when we're going into the battle I use
scene_switcher.change_scene("res://battlescene.tcsn", {players_deck, opponents_deck})
which stores the current scene exactly as it is and passes over player data to the battle scene.
once the battle is over I call return_to_previous_scene() which I call when one of the victory conditions is met like so
scene_switcher.return_to_previous_scene()
however I get the error:
Attempted to free a locked object (calling or emitting).
I've tried deferring the call to idle time based off of this code on the singleton autoload page of the docs however when I do:
call_deferred("scene_switcher.return_to_previous_scene")
it never gets called (the game_over function works, it prints out the result and my other tests have it working with the code below, I think the scene never idles which mean the code never gets a chance to fire)
Now I can use:
scene_switcher.change_scene("res://map.tcsn", {})
but that reverts the scene back to it's original state and is not very scalable (how will I know which scene to load if I can battle people in 12 different levels?)
So how can I halt the current scene. leave, and then return to the previous scene with everything how I left it? Thanks :)
I asked this same question on reddit and got an answer that solved my problem. Copying over here for anyone who might find this question in the future. All credit to /u/thomastc
Their answer:
call_deferred takes a method name only, so:
scene_switcher.call_deferred("return_to_previous_scene")
Alternatively, just use queue_free instead of free, to defer only the freeing.
I was not using call_deferred correctly.
I also made the slight modification of using duplicate() on the scene in change_scene to keep a copy that isn't freed.
so
global_data.previous_scene = get_tree().get_current_scene()
became
global_data.previous_scene = get_tree().get_current_scene().duplicate()
which now works as expected :)

Why is ReactiveList with ChangeTrackingEnabled slow when I Clear inside SuppressChangeNotifications?

Why is ReactiveList with ChangeTrackingEnabled slow when I Clear inside SuppressChangeNotifications?
With 10,000 entries it takes about 2 seconds for the Clear method to return.
Shouldn't SuppressChangeNotifications bypass the change tracking code?
Or how can I improve the performance here?
ReactiveList<Person> _personList = new ReactiveList<Person> { ChangeTrackingEnabled = true };
using (_personList.SuppressChangeNotifications())
{
_personList.Clear();
}
Thanks a lot.
Change tracking code is bypassed, but still ReactiveList needs to cleanup its internal stuff when you clear the list. And the method used to do so is extremely inefficient ( O(n2) ), as detailed in this SO answer.
The Clear implementation with change tracking enabled can definitely be improved, I'll send a PR to RxUI if I get the chance.
E.g. replacing this code by foreach (var foo in _propertyChangeWatchers.Values.ToList()) foo.Release(); makes the Clear immediate, w/o altering the behavior.
EDIT :
You can work around this performance issue by writing instead:
using (_personList.SuppressChangeNotifications())
_personList.RemoveRange(0, _personList.Count);

Coded UI error: The following element is not longer availabe

I recorded some test cases with CUIT in VS2010. Everything worked fine the day before. So, today I run again, all the test failed, with the warning: The following element is no longer available ... and I got the exception : Can't perform "Click" on the hidden control, which is not true because all the controls are not hidden. I tried on the other machine, and they failed as well.
Does anyone know why it happens? Is it because of the web application for something else? Please help, thanks.
PS: So I tried to record a new test with the same controls that said "hidden controls", and the new test worked!? I don't understand why.
EDIT
The warning "The following element blah blah ..." appears when I tried to capture an element or a control while recording. The source code of the button is said 'hidden'
public HtmlImage UIAbmeldenImage
{
get
{
if ((this.mUIAbmeldenImage == null))
{
this.mUIAbmeldenImage = new HtmlImage(this);
#region Search Criteria
this.mUIAbmeldenImage.SearchProperties[HtmlImage.PropertyNames.Id] = null;
this.mUIAbmeldenImage.SearchProperties[HtmlImage.PropertyNames.Name] = null;
this.mUIAbmeldenImage.SearchProperties[HtmlImage.PropertyNames.Alt] = "abmelden";
this.mUIAbmeldenImage.FilterProperties[HtmlImage.PropertyNames.AbsolutePath] = "/webakte-vnext/content/apps/Ordner/images/logOut.png";
this.mUIAbmeldenImage.FilterProperties[HtmlImage.PropertyNames.Src] = "http://localhost/webakte-vnext/content/apps/Ordner/images/logOut.png";
this.mUIAbmeldenImage.FilterProperties[HtmlImage.PropertyNames.LinkAbsolutePath] = "/webakte-vnext/e.consult.9999/webakte/logout/index";
this.mUIAbmeldenImage.FilterProperties[HtmlImage.PropertyNames.Href] = "http://localhost/webakte-vnext/e.consult.9999/webakte/logout/index";
this.mUIAbmeldenImage.FilterProperties[HtmlImage.PropertyNames.Class] = null;
this.mUIAbmeldenImage.FilterProperties[HtmlImage.PropertyNames.ControlDefinition] = "alt=\"abmelden\" src=\"http://localhost/web";
this.mUIAbmeldenImage.FilterProperties[HtmlImage.PropertyNames.TagInstance] = "1";
this.mUIAbmeldenImage.WindowTitles.Add("Akte - Test Akte Coded UI VS2010");
#endregion
}
return this.mUIAbmeldenImage;
}
}
Although I am running Visual Studio 2012, I find it odd that we started experiencing the same problem on the same day, I can not see any difference in the DOM for the Coded UI Tests I have for my web page, but for some reason VS is saying the control is hidden and specifies the correct ID of the element it is looking for (I verified that the ID is still the same one). I even tried to re-record the action, because I assumed that something must have changed, but I get the same error.
Since this sounds like the same problem, occurring at the same time I am thinking this might be related to some automatic update? That's my best guess at the moment, I am going to look into it, I will update my post if I figure anything out.
EDIT
I removed update KB2870699, which removes some voulnerability in IE, this fixed the problems I was having with my tests. This update was added on the 12. september, so it fits. Hope this helps you. :)
https://connect.microsoft.com/VisualStudio/feedback/details/800953/security-update-kb2870699-for-ie-breaks-existing-coded-ui-tests#tabs
Official link to get around the problem :
http://blogs.msdn.com/b/visualstudioalm/archive/2013/09/17/coded-ui-mtm-issues-on-internet-explorer-with-kb2870699.aspx
The problem is more serious than that! In my case I can't even record new Coded UI Tests. After I click in any Hyper Link of any web page of my application the coded UI test builder cannot record that click "The following element is no longer available....".
Apparently removing the updates, as said by AdrianHHH do the trick!
Shut down VS2010, launch it again "Run as administrator".
There may be a field in the SearchProperties (or possible the FilterProperties) that has a value set by the web site, or that represents some kind of window ID on your desktop. Another possibility is that the web page title changes from day to day or visit to visit. Different executions of the browser or different visits to the web page(s) create different values. Removing these values from the SearchProperties (or FilterProperties) or changing the check for the title from an equals to a contains for a constant part of the title should fix the problem. Coded UI often searches for more values than the minimum set needed.
Compare the search properties etc for the same control in the two recorded tests.
Update based extra detail given in the comments:
I solved a similar problem as follows. I copied property code similar to that shown in your question into a method that called FindMatchingControls. I checked how many controls were returned, in my case up to 3. I examined various properties of the controls found, by writing lots of text to a debug file. In my case I found that the Left and Top properties were negative for the unwanted, ie hidden, controls.
For your code rather than just using the UIAbmeldenImage property, you might call the method below. Change an expression such as
HtmlImage im = UIMap.abc.def.UIAbmeldenImage;
to be
HtmlImage im = FindHtmlHyperLink(UIMap.abc.def);
Where the method is:
public HtmlImage FindHtmlHyperLink(HtmlDocument doc)
{
HtmlImage myImage = new HtmlImage(doc);
myImage.SearchProperties[HtmlImage.PropertyNames.Id] = null;
myImage.SearchProperties[HtmlImage.PropertyNames.Name] = null;
myImage.SearchProperties[HtmlImage.PropertyNames.Alt] = "abmelden";
myImage.FilterProperties[HtmlImage.PropertyNames.AbsolutePath] = "/webakte-vnext/content/apps/Ordner/images/logOut.png";
myImage.FilterProperties[HtmlImage.PropertyNames.Src] = "http://localhost/webakte-vnext/content/apps/Ordner/images/logOut.png";
myImage.FilterProperties[HtmlImage.PropertyNames.LinkAbsolutePath] = "/webakte-vnext/e.consult.9999/webakte/logout/index";
myImage.FilterProperties[HtmlImage.PropertyNames.Href] = "http://localhost/webakte-vnext/e.consult.9999/webakte/logout/index";
myImage.FilterProperties[HtmlImage.PropertyNames.Class] = null;
myImage.FilterProperties[HtmlImage.PropertyNames.ControlDefinition] = "alt=\"abmelden\" src=\"http://localhost/web";
myImage.FilterProperties[HtmlImage.PropertyNames.TagInstance] = "1";
myImage.WindowTitles.Add("Akte - Test Akte Coded UI VS2010");
UITestControlCollection controls = myImage.FindMatchingControls();
if (controls.Count > 1)
{
foreach (UITestControl con in controls)
{
if ( con.Left < 0 || con.Top < 0 )
{
// Not on display, ignore it.
}
else
{
// Select this one and break out of the loop.
myImage = con as HtmlImage;
break;
}
}
}
return myImage;
}
Note that the above code has not been compiled or tested, it should be taken as ideas not as the final code.
I had the same problem on VS 2012. As a workaround, you can remove that step, and re-record it again. That usually works.
One of the biggest problem while analyzing the Coded UI test failures is that the error stack trace indicates the line of code which might be completely unrelated to the actual cause of failure.
I would suggest you to enable HTML logging in your tests - this will display step by step details of how Coded UI tried to execute the tests - with screenshots of your application. It will also highlight the control in red which Coded UI is trying to search/operate upon.This is very beneficial in troubleshooting the actual cause of test failures.
To enable tracing you can just add the below code to your app.config file --

Adding custom code to mootools addEvent

Even though I've been using mootools for a while now, I haven't really gotten into playing with the natives yet. Currently I'm trying to extend events by adding a custom addEvent method beside the original. I did that using the following code(copied from mootools core)
Native.implement([Element, Window, Document], {
addMyEvent:function(){/* code here */}
}
Now the problem is that I can't seem to figure out, how to properly overwrite the existing fireEvent method in a way that I can still call the orignal method after executing my own logic.
I could probably get the desired results with some ugly hacks but I'd prefer learning the elegant way :)
Update: Tried a couple of ugly hacks. None of them worked. Either I don't understand closures or I'm tweaking the wrong place. I tried saving Element.fireEvent to a temporary variable(with and without using closures), which I would then call from the overwritten fireEvent function(overwritten using Native.implement - the same as above). The result is an endless loop with fireEvent calling itself over and over again.
Update 2:
I followed the execution using firebug and it lead me to Native.genericize, which seems to act as a kind of proxy for the methods of native classes. So instead of referencing the actual fireEvent method, I referenced the proxy and that caused the infinite loop. Google didn't find any useful documentation about this and I'm a little wary about poking around under the hood when I don't completely understand how it works, so any help is much appreciated.
Update 3 - Original problem solved:
As I replied to Dimitar's comment below, I managed to solve the original problem by myself. I was trying to make a method for adding events that destroy themselves after a certain amount of executions. Although the original problem is solved, my question about extending natives remain.
Here's the finished code:
Native.implement([Element, Window, Document], {
addVolatileEvent:function(type,fn,counter,internal){
if(!counter)
counter=1;
var volatileFn=function(){
fn.run(arguments);
counter-=1;
if(counter<1)
{
this.removeEvent(type,volatileFn);
}
}
this.addEvent(type,volatileFn,internal);
}
});
is the name right? That's the best I could come up with my limited vocabulary.
document.id("clicker").addEvents({
"boobies": function() {
console.info("nipple police");
this.store("boobies", (this.retrieve("boobies")) ? this.retrieve("boobies") + 1 : 1);
if (this.retrieve("boobies") == 5)
this.removeEvents("boobies");
},
"click": function() {
// original function can callback boobies "even"
this.fireEvent("boobies");
// do usual stuff.
}
});
adding a simple event handler that counts the number of iterations it has gone through and then self-destroys.
think of events as simple callbacks under a particular key, some of which are bound to particular events that get fired up.
using element storage is always advisable if possible - it allows you to share data on the same element between different scopes w/o complex punctures or global variables.
Natives should not be modded like so, just do:
Element.implement({
newMethod: function() {
// this being the element
return this;
}
});
document.id("clicker").newMethod();
unless, of course, you need to define something that applies to window or document as well.

Programatically moving through a ListView in Qt (Ruby)

I'm making a small file-browser for my own use, in Ruby, and using Qt for the view. The idea is that it'll end up on my TV, where I can use the remote to move up and down and launch files.
Everything works fine, until I'm going to move the selection using the remote. I managed to set up a D-Bus service, so I'll just call the methods using LIRC.
The code I'm using for setting up the view looks like this:
#dm = Qt::DirModel.new
#sm = Qt::ItemSelectionModel.new(#dm)
#lv = Qt::ListView.new
#lv.model = #dm
#lv.selectionModel = #sm
cwd = #dm.index(#dir)
#lv.rootIndex = cwd
And then I'm unsure how to change the selection. Think I must have tried about every setIndex, setSelection and every method sounding similar, on the DirModel, ItemSelectionModel and ListView, without any luck. I've been googling and reading through the API without finding anything.
Ideally, I would have something like "moveSelectionDown" and "moveSelectionUp" that takes care of it, and making sure it wraps around correctly. But I can't seem to find anything.
Managed to fix it through the ItemSelectionModel every view apparently has.
moving up:
curIndex = #lv.currentIndex
#lv.selectionModel.setCurrentIndex(curIndex.sibling(curIndex.row-1, 0), Qt::ItemSelectionModel::ClearAndSelect)
or adding one to move down
I think you're forgetting that you have to create the ModelIndex through your model:
#dm.index(3, 0, None)
I'd try this method (Though I'm not really sure, this deselects the other cells.)
#lv.setCurrentIndex(#dm.index(3, 0, None))
I haven't used Ruby for ages, so I'm not exactly sure there's None.

Resources