I have a need to track mouse position. While I have attempted several ways of doing this, I never am able to follow/capture the position if the mouse is on another monitor.
[DllImport("user32.dll")]
public static extern bool GetCursorPos(ref Point pt);
[DllImport("user32.dll")]
public static extern bool GetCursorInfo(out CURSORINFO pci);
public void GetPosition(out int X, out int Y)
{
Point pt = new Point(0, 0);
X = Y = 0;
if (MouseMonitor.GetCursorPos(ref pt))
{
X = pt.X;
Y = pt.Y;
}
This works but only on one screen. I also read that I might try GetCursorInfo. I have attempted this but it always comes back false.
[DllImport("user32.dll")]
public static extern bool GetCursorInfo(out CURSORINFO pci);
Any suggestions? My goal is to track mouse position (outside of my own app) regardless of what screen it is on.
Your sample code works for me on my dual-monitor system...
You can actually simplify things quite a bit by using the .NET Framework: the System.Windows.Forms.Cursor class has a static Position property.
For example, I created a new Windows Forms project and then dragged a System.Windows.Forms.Timer onto the form. I set the Enabled property to true, and added this code to the Tick event:
this.Text = string.Format("{0}, {1}", Cursor.Position.X, Cursor.Position.Y);
Ran the project and it worked as expected on both my monitors...
Use DWORD GetMessagePos() - it gives you the last windows message mouse position. But be careful, it returns DWORD, but inside there are two SHORTS (16-bit signed ints) packed. So LOWORD/HIWORD macros (or C# respective) won't work.
http://msdn.microsoft.com/en-us/library/ms644938(VS.85).aspx
Related
I tried several ways, but none of them looked like the right solution.
One solution that only works for Windows and only in full screen mode. However, this solution does not work well and looks very wrong:
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern int SetCursorPos ( int x , int y );
void SetCursorPositionToCenter()
{
SetCursorPos(Screen.width/2, Screen.height/2);
}
I also tried to override the BaseInput class. This script is needed so that Input does not come from the mouse, but through the center of the screen. However, when moving the cursor to the blocked state, the BaseInput override is ignored. I assume that this is due to the fact that this function is not called at all when the cursor is put into the locked state.
public class MyInput : BaseInput {
public override Vector2 mousePosition{
get { return Camera.main.ViewportToScreenPoint(new Vector3(0.5f, 0.5f)); }
}
public void Start(){
GetComponent<StandaloneInputModule>().inputOverride = this;
}
}
Is it possible to interact with Canvas through the center of the screen when the cursor is locked? It is important that all Canvas events are handled.
my brothers and sisters from another mother : )
I'm trying using unity to implement a swipe menu, which is like the apps menu on a smart phone. I want to get the current corner's local location value, so I can use them as a reference to do some stuff. However, while I'm dragging the object, the corners' value seems remain fixed, which looks weird to me, since the object's relative position (local position) to its parent is definitely changed, I don't know why the corners' location position can all the way just stay the same.
public class pageSwiper: MonoBehaviour, IDragHandler
{
private Vector3 panelLocation;
void start() {panelLocation = transform.position;}
public void OnDrag(PointerEventData data)
{
float difference = data.pressPosiiton.x - data.position.x;
transform.position = panelLocation - new Vector3(difference,0,0);
Vector3[] corners = new Vector3[4];
GetComponent<RectTransform>().GetLocalCorners(corners);
Debug.Log(corners[0].x)
Debug.log(corners[3].x)
}
}
while I using using pointer (mouse) drag the object, the Debug's log value always be the same. Should they change as the object moving, shouldn't they?
You are using GetLocalCorners which are relative to the center of your object.
You can try using GetWorldCorners.
I'm making a spigot plugin (version 1.8.8) that has an function that I know works because it fires flawlessly through my command. However, when I call it at the end of a PlayerExpChangeEvent, it seems like vanilla leveling overrides the bar, making it go up way more that it is supposed to. Running the command/function after this happens makes the bar go back to how it is supposed to be. I've tried setting my event's priority to highest (and when that didn't work, to lowest) but no matter what my function appears to be completely ignored when called inside the event.
Here is some code:
#EventHandler(priority=EventPriority.HIGHEST)
public void onXpGain(PlayerExpChangeEvent event)
{
// Load custom levels from config
ArrayList<String> levelList = new ArrayList<String>(plugin.getConfig().getStringList("levels"));
if (!((String)levelList.get(0)).equals("none"))
{
Player player = event.getPlayer();
Iterator<String> var4 = levelList.iterator();
while (var4.hasNext())
{
String s = (String)var4.next();
String[] splits = s.split(" ");
int levelCompare = Integer.parseInt(splits[0]);
int playerLvl = player.getLevel();
// Detect if on correct tier, else continue iteration
if (playerLvl == levelCompare - 1)
{
// Calculate the player's new XP amount
int totalXp = player.getTotalExperience() + event.getAmount();
player.setTotalExperience(totalXp);
updateBar(event.getPlayer()); // <-- THIS IS THE FUNCTION
return;
}
}
// At max level
player.setTotalExperience(player.getTotalExperience() + event.getAmount());
player.setLevel(getHighestLevel(levelList));
player.setExp(1.0f);
}
}
And here is the function itself. Keep in mind that it works fine when called through a command and not an event. It's purpose is to use the player's total XP to set the level and bar. Neither set correctly in the event; it instead embraces vanilla leveling.
public static void updateBar(Player player) {
ArrayList<String> levelList = new ArrayList<String>(plugin.getConfig().getStringList("levels"));
int totalXp = player.getTotalExperience();
player.setLevel(getHighestLevelForXp(totalXp, levelList));
if (player.getLevel() < getHighestLevel(levelList)) {
int lvlDiff = getTotalXpToLevel(player.getLevel() + 1,levelList) - getTotalXpToLevel(player.getLevel(),levelList);
int xpDiff = totalXp - getTotalXpToLevel(player.getLevel(),levelList);
player.setExp((float)xpDiff/lvlDiff);
} else {
player.setLevel(getHighestLevel(levelList));
player.setExp(0.0f);
}
return;
}
The command where the function works correctly is a bare-bones call to the function and doesn't need a mention here. Does anyone know how to get my event to override vanilla xp gain? The update works through the command, just not natural xp gain. It is already confirmed that the event DOES fire, as the rest of the event changes the internal xp amount, but the visual effects are overridden by vanilla. Can anyone help? Thanks.
Only setting the Player's EXP won't be enough for your desired behaviour. The Vanilla behaviour will still complete, as you're not changing how the event will add EXP to the player.
Currently, your event is working like this:
And PlayerExpGainEvent isn't cancellable, so you cannot undo it's addition of EXP.
What you can do instead is to set the EXP the event will add to 0, therefore not changing the player's EXP after your interception.
event.setAmount(0); //Cancelling the EXP addition
I would recommend to set your event to a high priority, so that other events that depend on Experience gain won't trigger when you set the amount gained to 0.
I just got into Editor Scripting recently and I'm still getting a hold of all the basics. I wanted to know if the IntSlider (that we use to create a slider of integer values) has any methods or functions that can be used to get more functionality?
Something like the Slider class:
You have -maxValue, -minValue, -value, -onValueChanged (Callback executed when the value of the slider is changed)
These work during the "Play" mode.
I need to access this information while in the editor. Specifically: I need to access the onValueChanged (if it exists) of the IntSlider so I can assign a function for it to execute.
IntSlider Code:
totalRooms = EditorGUILayout.IntSlider(new GUIContent ("Total Rooms"), totalRooms, 0, 10);
Is there a way to achieve this for the inspector? Or something that can be created to solve this? If you can point me in the right direction, I'd be grateful.
I'm using Unity 5.3.1f
There is no such event in Unity at the moment. However this can be implemented easily like this:
Add a UnityEvent in your actual script.
public UnityEvent OnVariablesValueChanged;
Then in your editor script check if value is changed. (Note: I tried to write easily understandable code sample for this. you can change it accordingly)
[CustomEditor(typeof(MyScript))]
public class MyScriptEditor : Editor
{
public override void OnInspectorGUI()
{
MyScript myTarget = (MyScript)target;
int prevValue = myTarget.variable;
myTarget.variable = EditorGUI.IntSlider(new Rect(0,0,100, 20), prevValue, 1, 10);
int newValue = myTarget.variable;
if (prevValue != newValue)
{
Debug.Log("New value of variable is :" + myTarget.variable);
myTarget.OnVariablesValueChanged.Invoke();
}
base.OnInspectorGUI();
}
}
Then add listener to OnVariablesValueChanged event from inspector.
Hope this helps.
I have a game play scene in which the user can zoom in and out, for which I used smooth camera in the following manner:
public static final int CAMERA_WIDTH = 1024;
public static final int CAMERA_HEIGHT = 600;
public static final float MAXIMUM_VELOCITY_X = 400f;
public static final float MAXIMUM_VELOCITY_Y = 400f;
public static final float ZOOM_FACTOR_CHANGE = 1f;
mSmoothCamera = new SmoothCamera(0, 0,
Constants.CAMERA_WIDTH,
Constants.CAMERA_HEIGHT,
Constants.MAXIMUM_VELOCITY_X,
Constants.MAXIMUM_VELOCITY_Y,
Constants.ZOOM_FACTOR_CHANGE);
mSmoothCamera.setBounds(0f, 0f,
Constants.CAMERA_WIDTH,
Constants.CAMERA_HEIGHT);
But the above creates a problem for me. When the user performs zoom-in and leaves game play scene, then other scene behaviours do not look good. I have set zoom factor to 1 to fix this. But now it shows camera translation in other scenes. Because scene switching time it so short, the player can easily see camera translation, which is something I don't want. After the camera repositions, everything works perfect but how do I set camera position properly?
For example, my loading text moves from bottom to top or vice versa, based on camera movement. Please let me know if I can provide more details.
Please give more detail so that I can help you, or you can use the following method:
mSmoothCamera.setMaxVelocity() method and mSmoothCamera.setCenter()
And increase your MAXIMUM_VELOCITY_X and MAXIMUM_VELOCITY_Y value, e.g. to more than 800 or 1000. Example:
mSmoothCamera.setMaxVelocity(x, y)
where x = MAXIMUM_VELOCITY_X and y = MAXIMUM_VELOCITY_Y.
Following is optional:
mSmoothCamera.setCenter(as_per_your_requirement);
where as_per_your_requirement means the camera center.
I don`t know if this issue is still valid but I had also this issue, try use mCamera.setZoomFactorDirect(1.0f); in your menu scene constructor.
It`s works for me