I am porting a existing webgame to libgdx. The game is controlled by a script I would rather not change.
The script specifies actions to do on certain keypress events using their javascript keycode value.
ie. "OnKeyPress=32:" would define actions to run when space is pressed.
"OnKeyPress=40:" would define actions to run when down is pressed, etc.
Now, as LibGDX uses different keycode system I need some way to fire my existing events when the correct key is pressed.
#Override
public boolean keyDown(int keycode) {
//convert input processors keycode to javascripts?
}
I can only think I have to create some sort of large static hashmap mapping between
GDXs
Input.Keys
and
com.google.gwt.event.dom.client.KeyCodes
But before going to this bother I thought Id ask around in case theres a better way?
Thanks,
In the end I just created a class to associate one keycode (com.badlogic.gdx.Input.Keys) with another. (com.google.gwt.event.dom.client.KeyCodes)
Fairly easy, but anyone doing the same should pay careful attention that not everything has a 1:1 mapping.
For example;
ALT_LEFT and ALT_RIGHT both map to ALT in gwt/javascript.
Likewise CNTR left and right and SHIFT left and right.
GDX meanwhile treats BACKSPACE and DELETE as the same key.
This is, naturally, as GDX needs to be cross platform so has different requirements.
Other then that just a ImmutableMap seemed to do the job....
/**
* static mapping between javascript/gwt keycodes and gdxs
**/
static ImmutableMap<Integer,Integer> keyCodeConversion = ImmutableMap.<Integer, Integer>builder()
.put(Input.Keys.UP, GwtKeyCodeCopy.UP)
.put(Input.Keys.DOWN, GwtKeyCodeCopy.DOWN)
.put(Input.Keys.LEFT, GwtKeyCodeCopy.LEFT)
.put(Input.Keys.RIGHT, GwtKeyCodeCopy.RIGHT)
.....
...(lots more)
.bind();
static public int getJavascriptKeyCode(int GdxKeycode){
return keyCodeConversion.get(GdxKeycode);
}
Related
I'm using InputSystem.EnhancedTouch for my game and I have a few buttons that are available through UI Elements. When I click on the UI Elements buttons it activates the InputSystem thus creating a bad experience. I want to filter out all the InputSystem.EnhancedTouch events that come through UI.
TL;DR - I want UI Elements to block InputSystem.EnhancedTouch events from triggering
I have found quite some resources but nothing really works. Unity and some other people say to use EventSystem.current.IsPointerOverGameObject but it doesn't work and throws the following warning(I think this is meant to work with normal input only, not enhanced one)
I have tried a few other solutions such as UIDocument.rootVisualElement.panel.Pick or EventSystem.current.RaycastAll but nothing seems to work, or return any consistent data that can be used.
InputSystem.EnhancedTouch binding
private void Awake()
{
EnhancedTouchSupport.Enable();
Touch.onFingerDown += OnFingerDown;
Touch.onFingerMove += OnFingerMove;
Touch.onFingerUp += OnFingerUp;
}
I'm using the A* pathfinding algorithm for my 2D game (from my understanding, Unity Nav Meshes don't work in 2D). I would like to be able to pre-calculate navigation grids for all of my scenes, and save them in resource files that can be loaded whenever the player enters a new scene. Rather than having to remember to click "calculate" for every scene -- and remember to recalculate all of my scenes if I make a change to my navigation grids -- I want to be able to programatically have the Unity Editor iterate though each scene and calculate the grids.
Is there a way to create a command in the Unity editor that will iteratively open each scene in the editor and run a method on a MonoBehaviour that's in the scene? Alternatively, is there another way to accomplish what I'm trying to do?
Yes you can!
In editmode you can't use SceneManager but have to use the EditorSceneManager.
First of all you need the scenes you want to iterate.
Could be e.g. a public static field with a list of SceneAsset in the Inspector where you simply reference the scenes
public static List<SceneAsset> Scenes = new List<SceneAsset>();
or you could get them by script e.g. for only use the scenes added to the build settings using EditorBuildSettings.scenes
List<EditorBuildSettingsScene> Scenes = EditorBuildSettings.scenes;
For both you can get a list of the scene paths e.g. using LinQ Select (this is basically a kind of shortcut for a foreach loop) and AssetDatabase.GetAssetPath like
List<string> scenePaths = Scenes.Select(scene => AssetDatabase.GetAssetPath(scene)).ToList();
for the EditorBuildSettingsScene from EditorBuildSettings.scenes you can also simply use
List<string> scenePaths = Scenes.Select(scene => scene.path).ToList();
Now you can iterate over them all and do your stuff by using EditorSceneManager.OpenScene, EditorSceneManager.SaveScene and EditorSceneManager.CloseScene (and if you need it AssetDatabase.SaveAssets)
foreach(string scenePath in scenePaths)
{
// Open a scene e.g. in single mode
var currentScene = EditorSceneManager.OpenScene(scenePath);
/* Do your calculation for currentScene */
// Don't know if it makes changes to your scenes .. if not you can probably skip this
EditorSceneManager.SaveScene(currentScene);
// Finally Close and remove the scene
EditorSceneManager.CloseScene(currentScene, true);
}
// you might be doing changes to an asset you want to save when done
AssetDatabase.SaveAssets();
Before starting you should probably ask to save the current open scene(s) using EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo
if(EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
{
// Saved => the foreach loop here
}
else
{
// aborted => do nothing
}
Than in order to finally start that method the simplest would be to add a [MenuItem]
public static class Calculation
{
[MenuItem("YourMenu/RunCalculation")]
public static void RunCalculation()
{
// all the before mentioned snippets here
// depending how exactly you want to do it
}
}
This will add a new menu YourMenu with one entry RunCalculation to the top menubar of the Unity Editor.
Note:
Since this uses a lot of types (EditorSceneManager etc) that only exist in the UnityEditor namespace you should either place the whole script in an Editor folder (so it is ignored in the final build) or use pre-processors like
#if UNITY_EDITOR
// ... code here
#endif
so in the build the code is also ignored.
Note that I'm assuming so far you also did your calculation in editmode. The thing is if this calculation relies somewhere aon any Start or Awake method you have to call it manually from that editorscript before running the calculation.
I want to implement the navigational system in my Processing project. If user (that navigates the object) wants to turn left, he hits the 'a' button. Here is my callback function on keyPressed:
void keyPressed() {
...
if(key == 'a') { ship.plainAngle -= 0.1; }
else if(key == 'd') { ship.plainAngle += 0.1; }
}
What I want to avoid is spamming the 'a' key in order to make 90 degrees turn left. I tried increasing the value that affects it directly (0.1) but it made it look laggy. I heard that there is a possibility in processing to make continuous callbacks while user keeps holding the key. As I found out using callback function keyPressed should work out but it doesn't work for me. The code in callback function executes only once. I don't know how to solve that problem.
Use a boolean variable to keep track of whether the a key (or any other key you care about) is currently held down. Set it to true in the mousePressed() function, and set it to false in the mouseReleased() function. Then in the draw() function, you can check that variable and do something if the key is currently being pressed.
Shameless self-promotion: I wrote a tutorial on keyboard input in Processing available here. Check out the section on handling multiple key presses for the approach I just outlined.
Is there a way to assign multiple assets to multiple variables on the inspector???
My case is this, I have 5 objects, those objects have a script wich have around 1200 variables used to play SFXs. When Unity compile the script I have to manually drag and drop the SFX from the assets to the variable on the inspector, or go to the inspector, scrol to the variable, click the dot and then select the SFX file from the window.
Is there a way to speed this up?
You should create a public List of Audio Sources which will appear in inspector. Lock the inspector by clicking look in right top.
Now select all the files from Project and drag on list. All files will be added to list. Now if you want a specific file you can find the file by its name for example:
AudioSource GetAudioSource(string SourceName)
{
return audioSourceList.Find(item => item.Name == SourceName);
}
Use the Resources.LoadAll method to access all the assets from the path parameter via scripting. Probably put that method call in Start. Might have to rename the files to pull the right order from the LoadAll method if they result in some alternate order.
EDIT: Here's some example code...
(NOTE: Loads from Resources/Sound/SFX folder)
For reference: http://docs.unity3d.com/ScriptReference/Resources.LoadAll.html
public class YourClassNameGoesHere : MonoBehaviour
{
Public AudioClip[] BA;
void Start ()
{
BA = (AudioClip[]) Resources.LoadAll("Sound/SFX");
}
}
I found a solution for this problem. I must say, it's not perfect, in fact, it should not be used unless is absolutely necessary.
To speed up the assign you could do this:
Create a variable
public AudioClip ma, me, mi, mo, mu;
At Start() add
ma = Resources.Load("Sound/SFX/MA") as AudioClip;
me = Resources.Load("Sound/SFX/ME") as AudioClip;
mi = Resources.Load("Sound/SFX/MI") as AudioClip;
mo = Resources.Load("Sound/SFX/MO") as AudioClip;
mu = Resources.Load("Sound/SFX/MU") as AudioClip;
After compile the public variables will be available on the Inspector as empty variables, but, on runtime the variables will be filled with the content of the folder Resources/Sound/SFX (Assets\Resources\Sound\SFX).
Why shouldn't be use unless necessary?, first, it's a bad practice; second, it's a cheap trick that comes at a price (on mobile devices it load all the resources so will consume RAM fast). In my test, all my sound clips take as much as 169 MB. On PC it's not much of a problem, but if your target is Mobile games, this is something to take into consideration. And third, on web player, ALL resources will be streamed first.
On a side note, this cheap trick ignores the way Unity handles assets. Unity force you to assign assets manually because if the asset is not use, it will not be integrated into the build. This trick force everything to be loaded and be integrated into the final build, used or no. On the other hand, if you are assign it, you will use it... right?
The answer and example given by #Jayson Ash lead me to the right direction.
I'm having a rare issue in my code, I have a method that makes a very simple validation based on a string variable:
private void showNextStep(String psCondition,String poStepName){
int liCurrentStep=Integer.valueOf(poStepName);
String lsNextTrueStep=moSteps[liCurrentStep][4];
String liNextFalseStep=moSteps[liCurrentStep][5];
if ("Yes".equals(psCondition)){
moFrmStepsContainer.getField(liNextFalseStep).hide();
moFrmStepsContainer.getField(lsNextTrueStep).show();
}else{
moFrmStepsContainer.getField(liNextFalseStep).show();
moFrmStepsContainer.getField(lsNextTrueStep).hide();
}
}
Now, here is the ticky part: if I execute the application without debugging mode, it does the validation right all the time, how ever if don't it always goes to the else block (or at least I think) I tried to use JS alerts (I have a class that calls JS methods) to debug manually and check the valors of the variables; the valors where all right and the validation was also good. This means that only debugging or putting alerts before at the beggining of the IF block it does the validation right, otherwise it always goes to the ELSE, what do you think it could be?
It might be worth mentioning this is a web application made in netbeans 6.9, using the framework GWT 2.1. This application runs in firefox 25.0.1
Thank you!
UPDATE
Here is the code of the event that calls my method
final ComboBoxItem loYesNo=new ComboBoxItem("cmbYesNo" + moSteps[liStepIndex][0],"");
loYesNo.setValueMap("Yes","No");
loYesNo.setVisible(false);
loYesNo.setAttribute("parent", liStepIndex);
loYesNo.addChangedHandler(new ChangedHandler() {
public void onChanged(ChangedEvent poEvent){
String lsStepName=loYesNo.getName();
FormItem loItem=moFrmStepsContainer.getField(lsStepName);
String liStepNumber=String.valueOf(loItem.getAttributeAsInt("parent"));
showNextStep((String)poEvent.getItem().getValue(),liStepNumber);
}
});