Dragging Item With Icon Following Pointer Unity C# [duplicate] - c#

This question already has answers here:
Unity3D UI, calculation for position dragging an item?
(4 answers)
Closed 6 years ago.
How To Dragging Item With Icon Following Pointer ?
MAYBE IT WILL TAKE SOME TIMES TO SEE ALL THE CODE. Many thanks Before for your attention.
But I have done a little Code Before. And it is run successful, but there is some mistake in my code. Actually the icon dragging is following the pointer but it just temporary.
And my prediction is because i make an paging inventory Storage 1 , 2 , and 3. When All of 3 Storgae is visible the dragging item icon run successfull with following the pointer. But if one of the inventory storage was hide for example : i have click storage 2 then storage 1 and 3 are hide then when i dragging the item the icon was not following the pointer. It become Stuck. But still can swap item slot. Just only the icon not following the pointer.
Below is my code it a little long :) I will give the detail code.
slotScript.cs (this script is a prefabs of Slot that show item icon, amount)
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections.Generic;
public class slotScript : MonoBehaviour, IPointerDownHandler, IPointerEnterHandler, IPointerExitHandler, IDragHandler {
Image itemImage;
Sprite icon;
Text amount;
public int slotNumber;
inventory inventoryx;
player Playerx;
item temp;
menu menux;
dragitemicon dragger;
// Use this for initialization
void Start () {
inventoryx = GameObject.FindGameObjectWithTag ("inventory").GetComponent<inventory> ();
itemImage = gameObject.transform.GetChild (0).GetComponent<Image> ();
amount = gameObject.transform.GetChild (1).GetComponent<Text> ();
}
// Update is called once per frame
void Update () {
//Show Images Icon Slot Inventory
if (inventoryx.Player.items[slotNumber].itemName != null) {
itemImage.enabled = true;
icon = Resources.Load<Sprite> (inventoryx.Player.items[slotNumber].itemIcon + "/" + inventoryx.Player.items[slotNumber].itemName);
itemImage.sprite = icon;
amount.text = inventoryx.Player.items[slotNumber].itemStock.ToString();
amount.enabled = true;
} else {
itemImage.enabled = false;
}
}
public void OnPointerDown (PointerEventData data) {
if (inventoryx.Player.items[slotNumber].itemType == item.ItemType.Raw) {
inventoryx.Player.items [slotNumber].itemStock--;
}
//Debug.Log (transform.name);
if (inventoryx.Player.items [slotNumber].itemName == null && inventoryx.draggingitem) {
inventoryx.Player.items [slotNumber] = inventoryx.getdragitem;
inventoryx.closeDragItem ();
//inventoryx.dragitemicon.GetComponent<Image>().sprite = null;
} else if (inventoryx.draggingitem && inventoryx.Player.items[slotNumber].itemName != null ) {
inventoryx.Player.items[inventoryx.indexofdragitem] = inventoryx.Player.items[slotNumber];
inventoryx.Player.items[slotNumber] = inventoryx.getdragitem;
inventoryx.closeDragItem ();
}
}
//On Drag Close ToolTips and Show Drag Item
public void OnDrag (PointerEventData Data) {
if (inventoryx.Player.items[slotNumber].itemType == item.ItemType.Raw) {
inventoryx.Player.items[slotNumber].itemStock++;
}
if (inventoryx.Player.items[slotNumber].itemName != null) {
inventoryx.showDragItem(inventoryx.Player.items[slotNumber], slotNumber);
dragger.showDragItem(inventoryx.Player.items[slotNumber], slotNumber);
inventoryx.Player.items[slotNumber] = new item();
inventoryx.closeToolTips();
amount.enabled = false;
}
}
}
How to change dragging code above i used to this code below :
public class Draggable : MonoBehaviour,
IBeginDragHandler, IDragHandler, IEndDragHandler {
public void OnBeginDrag(PointerEventData eventData) {}
public void OnDrag(PointerEventData eventData) {
//Debug.Log ("OnDrag");
transform.position = eventData.position;
}
public void OnEndDrag(PointerEventData eventData) {}
}
Many Thanks
Dennis

