I am following this tutorial to learn how to use OpenGL in C#. Everything ran fine until this part: OpenGL 4 with OpenTK in C# Part 10: Asteroid Invaders. I am not using the exact same OpenTK as the one used in the tutorial. I am using this version that is compatible with .NET Core here: https://www.nuget.org/packages/OpenTK.NETCore/
Issue
Seems that OpenTK does not detect my keyboard. I have a simple update loop that handles keyboard input like this:
OnUpdateFrame
protected override void OnUpdateFrame(FrameEventArgs e)
{
base.OnUpdateFrame(e);
this.HandleKeyboard(e.Time);
// {...} Update Logic
}
HandleKeyboard
protected void HandleKeyboard(double delta)
{
Console.WriteLine("Handling keyboard");
var keyState = this.Keyboard.GetState();
if (keyState.IsKeyDown(Key.Escape))
{
this.Exit();
}
if (keyState.IsKeyDown(Key.A))
{
Console.WriteLine("Moving left");
this.player.MoveLeft();
}
if (keyState.IsKeyDown(Key.D) {
Console.WriteLine("Moving right");
this.player.MoveRight();
}
if (!this.gameOver && keyState.IsKeyDown(Key.Space) && this.lastKeyboardState.IsKeyUp(Key.Space))
{
this.gameObjects.Add(this.gameObjectFactory.CreateBullet(this.player.Position));
}
this.lastKeyboardState = keyState;
}
The console shows Handling keyboard many times, when I press A or D it doesn't write Moving left or Moving right. When I debug, and hover over keystate there is a property IsConnected = false. Maybe OpenTK is not recognizing my keyboard?
I am using the laptop keyboard so nothing fancy.
According to the documentation on Keyboard.GetState() it says Gets the primary Keyboard device, or null if no keyboard exists. But it doesn't return null?
How can I solve this? Thanks
Minimal example
I tried this on a separate solution:
using System;
using OpenTK;
using OpenTK.Input;
namespace OpenTKTest
{
class Program
{
[STAThread]
static void Main(string[] args)
{
using (var window = new GameWindow())
{
window.UpdateFrame += (sender, eventArgs) =>
{
var state = window.Keyboard.GetState();
if (state.IsKeyDown(Key.A))
{
Console.WriteLine("KEYSTATE");
}
};
window.KeyDown += (sender, eventArgs) =>
{
if (eventArgs.Key == Key.A)
{
Console.WriteLine("KEYDOWN EVENT");
}
};
window.Run(60);
}
}
}
}
And effectively, when I press the A key, KEYDOWN EVENT gets written but not KEYSTATE. So definitely a bug.
From what I gather (having experienced similar results), OpenTK.Input.Keyboard API is not yet implemented.
Related
I have created a simple custom editor tool, which allows me to keep mouse position in a straight line. I require this to draw texture on a terrain in a straight line. Unfortunately, when I enable "Paint texture" tool in the terrain editor in inspector, my custom tool gets disabled and vice-versa. How can I keep both my custom tool and terrain paint tool enabled at once?
Custom tool selected but paint texture is deactivated-
Custom tool got deselected on paint texture selection-
Following is the OnToolGUI method
public override void OnToolGUI(EditorWindow window)
{
HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));
Event e = Event.current;
if (!(window is SceneView))
return;
if (!ToolManager.IsActiveTool(this))
return;
if (e.shift)
{
if (e.type == EventType.MouseDown)
{
if (e.button == 0)
{
downY = e.mousePosition.y;
}
}
if (e.type == EventType.MouseDrag)
{
if (e.button == 0)
{
e.mousePosition = new Vector2(e.mousePosition.x, downY);
Debug.Log("Mouse Position: " + e.mousePosition);
}
}
}
As mentioned in the comments I guess it simply is the nature of the tools that they are exclusive and you can only have one active at a time.
As alternative I would rather simply
enable/disable this via a general header menu entry
(optionally) store that decision persistent in EditorPrefs (pretty much like PlayerPrefs but for the editor itself)
and accordingly attach a listener to SceneView.duringSceneGui
This could look somewhat like e.g.
public static class StraightLineTool
{
// Used for the displayed menu labels
// and also simply (ab)used as the unique key for the EditorPrefs
private const string k_MenuName = "My Tools/Straight Line Tool";
private static float downY;
// Property for simplifying access and setting more centralized
private static bool IsEnabled
{
get => EditorPrefs.GetBool(k_MenuName, false);
set => EditorPrefs.SetBool(k_MenuName, value);
}
// method to be called when clicking the menu button
[MenuItem(k_MenuName)]
private static void ToggleEnabled()
{
IsEnabled = !IsEnabled;
ApplySettings();
}
// adding a checkmark when is enabled and simply always allow to click it
[MenuItem(k_MenuName, true)]
private static bool ToggleEnabledValidate()
{
Menu.SetChecked(k_MenuName, IsEnabled);
return true;
}
// Called on every project loading or code recompilation
[InitializeOnLoadMethod]
private static void Initialize()
{
EditorApplication.delayCall -= ApplySettings;
EditorApplication.delayCall += ApplySettings;
}
private static void ApplySettings()
{
// remove so only happening once
EditorApplication.delayCall -= ApplySettings;
SceneView.duringSceneGui -= OnSceneGUI;
if (IsEnabled)
{
// if enabled start listening
SceneView.duringSceneGui += OnSceneGUI;
}
}
// Callback listening to any SceneView.duringSceneGui
private static void OnSceneGUI(SceneView sceneView)
{
// Not sure tbh what this does or if you need it still in this approach
// HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));
var currentEvent = Event.current;
if (currentEvent.shift)
{
if (currentEvent.type == EventType.MouseDown)
{
if (currentEvent.button == 0)
{
downY = currentEvent.mousePosition.y;
}
}
if (currentEvent.type == EventType.MouseDrag)
{
if (currentEvent.button == 0)
{
currentEvent.mousePosition = new Vector2(currentEvent.mousePosition.x, downY);
Debug.Log("Mouse Position: " + currentEvent.mousePosition);
}
}
}
}
}
=> using this the tool will be enabled/disabled persistent even when restarting Unity
Then using this as start point you can probably still try to somehow integrate this somewhere more nicely into the SceneView menus - but maybe that is also overkill ;)
in the code bellow it´s impossible to print "FBleftcontrol", also depending on the order and combination of keys pressed sometimes other lines are impossible to print
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
bool LeftControl = false;
bool LeftShift = false;
bool LeftAlt = false;
// Update is called once per frame
void Update()
{
LeftControl = Input.GetKey(KeyCode.LeftControl);
LeftShift = Input.GetKey(KeyCode.LeftShift);
LeftAlt = Input.GetKey(KeyCode.LeftAlt);
if (LeftAlt || LeftShift) fb();
else fa();
}
private void fb()
{
print("fb");
if (LeftControl)
{
if (Input.GetKeyDown(KeyCode.Alpha1)) print("leftcontrol");
}
else
{
if (Input.GetKeyDown(KeyCode.Alpha1)) print("NOleftcontrol");
}
}
private void fa()
{
print("fa");
if (LeftControl)
{
if (Input.GetKeyDown(KeyCode.Alpha1)) print("leftcontrol");
}
else if(LeftShift)
{
if (Input.GetKeyDown(KeyCode.Alpha1)) print("leftshift");
}
}
}
Things I´ve tried:
latch booleans;
use all posible combinations of getkey/getkeydown/getkeyup;
put it all in the update and forget about calling functions
Unity Editor is stealing your keyboard focus because most modifier keys are bound to it's GUI.
Try the same code with KeyCode.A, KeyCode.S, KeyCode.C instead of Alt, Shift, Control and your code will work as expected.
This should happen only in the Editor and not in the final build, though.
Unfortunately, I don't know of any solution to avoid this in the Editor:
I would just use different key-bindings during development.
I want to track the windows unlock event in a windows application. How is it done? What is the event used for that? Does I need to import any namespace for that?
While a user unlocks the windows, the application needs to do some tasks.
As posted in this StackOverflow answer: https://stackoverflow.com/a/604042/700926 you should take a look at the SystemEvents.SessionSwitch Event.
Sample code can be found in the referred answer as well.
I just took the code shown in the referred StackOverflow answer for a spin and it seems to work on Windows 8 RTM with .NET framework 4.5.
For your reference, I have included the complete sample code of the console application I just assembled.
using System;
using Microsoft.Win32;
// Based on: https://stackoverflow.com/a/604042/700926
namespace WinLockMonitor
{
class Program
{
static void Main(string[] args)
{
Microsoft.Win32.SystemEvents.SessionSwitch += new Microsoft.Win32.SessionSwitchEventHandler(SystemEvents_SessionSwitch);
Console.ReadLine();
}
static void SystemEvents_SessionSwitch(object sender, Microsoft.Win32.SessionSwitchEventArgs e)
{
if (e.Reason == SessionSwitchReason.SessionLock)
{
//I left my desk
Console.WriteLine("I left my desk");
}
else if (e.Reason == SessionSwitchReason.SessionUnlock)
{
//I returned to my desk
Console.WriteLine("I returned to my desk");
}
}
}
}
I was wondering if anyone has any experience with Datalogic's SDK for Visual Studio.
I'm trying to get the image out of VPM (Vision Program Manager). You have to be a bit familiar with Datalogic's 'Impact' to know where I am talking about. I'm using the function GetData(). The following condition must be made:
Device.GetImagePortValue(VisionPort.CreateFromPath("Inspection.Image In Task:Image"),
Afterward.IfSuccess<VisionImage>((ImageInspection) =>
But That's not the case. Here is the complete Program:
using VisionSDK;
using VisionSDK.Drawing;
using VisionSDK.Events;
namespace SDKCameraImage
{
public partial class MainWindow : Window
{
VisionDevice Device = VisionDevice.Create();
public MainWindow()
{
InitializeComponent();
Device.SetupConnection(VisionDeviceConnectionDetails.CreateForNetworkConnection("127.0.0.1",10001,2000));
GetData();
Device.EventListener.DidAcquiredAnImage += (_, __) =>
{
MessageBox.Show("Image Acquired");
GetData();
};
Device.DeviceConnection.DidConnectHandler += (object sender, VisionEventArgs e) =>
{
//MessageBox.Show("Connection");
};
Device.DeviceConnection.DidDisconnectHandler += (object sender, VisionEventArgs e) =>
{
MessageBox.Show("No Connection");
};
Device.Connect();
}
private void GetData()
{
Device.GetImagePortValue(VisionPort.CreateFromPath("Inspection.Image In Task:Image"),
Afterward.IfSuccess<VisionImage>((ImageInspection) =>
{
ImageViewer.Background = new ImageBrush(ImageInspection.AsImageSource());
}));
}
}
}
I have a connection with the camera. And the camera is in online state.
Hopefuly it's enough info. Thanks in advance!
Dirk
I figured it out!
The solution is to use an image made by a Datalogic camera. If you use any other image it won't show in your application.
I'm not sure yet why this is but now I know how to get it working!
I want to track the windows unlock event in a windows application. How is it done? What is the event used for that? Does I need to import any namespace for that?
While a user unlocks the windows, the application needs to do some tasks.
As posted in this StackOverflow answer: https://stackoverflow.com/a/604042/700926 you should take a look at the SystemEvents.SessionSwitch Event.
Sample code can be found in the referred answer as well.
I just took the code shown in the referred StackOverflow answer for a spin and it seems to work on Windows 8 RTM with .NET framework 4.5.
For your reference, I have included the complete sample code of the console application I just assembled.
using System;
using Microsoft.Win32;
// Based on: https://stackoverflow.com/a/604042/700926
namespace WinLockMonitor
{
class Program
{
static void Main(string[] args)
{
Microsoft.Win32.SystemEvents.SessionSwitch += new Microsoft.Win32.SessionSwitchEventHandler(SystemEvents_SessionSwitch);
Console.ReadLine();
}
static void SystemEvents_SessionSwitch(object sender, Microsoft.Win32.SessionSwitchEventArgs e)
{
if (e.Reason == SessionSwitchReason.SessionLock)
{
//I left my desk
Console.WriteLine("I left my desk");
}
else if (e.Reason == SessionSwitchReason.SessionUnlock)
{
//I returned to my desk
Console.WriteLine("I returned to my desk");
}
}
}
}