I'd like to know how can I perform for example a right mouse click, or press ENTER with XNA, is it possible? I want the XNA prog to do the action, not to check if I clicked it.
Thanks.
You can use the following to make the cursor of the mouse visible (if this is necessary):
protected override void Initialize()
{
// Make mouse visible
this.IsMouseVisible = true;
base.Initialize();
}
Create the following variables, this way you can save the current and previous mouseState:
MouseState mouseStateCurrent, mouseStatePrevious;
In the Update function you can use the following:
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
{
this.Exit();
}
// Get current mouseState
mouseStateCurrent = Mouse.GetState();
// Left MouseClick
if (mouseStateCurrent.LeftButton == ButtonState.Pressed)
{
// TODO when left mousebutton clicked
}
// Right MouseClick
if (mouseStateCurrent.RightButton == ButtonState.Pressed && mouseStatePrevious.RightButton == ButtonState.Released)
{
//TODO when right mousebutton clicked
}
mouseStatePrevious = mouseStateCurrent;
// Update
base.Update(gameTime);
}
Hopefully this is of some use to you!
Just call the function that clicking would call
So leftClick gets called when the user clicks, but you can call that function whenever you want
edit: Another thing you can do if you can do if you want to call mouseClick yourself (instead of leftClick) is to have your own variable sent in, and have an enum for different states you want to define.
enum CLICKS{left=0, right, middle);
public void mouseClick(){
mouseClick(-1);
}
public void mouseClick(int manualClick){
if(mouseStateCurrent.LeftButton == ButtonState.Pressed || manualClick == CLICKS.left)
leftClick();
}
public void leftClick(){
//do stuff
}
public void randomFunction(){
//doing stuff
mouseClick(CLICKS.left); //<-- will simulate a left click
}
If you'd like to simulate real mouse pressed, you can use the SendInput Win32 method.
Ths is not as easy as the technique already offered here, but the game will not be able to distinguish whether these clicks originated from real user clicks or simulated ones.
Also check out this StackOverflow question that discussed the same issue.
Related
I am working on this 3d game were a player has to press E to interact with objects.
the player has a collider that when touching a type of trigger that has this type of code, makes an object pop up showing that the player's is "selecting" something.
when the player is in the trigger I made it were when they press E, the objects animation plays. When adding the objecting selecting thing it made it now that I cant make the animation play when pressing E
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Fixedpress : MonoBehaviour
{
public Animator Tributton;
public GameObject GM;
private Coroutine routine;
private void Start()
{
GM.SetActive(false);
}
private void OnTriggerStay(Collider other)
{
// in general rather use CompareTag instead of ==
// it is slightly faster and also shows an error if the tag doesn't exist instead of failing silent
if (!other.CompareTag("LookTrig")) {
GM.SetActive(true);
return;
}
// just in case to prevent concurrent routines
if (routine != null) StopCoroutine(routine);
// start a new Coroutine
routine = StartCoroutine(WaitForKeyPress());
}
private IEnumerator WaitForKeyPress()
{
// check each FRAME if the key goes down
// This is way more reliable as OnTriggerStay which is called
// in the physics loop and might skip some frames
// This also prevents from holding E while entering the trigger, it needs to go newly down
yield return new WaitUntil(() => Input.GetKeyDown(KeyCode.E));
// set the trigger once and finish the routine
// There is no way to trigger twice except exit the trigger and enter again now
Tributton.SetTrigger("Fiveyon");
Debug.Log("Fiveyon!");
// If you even want to prevent this from getting triggered ever again simply add
enabled = false;
// Now this can only be triggered ONCE for the entire lifecycle of this component
// (except you enable it from the outside again of course)
}
void OnTriggerExit(Collider other)
{
if (!other.CompareTag("LookTrig")) {
GM.SetActive(false);
return;
}
// when exiting the trigger stop the routine so later button press is not handled
if (routine != null)
{
StopCoroutine(routine);
GM.SetActive(false);
}
}
}
OnTrigger methods are called when another object with a Collider enters in your object Collider.
First, make sure everything was well set up well, and maybe you want to use OnCollision instead of OnTrigger methods, if you want to detect a collision whether than a "penetration" if i may say
I am trying to add a menu in my 2D unity game where the user can specify which controls they prefer to use in the game. Right now I have a script where the code for the main character movements are specified as follows:
private void Update()
{
// Set the new direction based on the current input
if (Input.GetKeyDown(KeyCode.W) || Input.GetKeyDown(KeyCode.UpArrow)) {
movement.SetDirection(Vector2.up);
}
else if (Input.GetKeyDown(KeyCode.S) || Input.GetKeyDown(KeyCode.DownArrow)) {
movement.SetDirection(Vector2.down);
}
else if (Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.LeftArrow)) {
movement.SetDirection(Vector2.left);
}
else if (Input.GetKeyDown(KeyCode.D) || Input.GetKeyDown(KeyCode.RightArrow)) {
movement.SetDirection(Vector2.right);
}
// Rotate the main character to face the movement direction
float angle = Mathf.Atan2(movement.direction.y, movement.direction.x);
transform.rotation = Quaternion.AngleAxis(angle * Mathf.Rad2Deg, Vector3.forward);
}
Instead of for example Input.GetKeyDown(KeyCode.W) || Input.GetKeyDown(KeyCode.UpArrow) I'd like to listen to what the user has typed in, in a "controls" menu. However, I don't know how this menu should be connected to the script.
Does anyone have any suggestions on how this can be done or if there is some website/video that I can watch where this is implemented?
Thanks in advance,
N
Ah, key binding. There is no easy way of adding keybinds.
You would have to loop through all the keycodes and see if any are pressed. It isn't efficient but it works in this context.
foreach(KeyCode kcode in Enum.GetValues(typeof(KeyCode)))
{
if (Input.GetKey(kcode))
{
// Set key to given keycode.
return;
}
}
After that, you should save what key the user pressed into a file or into PlayerPrefs.
When the player starts the game again, just read it and set it back.
When running the following code in a loop (var enterKey = Keyboard.GetState().IsKeyDown(Keys.Enter);) pushing the enter key returns true even after I've released the key.
Any ideas as to what I'm doing wrong?
Try checking like this:
KeyboardState newState;
public void Update(...)
{
newState = Keyboard.GetState();
if(newState.IsKeyDown(Keys.Enter))
{
*do what you want here*
}
}
This way, on each update you are updating current keyboard state (which keys are pressed), so you can check for different key presses in each frame.
EDIT:
You are likely to want to check for a single click, so instead of asking 2 question, here is a "bonus" to your question. Code is similar:
KeyboardState newState, oldState;
public void Update(...)
{
//gets keyboard state for this single frame
newState = Keyboard.GetState();
//checks if enter is down
if(newState.IsKeyDown(Keys.Enter))
{
*do what you want here*
}
// checks if enter is clicked
// if statement asks if in this frame, enter button is down
// AND if enter button was not down in the last frame
// this way, if statement below will fire only on each click
if(newState.IsKeyDown(Keys.Enter) && oldState.IsKeyUp(Keys.Enter))
{
*do what you want here*
}
//set old state to new state, so the next frame knows
//what was happening in frame before that one
oldState = newState;
}
I suspect the state of the keyboard only gets refreshed between Update(...) cycles (or a close equivalent thereof) so looping is not going to do anything useful.
To detect changes in keyboard state, you'll want to compare keyboard states between successive calls to Update(...).
Restarting my computer fixed the problem, it must have been a bug outside of the code.
I am making simple game in witch a player touches anywhere on the screen to do something. It is a kind of reflex game. At the same time I have button on the screen that allows to pause a game. The problem is that when I touch a button a game detects a screen touch at the same time and I would like to avoid that. I use a boolean that I change on button press but it still doesnt work properrly - game is paused just a fraction of the second after the screen touch is detected.
My pause game code:
GameControlerScript:
public static bool isPaused;
public void PauseGame()
{
isPaused = true; // this is static
Time.timeScale = 0.0f;
//more code here
}
and my touch detection in the script attached to different object:
void Update()
{
if (((Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began) || (Input.GetKeyDown(KeyCode.Space))) && !GameControllerScript.isPaused)
{
// code here starts to be executed and then pasues because of timescale
}
}
So is there a way to make get the change to the isPaused boolean before it detects scrren touch?
check it your touch is on the UI element then if it isn't call whatever method you call for normal input
public void Update()
{
foreach (Touch touch in Input.touches)
{
if (EventSystem.current.IsPointerOverGameObject(touch.fingerId))
{
// you touched at least one UI element
return;
}
}
// you didnt touched any UI element
// Do Something
}
Essentially I have a door trigger event where if the player presses the switch then the door open. I wish however to do it so that if the door associated needs two switches to open well... then it only opens if two switches are pressed. Here is my code for my InteractSwitch
public class InteractSwitch : MonoBehaviour
{
Animator animator;
public DoorEventTrigger[] doorTriggers;
public bool pressed;
private bool down;
// Use this for initialization
void Start ()
{
animator = GetComponent <Animator> ();
}
// Update is called once per frame
void Update ()
{
}
void OnCollisionEnter2D (Collision2D target)
{
if (target.gameObject.tag == "Player") {
down = true;
animator.SetInteger ("SwitchTrig", 1);
foreach (DoorEventTrigger trigger in doorTriggers)
if (trigger != null)
trigger.Toggle (true);
}
}
When triggered this event checks for player, shows switch has been pressed then sends a bool to a function called Toggle which handles the operation of the door.
Next I have my DoorEventTrigger event which checks if the bool sent = true. If it is then the door will open. Here is where I am stuck. As seen in the code I have created a array of InteractSwitch which stores the amount of switches I want the player to have pressed before the door will open. I then state that if the length > 1 then this if condition is true and some code will be added here which will then open the door only if the player has selected the InteractSwitch[].length switches. My question is how would I check that all instances of InteractSwitch for this DoorEventTrigger equals true?
Here is my DoorEventTrigger code
public void Toggle (bool val)
{
if (switchTriggers.Length > 1) {
Debug.Log ("HAS THIS ACTUALLY DONE ANYTHING");
door.Open ();
}
else
{
if (val)
door.Open ();
else
door.Close ();
}
}
}
The solution I came up with is nowhere near I believe the most efficient answer as it requires code each time u add a new switch but this is what I have
firstly in the InteractSwitch script the bool down is public so it can be accessed by the switchtriggers
public bool down;
Next is the added code to the Toggle() method
public void Toggle (bool val)
{
if (switchTriggers.Length > 1) {
if((switchTriggers[0].down == true) && (switchTriggers[1].down == true)){
Debug.Log ("THIS ACTUALLY DONE SOMETHING!");
door.Open ();
}
}
else
{
if (val)
door.Open ();
else
door.Close ();
}
}
Now from the public SwitchInteract[]; I know the exact amount of elements in the array however this could be checked through switchTriggers.length; Knowing there is two elements in the array my condition switchTriggers.Length > 1 is correct so next I take the two elements in the array and check if they are down; if BOTH are down then the condition continues and the Debug.Log() validates this. Finally Open() is called which opens the door.
You can have the switches increment or decrement a required switch variable in the door object.
Give the door object a requiredSwitch variable.
Give each switch a door variable and set it to the door it controls.
When a switch is activated, have it decrement its door's requiredSwitch variable.
When the door's requiredSwitch variable is 0, then the door opens.
You can also have the switches increment the variable if they get deactivated.
This solution allows you to add switches by just setting the door variable of the switch and incrementing the door's initial requiredSwitch variable.