Very fortunately, there is now an
incredibly simple way
to do this in Unity.
Here it is: https://stackoverflow.com/a/37473953/294884
Ask if you have more trouble!

Related

Simple Integer C# Unity i=i+1 not adding

so i'm trying to do a little game on unity . And i did a script , when you press left click on an object , it open a canvas and another one and then it add +1 to i , like that when i found every object . (so when i=3) it shows the end screen. But when i go in game mode , when i press left click it doesnt add the number , like every object have his same i , but i dont understand they have the same function no ?
And sometimes 2 of 3 works, i dont know if thats clear to understand.
using UnityEngine;
using UnityEngine.UI;
public class ActionObjet : MonoBehaviour
{
public Image image1;
public Image image2;
public Image image3;
public int i = 0;
void Start()
{
image1.enabled = false;
image2.enabled = false;
image3.enabled = false;
}
void Update()
{
if (Input.GetKeyDown("space"))
{
if (image1.enabled == true)
{
i = i + 1;
print(i);
image2.enabled = !image2.enabled;
image1.enabled = !image1.enabled;
FindObjectOfType<AudioManager>().Play("bruit_recuperer_objet");
}
}
}
void OnMouseDown()
{
if (image1.enabled == false)
{
image1.enabled = !image1.enabled;
}
}
}
https://i.stack.imgur.com/sOSJH.png
So I found the solution , I'm a bit sad that I wasted 5 hours just for that but yea..
I just changed the
public int i=0
into
static int i=0;
This is because each gameObject with this script has its own instance of all the variables. A static variable's value is universal to all instances of the same class so any one of them can update it for all of them when marked static.

How do I prevent UI button from resetting to start condition on every click? Unity3D

