Gun should shoot only when button is touched instead of entire screen - unity3d

I've made a 3d game and I have a first person controller, control by a joystick. I want my player to shoot only when I touch a button on the screen, but now my player shoots if I touch anything on the screen. This is the script for the shoot function:
using UnityEngine;
using UnityEngine.UI;
public class Gun : MonoBehaviour
{
public float damage = 10f;
public float range = 100f;
public Camera fpsCam;
public Button button;
// Start is called before the first frame update
void Start()
{
//Calls the TaskOnClick/TaskWithParameters/ButtonClicked method when you click the Button
button.onClick.AddListener(TaskOnClick);
}
// Update is called once per frame
void Update()
{
Vector3 forward = transform.TransformDirection(Vector3.forward) * 10;
Debug.DrawRay(transform.position, forward, Color.green);
}
void Shoot()
{
RaycastHit hit;
if( Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range))
{
Debug.Log(hit.transform.name);
Target target = hit.transform.GetComponent<Target>();
if(target != null)
{
target.TakeDamage(damage);
}
}
}
void OnCollisionEnter(Collision collision)
{
Debug.DrawRay(collision.contacts[0].point, collision.contacts[0].normal, Color.green, 2, false);
}
void TaskOnClick()
{
Shoot();
}
}

Your Shoot() method runs whenever you press the "Fire1" button, since the only check you are doing is if (Input.GetButtonDown("Fire1")).
If you want to depend on a button to fire you need to take this part of the code out and call Shoot() whenever you click the button.
You can add the event to the button using code, as explained here
public Button m_YourFirstButton;
void Start()
{
//Calls the TaskOnClick/TaskWithParameters/ButtonClicked method when you click the Button
m_YourFirstButton.onClick.AddListener(TaskOnClick);
}
void TaskOnClick()
{
//Output this to console when Button1 or Button3 is clicked
Debug.Log("You have clicked the button!");
}
or you could call it from the inspector by referencing your Gun monobehaviour.

Related

How to create a button that slides out when the mouse hovers over it? (Unity2D)

I have a button that I want to slide out from Y position 295 to 205 when the mouse hovers/touches the button, than slides back if the mouse no longer touches the button.
This is my code, the script is on the button I want to move, I tried using RaycastHit2Ds to detect mouse position.
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class SlideButton : MonoBehaviour
{
public Button button;
float slideDownY = 205f;
float slideUpY = 295f;
public float slideSpeed = 5f;
public RectTransform rectTransform;
private void Start()
{
button.onClick.AddListener(OnButtonClick);
}
// Update is called once per frame
void Update()
{
RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
if(hit.collider != null)
{
Debug.Log("success");
rectTransform.anchoredPosition = Vector2.Lerp(rectTransform.anchoredPosition, new Vector2(rectTransform.anchoredPosition.x, slideDownY), slideSpeed * Time.deltaTime);
}
else
{
rectTransform.anchoredPosition = Vector2.Lerp(rectTransform.anchoredPosition, new Vector2(rectTransform.anchoredPosition.x, slideUpY), slideSpeed * Time.deltaTime);
}
}
void OnButtonClick()
{
// add after slider works
}
}
I have also tried OnMouseEnter/OnMouseExit and OnPointerEnter/OnPointerExit but none have worked either. I haven't found anything that has solved this problem, other answers are all in different languages or not specific enough to help.

How to Jump by Button UI using Character Controller in Unity3D

I am calling JUMP function from a UI Button but unable to jump using Character Collider provided by Unity. Can someone please help me where am i going wrong?
PlayerMovement Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class PlayerControllerCC : MonoBehaviour
{
public FixedJoystick moveJoystick;
CharacterController _charController;
private Vector3 v_movement;
private Animator _animator;
public float moveSpeed = 0.1f;
public float gravity = 0.5f;
public float jumpForce = 0.5F;
private float originalstepOffset;
private float InputX;
private float InputZ;
// Start is called before the first frame update
void Start()
{
moveSpeed = 0.1f;
gravity = 0.5f;
jumpForce = 0.5F;
_charController = GetComponent<CharacterController>();
originalstepOffset = _charController.stepOffset;
_animator = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
InputX = moveJoystick.Horizontal;
InputZ = moveJoystick.Vertical;
isWalking();
}
private void FixedUpdate()
{
playerMovement();
}
void playerMovement()
{
//Check Gravity
if (_charController.isGrounded)
{
_charController.stepOffset = originalstepOffset;
v_movement.y = -0.5f;
}
else
{
_charController.stepOffset = 0;
v_movement.y -= gravity * Time.deltaTime;
}
//player movement
v_movement = new Vector3(InputX * moveSpeed, v_movement.y, InputZ * moveSpeed);
float magnitute = Mathf.Clamp01(v_movement.magnitude);
v_movement.Normalize();
_charController.Move(v_movement * magnitute);
Vector3 lookDir = new Vector3(v_movement.x, 0, v_movement.z);
//Set rotation facing after player movement
if ((lookDir.x != 0) && (lookDir.z != 0))
{
transform.rotation = Quaternion.LookRotation(lookDir);
}
}
void isWalking()
{
if (InputX == 0 && InputZ == 0)
{
_animator.SetBool("isWalking", false);
}
else
{
_animator.SetBool("isWalking", true);
}
}
public void Attack()
{
_animator.SetTrigger("isAttacking");
}
public void Jump()
{
if (_charController.isGrounded)
{
v_movement.y = jumpForce * Time.deltaTime;
}
}
}
When button is clicked in UI it called the JUMP function. I am not using keyboard but FixedJoyStick hence using button to jump.
My Game looks like this and the UI. The up arrow key is the jump button.
The Game button Up Arrow Jump
Calling Jump Function in Button
Your problem lays on the OnClick() function of the button, it is interacting with the script but the script itself is not attached to any character in this case. What you did works when the script works by itself no matter where is attached (e.g. when you call all the objects with a tag).
What you need to do is to link the object which has the script to the OnClick() in the editor, then select from the dropdown menu the script component and then call the function you want.
Like This.
Image link since I'm new
Notice how what is linked are the Game Objects and then the script is selected.

How to make button image change with on click anywhere on screen?

I am very new to Unity and I have trouble understanding on click possibilities with my UI buttons etc.. In my project, I have a button which changes its image whenever I click on it and the way I made it is: I created this script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
[RequireComponent(typeof(Button))]
public class OnClickScript : MonoBehaviour
{
public static int spritenumber=1;
public Button mybutton;
public Sprite square;
public Sprite circle;
public Sprite triangle;
public int counter = 1;
void Start()
{
mybutton = GetComponent<Button>();
}
public void changeButton()
{
if (PAUSESCRIPTE.isPaused == false)
{
counter++;
if (counter == 1)
{
mybutton.image.overrideSprite = square;
spritenumber = 1;
soundmanagerscript.PlaySound("buttonpress");
}
if (counter == 2)
{
mybutton.image.overrideSprite = circle;
spritenumber = 2;
soundmanagerscript.PlaySound("buttonpress");
}
if (counter == 3)
{
mybutton.image.overrideSprite = triangle;
spritenumber = 3;
counter = counter - 3;
soundmanagerscript.PlaySound("buttonpress");
}
}
}
}
I attached this script to my button, selected sprites which I want to use and I added on On Click() function to the button.
Afterwards I decided that I no longer want to change the sprite of my button by clicking on the button itself but rather by clicking anywhere on the screen. I tried using Input.GetMouseButtonDown(0) but got no results since I used it incorrectly. Any help on, how to achieve what I want, is very welcome. Thanks in advance.
Here's how I'd do it:
using UnityEngine.UI;
using UnityEngine;
public class ButtonScript : MonoBehaviour
{
// Public objects
public Sprite[] sprites;
//Private objects/variables
private Image buttonImage;
private int spriteIndex;
void Start()
{
buttonImage = GetComponent<Image>(); // Get the image component of your button
spriteIndex = 0; // Set the index to 0
buttonImage.sprite = sprites[spriteIndex]; // Set the image to the first image in your sprite array
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
spriteIndex++; // Increment the index
if (spriteIndex > sprites.Length - 1) // Ensure that you stay within the array size
{
spriteIndex = 0;
}
buttonImage.sprite = sprites[spriteIndex]; // Set the image
}
}
}
However, you need to change the image settings to:
Image Type: simple
Use Sprite Mesh: true
(maybe) Preserve aspect: true
As an answer to your comment above, I will suggest you to have a button in the background and your pause button above. Then, replace your Update() method with an event OnClick() as you did before.
Your pause button will catch the left click and your background button will not.
Be sure to tick Interactable in the Button component.
Then you can safly remove the Image component of your background button, if you don't need it.
What it means is you can create (or modify) a class for your pause button
using UnityEngine.EventSystems;
public class PauseButton : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
public bool IsMouseOver = false;
public void OnPointerEnter(PointerEventData eventData)
{
IsMouseOver = true;
}
public void OnPointerExit(PointerEventData eventData)
{
IsMouseOver = false;
}
// --
// Your OnClick method
// --
}
Note: the using eventSystems.
Now you can use this bool value within a code like amengelbrecht send you.
I'll will copy and paste his code from his answer, and add the bool value based on the previous class above.
public class BackgroundButtonScript : MonoBehaviour
{
// Public objects
public Sprite[] sprites;
public PauseButton pauseButton;
//Private variables
private Image buttonImage;
private int spriteIndex;
private void Start()
{
buttonImage = GetComponent<Image>(); // Get the image component of your button
spriteIndex = 0; // Set the index to 0
buttonImage.sprite = sprites[spriteIndex]; // Set the image to the first image in your sprite array
}
private void Update()
{
if (Input.GetMouseButtonDown(0) && !pauseButton.IsMouseOver)
{
spriteIndex++; // Increment the index
if (spriteIndex > sprites.Length - 1) // Ensure that you stay within the array size
{
spriteIndex = 0;
}
buttonImage.sprite = sprites[spriteIndex]; // Set the image
}
}
}
This will allow you to click anywhere on your screen except if the mouse is over your pause button. In this case, OnClick from the pause button will be called.
Be careful
If your game is is pause and the user left click anywhere but the pause button, depends on how your pause works, the Update() method of BackgroundButtonScript will be called and can lead to if (Input.GetMouseButtonDown(0) && !pauseButton.IsMouseOver).