The answer to the boolean issue provided by #Mario below solved the main issue as well
The code in the original post (below the line) had an unrelated problem ('==' instead of '=') but in fixing that I've realized that I am having an issue with the string name of 'cubeRend.material' which includes the additive Instance after it and therefore doesn't seem to be counted as logically equal to the string name of 'material[0].'
I don't THINK that is the issue behind the resetting problem however, because I did find a question about a similar resetting problem on the Unity answer forum here: https://answers.unity.com/questions/1303925/ui-buttons-images-resets-after-scene-reloads-scrip.html
Unfortunately no one provided any responses to that question which I could try to apply in this case. I will try to sort out my equivalency problem and then update with the improved code
I'm trying to make a UI button change the colors on a cube on every click. The materials are in an array. In the start function, I set the initial condition of the cube's renderer to material[0]. In the ChangeCubeColor function (which is referred to on the UI button's inspector), I use a simple if/else statement to check which material is currently assigned to the cube. On clicking the button, Unity seems to reset the material back to the original condition and then invisible to the eye follow the if/else instructions to set the color to the 2nd color in the array. The affect is that on the first time you play, the button will change the color, but every time after that, the color is stuck on the second color.
Here is my code. I apologize for all of the debug statements. I was trying to figure out when the state was or was not changing. I've also included a screenshot of my console upon first play and the first 3 clicks of the button. Lastly, the code with the debug statements removed for clarity.
Thanks in advance for any ideas.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChangeCubeColor : MonoBehaviour
{
public Material[] material;
Renderer cubeRend;
void Start()
{
cubeRend = GetComponent<Renderer>();
cubeRend.material = material[0];
Debug.Log(cubeRend.material);
}
public void CubeColorChange()
{
if(cubeRend.material = material[0])
{
Debug.Log("cubeRend.material = material[0]");
cubeRend.material = material[1];
Debug.Log("Make 1: "+cubeRend.material);
Debug.Log("cubeRend.material = material[1]");
}
else if (cubeRend.material = material[1])
{
Debug.Log("cubeRend.material = material[1]");
cubeRend.material = material[0];
Debug.Log("Make 0: " + cubeRend.material);
Debug.Log("cubeRend.material = material[0]");
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChangeCubeColor : MonoBehaviour
{
public Material[] material;
Renderer cubeRend;
void Start()
{
cubeRend = GetComponent<Renderer>();
cubeRend.material = material[0];
}
public void CubeColorChange()
{
if(cubeRend.material = material[0])
{
cubeRend.material = material[1];
}
else if (cubeRend.material = material[1])
{
cubeRend.material = material[0];
}
}
}
Try this way. This work for 2 materials if you want more you can use an int index and update the index without use if for each material
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChangeCubeColor : MonoBehaviour
{
public Material[] material;
public bool state;
Renderer cubeRend;
void Start()
{
cubeRend = GetComponent<Renderer>();
cubeRend.material = material[0];
//state = false is material 0 //state = true is material 1
state = false;
}
public void CubeColorChange()
{
//Change the state to the other state
state = !state;
cubeRend.material = (state) ? material[1] : material[0];
}
}
EDIT 1:
Here is the variation with index for more materials
using UnityEngine;
public class ChangeCubeColor : MonoBehaviour
{
public Material[] material;
public int index;
Renderer cubeRend;
void Start()
{
cubeRend = GetComponent<Renderer>();
index = 0;
cubeRend.material = material[index];
}
public void CubeColorChange()
{
//Increase index
index = (material.Length - 1 > index) ? index + 1 : 0;
cubeRend.material = material[index];
}
}

Changing the image of long clicked Sprite

I am trying to change the image of a sprite that's had a long click on it.
My below code works except in the LongPress method it changes the image of all sprites that have this script assigned as an inspector component. Additionally, the code triggers after long clicking anywhere onscreen, not isolating itself to just the sprites with the script assinged
OnMouseDownAsButton would solve a lot of the issues, however wrapping bits of my code in an OnMouseDownAsButton function to isolate the colliders seems to cancel out the update() method.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class LongClickButton : MonoBehaviour
{
public Sprite flagTexture;
public Sprite defaulttexture;
public float ClickDuration = 2;
public UnityEvent OnLongClick;
bool clicking = false;
float totalDownTime = 0;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
totalDownTime = 0;
clicking = true;
}
if (clicking && Input.GetMouseButton(0))
{
totalDownTime += Time.deltaTime;
if (totalDownTime >= ClickDuration)
{
clicking = false;
OnLongClick.Invoke();
}
}
if (clicking && Input.GetMouseButtonUp(0))
{
clicking = false;
}
}
public void LongPress()
{
if (GetComponent<SpriteRenderer>().sprite == flagTexture)
{
GetComponent<SpriteRenderer>().sprite = defaulttexture;
}
else if(GetComponent<SpriteRenderer>().sprite == defaulttexture)
GetComponent<SpriteRenderer>().sprite = flagTexture;
}
}
Try using OnMouseDown functions and OnMouseUpAsButton. Your current issue seems that the Input detects of a mouse down anywhere on screen, which causes all scripts to activate, which causes the changes.
void OnMouseDown() {
clicking = true
}
void OnMouseUpAsButton(){
clicking = false
}
void Update() {
if(clicking){
//your time stuff
}
}
You could add a EventTrigger component to the gameobject with the "OnPointerEnter" and "OnPointerExit" events to check if the mouse is on that object (Make OnPointerEnter call a function that sets a boolean to true and OnPointerExit to set that boolean to false).
What you could do is make your script implement interafaces IPointerEnterHandler, IPointerExitHandler found in namespace UnityEngine.EventSystems. Inside onPointerEnter and onPointerExit you could set a value of boolean variable.

how to make an ammo limit decrease from its current value, after it has been increased in C#, Unity?

my character shoots arrows. She starts without zero arrows and cannot shoot any until she picks up an arrow icon. Arrow icons have a value of 3. After this she can shoot arrows. That code works fine. Now I have to make it so these arrows decrease in value through the UI text display. The UI text value changes from 0 to 3 when an arrow icon is picked up, but it doesn't decrease when I shoot an arrow. I have another game object with a script that will detect when an arrow is shot. when this happens, it tells that main script that, "hey, an arrow was just shot." The focus is on getting the Text to decrease when I shoot an arrow.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class arrowManager : MonoBehaviour {
private Text text;
public static int arrowCount;
public static int arrowRecount;
private int maxArrows = 99;
void Start ()
{
text = GetComponent<Text> ();
arrowCount = 0;
}
void Update ()
{
FullQuiver ();
arrowCounter ();
}
void arrowCounter()
{
if (arrowCount < 0) {
arrowCount = 0;
text.text = "" + arrowCount;
}
if (arrowCount > 0)
text.text = "" + arrowCount;
}
public static void AddPoints(int pointsToAdd)
{
arrowCount += pointsToAdd;
}
public static void SubtractPoints(int pointsToSubtract)
{
arrowCount -= pointsToSubtract;
}
public void FullQuiver()
{
if (arrowCount >= maxArrows)
{
arrowCount = maxArrows;
}
}
}
the game object with the script that detects arrows looks like this.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class arrowDetector : MonoBehaviour {
public int pointsToSubtract;
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.tag == "arrow")
{
arrowManager.SubtractPoints (pointsToSubtract);
}
}
}
Forgive me if I've misunderstood, but it looks to me like you are subtracting from the wrong variable.
Since you are displaying the 'arrowCount' variable, I imagine that's what should be subtracted from.
public static void SubtractPoints(int pointsToSubtract)
{
if (arrowCount > 0) {
arrowCount -= pointsToSubtract;//pointsToSubtract is an int value passed to this script from my player script whenever she shoots an arrow.
}
}
In SubtractPoints method you are detracting from the variable "arrowRecount".
Wouldn't you want to be subtracting from "arrowCount" instead? If you used "arrowCount" your text value should update properly.
I figured it out. Before, I was trying to get it to detect my arrows whenever a bool became true from my player script. That wasn't working so I said screw it and just made an empty that detects gameobjects with the tag "arrow." Then I updated the script in here to reflect that. I was dead tired last night after not getting any sleep for two days so I forgot to put in a value of pointsToSubtract in the hierarchy. Thanks everyone for their responses.

hololens 101 chapter 3: what is "=>" for?

Hololense tutorial here
in chapter 3 GazeGestureManager.cs:
using UnityEngine;
using UnityEngine.VR.WSA.Input;
public class GazeGestureManager : MonoBehaviour
{
public static GazeGestureManager Instance { get; private set; }
// Represents the hologram that is currently being gazed at.
public GameObject FocusedObject { get; private set; }
GestureRecognizer recognizer;
// Use this for initialization
void Start()
{
Instance = this;
// Set up a GestureRecognizer to detect Select gestures.
recognizer = new GestureRecognizer();
recognizer.TappedEvent += (source, tapCount, ray) =>
{
// Send an OnSelect message to the focused object and its ancestors.
if (FocusedObject != null)
{
FocusedObject.SendMessageUpwards("OnSelect");
}
};
recognizer.StartCapturingGestures();
}
// Update is called once per frame
void Update()
{
// Figure out which hologram is focused this frame.
GameObject oldFocusObject = FocusedObject;
// Do a raycast into the world based on the user's
// head position and orientation.
var headPosition = Camera.main.transform.position;
var gazeDirection = Camera.main.transform.forward;
RaycastHit hitInfo;
if (Physics.Raycast(headPosition, gazeDirection, out hitInfo))
{
// If the raycast hit a hologram, use that as the focused object.
FocusedObject = hitInfo.collider.gameObject;
}
else
{
// If the raycast did not hit a hologram, clear the focused object.
FocusedObject = null;
}
// If the focused object changed this frame,
// start detecting fresh gestures again.
if (FocusedObject != oldFocusObject)
{
recognizer.CancelGestures();
recognizer.StartCapturingGestures();
}
}
}
I really don't understand this line:
recognizer.TappedEvent += (source, tapCount, ray) =>
What is inside (), why there is a => operator and what is for?
Take a look at C# Lambda operator here. It separates the block from the input variables on the left. So it looks like that the block will be executed on the tapped event and the parameters (source, tapCount, ray) will be passed and can be used in the block.
I like to think of it as a "inlined delegate to handle events or callbacks". Hope that helps :)

Categories

Resources