Trying to set gravity modifier with script

I want to set the gravity modifier of an object to 2 when the mouse is clicked down, then go back down to .3 when it is released.
I think its just a simple stupid error.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour
{
public Rigidbody2D rb;
public float idle = .3f;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
rb.gravityScale = 2f;
}
else
{
rb.gravityScale = .3f;
}
}
}
GetMouseButtonDown will only return true on the exact frame that the mouse button was pressed down. This means that if you hold it down, your else block will run every frame other than the one it was pressed. You can instead check for the mouse being released with GetMouseButtonUp and change it back when that happens:
if (Input.GetMouseButtonDown(0))
{
rb.gravityScale = 2f;
}
if (Input.GetMouseButtonUp(0))
{
rb.gravityScale = .3f;
}
or you can be more specific with your first if and then use an empty else:
if (Input.GetMouseButtonDown(0) || Input.GetMouseButton(0))
{
rb.gravityScale = 2f;
}
else
{
rb.gravityScale = .3f;
}
GetMouseButton will return true during any frame it's held.

How to simulate a mouse up event?

There is a bug in my code: When I release the mouse out of the screen, the unity can't detect "GetMouseButtonUp", and when I move the released mouse back to the screen, it detects the "GetMouseButton" which should not.
So when the mouse out of the screen, I want simulate send a mouse up event to let the unity detect "GetMouseButtonUp".
How to simulate a mouse event?
Pseudo code
bool mouseIsDown = false;
public void Update()
{
Rect screenRect = new Rect(-Screen.width/2, -Screen.height/2, Screen.width, Screen.height);
If(screenRect.Contains(Input.mousePosition))
{
if(mouseIsDown && !Input.GetMouseButton(0))
OnMouseUp();
if(Input.GetMouseButton(0))
{
OnMouse();
if(!mouseIsDown)
{
OnMouseDown();
mouseIsDown = true;
}
}
}
}
public void OnMouseDown()
{
// Do something
}
public void OnMouse()
{
// Do something
}
public void OnMouseUp()
{
// Do something
}
I am not sure if I correctly understand your question. But, you can use these functions the same way you would use the Start() Update() Awake() etc. functions
void OnMouseUp () {
}
void OnMouseDown (){
}