How to compare name of a GameObject in Unity - c#

So I'm making simple game to put the right answer in the right slot. which is when you put the right sticker on the slot you got score.
for the example if you put the sticker "a" to the slot "b" then you got point. and then the sticker "a", the sticker become child of slot "b".
the problem is when i uses the name of the gameobject it doesnt work, i tried using debug.log to show the score but it doesnt work. this script is component of the slot. the draghandler is from another script the script is component of the sticker.
Here is the code
public void OnDrop (PointerEventData eventData)
{
if (!item) {
DragHandler.itemBeingDragged.transform.SetParent (transform);
if (DragHandler.itemBeingDragged.gameObject.name == "b" && DragHandler.itemBeingDragged.transform.parent.name == "slot2") {
score = score + 25;
nilai = score.ToString();
Debug.Log ("score: "+nilai);
}}}
but when i used this code to show the name of slot and the sticker it's work
public void OnDrop (PointerEventData eventData)
{
if (!item) {
DragHandler.itemBeingDragged.transform.SetParent (transform);
Debug.Log ("slot: "+DragHandler.itemBeingDragged.transform.parent.name + "item : "+DragHandler.itemBeingDragged.gameObject.name);
}
}
this is the code for draghandler
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
public class DragHandler : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler {
public static GameObject itemBeingDragged;
Vector3 startPosition;
Transform startParent;
#region IBeginDragHandler implementation
public void OnBeginDrag (PointerEventData eventData)
{
itemBeingDragged = gameObject;
startPosition = transform.position;
startParent = transform.parent;
GetComponent<CanvasGroup> ().blocksRaycasts = false;
}
#endregion
#region IDragHandler implementation
public void OnDrag (PointerEventData eventData)
{
startPosition = Input.mousePosition;
//Debug.Log ("namanya : " + itemBeingDragged.name);
}
#endregion
#region IEndDragHandler implementation
public void OnEndDrag (PointerEventData eventData)
{
itemBeingDragged = null;
GetComponent<CanvasGroup> ().blocksRaycasts = true;
if (transform.parent == startParent) {
transform.position = startPosition;
}
}
#endregion
}
If there's something missing with my explanation let me know.
Thank you.

I can't see the code for the drag handler but does it drop the item after you release it? If so it may not have the item that WAS being dragged. So maybe when you check the DragHandler.itemBeingDragged it may return null.

Related

Unity - character starts to fly up when there should be gravity

I am developing a 2D platform game, where the character is a ball and should be able to move right and left, and to jump. It now does all that, but for some reason which i do not understand (as i am complitely new to Unity) sometimes it flies up like if the gravity was negative.
Here is the code of my first script Move2D:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move2D : MonoBehaviour
{
public float moveSpeed = 5f;
public bool isGrounded = false;
[SerializeField] private Rigidbody2D rigidbody;
private Vector2 currentMoveDirection;
private void Awake()
{
rigidbody = GetComponent<Rigidbody2D>();
currentMoveDirection = Vector2.zero;
}
public void Jump()
{
if (isGrounded)
{
rigidbody.AddForce(new Vector3(0f, 5f), ForceMode2D.Impulse);
}
}
private void FixedUpdate()
{
rigidbody.velocity = (currentMoveDirection + new Vector2(0f, rigidbody.velocity.y)).normalized * moveSpeed;
}
public void TriggerMoveLeft()
{
currentMoveDirection += Vector2.left;
}
public void StopMoveLeft()
{
currentMoveDirection -= Vector2.left;
}
public void TriggerMoveRight()
{
currentMoveDirection += Vector2.right;
}
public void StopMoveRight()
{
currentMoveDirection -= Vector2.right;
}
}
And this is the code of the second script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class ContinuesButton : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
[SerializeField] private Button targetButton;
[SerializeField] private Move2D playerMovement;
[SerializeField] private bool movesLeft;
private readonly bool isHover;
private void Awake()
{
if (!targetButton) targetButton = GetComponent<Button>();
}
public void OnPointerDown(PointerEventData eventData)
{
if (movesLeft)
{
playerMovement.TriggerMoveLeft();
} else
{
playerMovement.TriggerMoveRight();
}
}
public void OnPointerUp(PointerEventData eventData)
{
if (movesLeft)
{
playerMovement.StopMoveLeft();
} else
{
playerMovement.StopMoveRight();
}
}
}
I noticed that the ball starts to fly up as soon as the movement controller or some collider makes it go up a bit. For example when i make it jump, it just keeps going up, or when in the game i try to make it "walk" up a hill, it immediately starts flying up.
Any help or information is really appreciated, I really do not see the problem.
The issue I lies in normalized. This might unexpectedly increase the Y velocity. Especially in cases when you set the X velocity to 0 the Y component is taken into account to much.
I guess you should rather use something like
currentDirection * moveSpeed + Vector2.up * rigidbody.velocity.y;
In order to simply keep the current Y velocity.
Also be careful with these currentDirection += ...! I would suggest rather use single methods and use fixed values like e.g.
public void DoMove(bool right)
{
currentDirection = (right ? 1 : -1) * Vector2.right;
}
public void StopMove()
{
currentDirection = Vector2.zero;
}
And then rather call them like
public void OnPointerDown(PointerEventData eventData)
{
playerMovement.DoMove(!movesLeft);
}
public void OnPointerUp(PointerEventData eventData)
{
playerMovement.StopMove();
}

unity - android touch button with name fire1 not working

i need help to fix the following code to be able fire when bullet when touch the fire 1 button its not working when i use unity remote on my mobile
steps
Assined the PlayerShoot script to GameObject
click on the button in the scene, go to the inspector. and add an OnClick event, drag the gameobject that has the script on it, and select the Fire() function.
using the unity remote app on mobile where the fire button not working
the code i use ...as the following :
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PlayerShoot : MonoBehaviour {
public GameObject Ammo; // the shot
GameObject FiredShot;
public AudioClip bcgMusic;
public List<GameObject> ShotsOnAir;
//public AudioClip sound1; // Use this for initialization
void Start (){
ShotsOnAir = new List<GameObject>();
}
//void Update (){
// Fire ();
//}
public void Fire(){
if (Input.GetButtonDown ("Fire1")){
FiredShot = (GameObject)Instantiate(Ammo,transform.position,transform.rotation);
ShotsOnAir.Add(FiredShot);
AudioSource.PlayClipAtPoint (bcgMusic, transform.position);
}
if(ShotsOnAir != null){
int i=0;
foreach (GameObject GB in ShotsOnAir){
ShotsOnAir[i].transform.position += ShotsOnAir[i].transform.forward * 200 * Time.deltaTime;
i++;
}
}
}
}
Input.GetButton() does not work on mobile
You need to use Input.touches/Input.GetTouch() instead
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PlayerShoot : MonoBehaviour {
public GameObject Ammo; // the shot
public GameObject FiredShot;
public AudioClip bcgMusic;
public List<GameObject> ShotsOnAir;
//public AudioClip sound1; // Use this for initialization
void Start (){
ShotsOnAir = new List<GameObject>();
}
//void Update (){
// Fire ();
//}
public void Fire(){
//if (Input.touches ("Fire1")){
if (Input.touchCount > 0 ){
FiredShot = (GameObject)Instantiate(Ammo,transform.position,transform.rotation);
ShotsOnAir.Add(FiredShot);
AudioSource.PlayClipAtPoint (bcgMusic, transform.position);
}
if(ShotsOnAir != null){
int i=0;
foreach (GameObject GB in ShotsOnAir){
ShotsOnAir[i].transform.position += ShotsOnAir[i].transform.forward * 10000 * Time.deltaTime;
i++;
}
}
}
}

Game Object does not retain its original position when left in space on drag n drop in unity

There is a game Object "Heat" in Unity 2D. I am trying to drag and drop game object on another game object Sun using UI(works for unity version greater than 4.6). Drag works right but when I drop the object in space other than Sun, heat object does not retain its original position. I tried to make it work using colliders and raycasting but it does not seem to work. Here is the code:
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
public class Drag : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler {
public static GameObject itemBeingDragged;
public static Vector2 startPos;
void Start () {
}
#region IBeginDragHandler implementation
public void OnBeginDrag (PointerEventData eventData)
{
itemBeingDragged = gameObject;
startPos = transform.position;
}
#endregion
#region IDragHandler implementation
public void OnDrag (PointerEventData eventData)
{
transform.position = eventData.position;
}
#endregion
#region IEndDragHandler implementation
public void OnEndDrag (PointerEventData eventData)
{
//if itemBeingDragged is in Space then move it to its original position and then assign null
//itemBeingDragged = null;
RaycastHit2D hit = Physics2D.Raycast (Camera.main.ScreenToWorldPoint (Input.mousePosition), Vector2.zero);
if (hit.collider != null)
{
print ("Inside hit.collider" + hit.collider.name);
//Itembeing Dragged ... set it to startPos if released in space
if (hit.collider.gameObject.name == "Heat")
{
LeanTween.move (hit.collider.gameObject,PublicVariables.startPosHeat, 1.5f);
}
}
}
#endregion
}
Any help is much appreciated. Thanks.

Buttons in Unity, without using UI?

Is there a way in Unity to create a simple 2D button without using the UI layer. I have a game with a lot of buttons and I don't want to make the whole app in the UI. Some more controls are welcome too: switches, sliders etc.
PS. I saw NGUI and I don't like it so far. Anything else?
Is there a way in Unity to create a simple 2D button without using the
UI layer
You can use Sprite/Sprite Render as a Button.First Create a GameObject and attach EventSystem and StandaloneInputModule to it. Attach Physics2DRaycaster to the Camera, implement IPointerClickHandler and override OnPointerClick function. Create a 2D Sprite by going to GameObject->2D Object->Sprite then attach your script to the Sprite. Here is a complete code to do that:
using UnityEngine;
using UnityEngine.EventSystems;
using System.Collections;
public class SPRITEBUTTON: MonoBehaviour, IPointerClickHandler,
IPointerDownHandler, IPointerEnterHandler,
IPointerUpHandler, IPointerExitHandler
{
void Start()
{
//Attach Physics2DRaycaster to the Camera
Camera.main.gameObject.AddComponent<Physics2DRaycaster>();
addEventSystem();
}
public void OnPointerClick(PointerEventData eventData)
{
Debug.Log("Mouse Clicked!");
}
public void OnPointerDown(PointerEventData eventData)
{
Debug.Log("Mouse Down!");
}
public void OnPointerEnter(PointerEventData eventData)
{
Debug.Log("Mouse Enter!");
}
public void OnPointerUp(PointerEventData eventData)
{
Debug.Log("Mouse Up!");
}
public void OnPointerExit(PointerEventData eventData)
{
Debug.Log("Mouse Exit!");
}
//Add Event System to the Camera
void addEventSystem()
{
GameObject eventSystem = null;
GameObject tempObj = GameObject.Find("EventSystem");
if (tempObj == null)
{
eventSystem = new GameObject("EventSystem");
eventSystem.AddComponent<EventSystem>();
eventSystem.AddComponent<StandaloneInputModule>();
}
else
{
if ((tempObj.GetComponent<EventSystem>()) == null)
{
tempObj.AddComponent<EventSystem>();
}
if ((tempObj.GetComponent<StandaloneInputModule>()) == null)
{
tempObj.AddComponent<StandaloneInputModule>();
}
}
}
}
EDIT:
If this is a 3D GameObject/Mesh, then you need to add a simple collider to it. If it is just Sprite then you must add a 2D collider to the sprite.
Another approach that is even simpler, is to just add a BoxCollider2D component, then add the following methods to the a new componenent, say UIButton, where you will to perform the button actions :
void OnMouseOver()
void OnMouseDown()
void OnMouseUp()
This avoids the use of an EventSystem, StandaloneInputModule and Physics2DRaycaster.
Example :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class UIButton : MonoBehaviour {
public Sprite regular;
public Sprite mouseOver;
public Sprite mouseClicked;
public TextMeshPro buttonText;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
private void OnMouseDown()
{
}
private void OnMouseEnter()
{
}
private void OnMouseExit()
{
}
private void OnMouseUpAsButton()
{
}
}
Tested in unity 2018.1. One difference I initially noticed to this and the above approach is that the right mouse button click is not detected in this model, but is detected in the EventSystemModel.

Creating a drag and drop system with a trash can to remove object

I'm having trouble creating a a script the allows for a gameobject to be dropped onto a trash area of the screen thereby destroying the gameobject. Where am I going wrong in the onDrop function? Basically I'm trying to say that when a GameObject gets dropped onto the trash can it becomes a child of the trash can and once it's a child it gets destroyed. Does this logic make sense?
using System.Collections;
using UnityEngine.EventSystems;
namespace MyNamespace
{
public class DropZone : MonoBehaviour, IDropHandler, IPointerEnterHandler, IPointerExitHandler
{
public void OnPointerEnter(PointerEventData eventData)
{
if(eventData.pointerDrag == null)
return;
DragHandling dragHandling = eventData.pointerDrag.GetComponent<DragHandling>();
if(dragHandling != null)
{
dragHandling.placeholderParent = this.transform; // change parent based on drop zone
}
}
public void OnPointerExit(PointerEventData eventData)
{
if(eventData.pointerDrag == null)
return;
DragHandling dragHandling = eventData.pointerDrag.GetComponent<DragHandling>();
if(dragHandling != null && dragHandling.placeholderParent == this.transform)
{
dragHandling.placeholderParent = dragHandling.parentToReturnTo; // change parent based on drop zone
}
}
public void OnDrop(PointerEventData eventData)
{
Debug.Log(eventData.pointerDrag.name + " was dropped on " + gameObject.name);
DragHandling dragHandling = eventData.pointerDrag.GetComponent<DragHandling>();
if(dragHandling != null)
{
dragHandling.parentToReturnTo = this.transform; // change parent based on drop zone
}
if (this.transform.parent.gameObject == dragHandling.trashCan)
{
Destroy(this);
}
}
}
and this is the script I'm referencing to get my variables:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.EventSystems;
using System.Collections.Generic;
public class DragHandling : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IPointerClickHandler
{
public Transform placeholderParent = null;
public Transform parentToReturnTo = null;
GameObject placeholder = null;
public GameObject trashCan;
public Transform trashCanTrans;
public GameObject partsPanel;
public Transform partsPanelTrans;
public GameObject buildBoard;
public GameObject dragLayer;
void Awake ()
{
dragLayer = GameObject.FindGameObjectWithTag("DragLayer");
buildBoard = GameObject.FindGameObjectWithTag("Board");
partsPanel = GameObject.FindGameObjectWithTag("Parts");
trashCan = GameObject.FindGameObjectWithTag("Trash");
partsPanelTrans = partsPanel.transform;
// trashCanTrans = trashCan.transform;
}
#region IPointerClickHandler implementation
public void OnPointerClick (PointerEventData eventData)
{
if(this.transform.parent.gameObject == buildBoard)
{
this.transform.SetAsLastSibling();
}
}
#endregion
#region IBeginDragHandler implementation
public void OnBeginDrag (PointerEventData eventData)
{
// this.transform.SetAsLastSibling();
// create placeholder gap and hold correct position in layout
placeholder = new GameObject();
placeholder.transform.SetParent(this.transform.parent);
placeholder.transform.SetSiblingIndex(this.transform.GetSiblingIndex());
LayoutElement le = placeholder.AddComponent<LayoutElement>(); // add layout element
le.preferredWidth = this.GetComponent<LayoutElement>().preferredWidth;
le.preferredHeight = this.GetComponent<LayoutElement>().preferredHeight;
le.flexibleWidth = 0;
le.flexibleHeight = 0;
parentToReturnTo = this.transform.parent; // store current parent location
placeholderParent = parentToReturnTo; // set placeholder gameobject transform
GetComponent<CanvasGroup>().blocksRaycasts = false; // turn off image raycasting when dragging image in order to see what's behind the image
}
#endregion
#region IDragHandler implementation
public void OnDrag (PointerEventData eventData)
{
this.transform.position = eventData.position; // set object coordinates to mouse coordinates
this.transform.SetParent(dragLayer.transform); // pop object to draglayer to move between dropzones
}
#endregion
#region IEndDragHandler implementation
public void OnEndDrag (PointerEventData eventData)
{
this.transform.SetParent(parentToReturnTo); // Snaps object back to orginal parent if dropped outside of a dropzone
this.transform.SetSiblingIndex(placeholder.transform.GetSiblingIndex()); // Returns card back to placeholder location
GetComponent<CanvasGroup>().blocksRaycasts = true; // turn on Raycast blocking
Destroy(placeholder); // kill the placeholder if object hits a drop zone or returns to parts panel
}
#endregion
}
Okay, so I made a few changes and now when I drag the gameobject onto the trashcan it gets destroyed but so does the trashcan. I've been trying to get it to work, but still no luck. Here's what I have now, but it's still not working correctly.
public void OnDrop(PointerEventData eventData)
{
Debug.Log(eventData.pointerDrag.name + " was dropped on " + gameObject.name);
DragHandling dragHandling = eventData.pointerDrag.GetComponent<DragHandling>();
if(dragHandling != null)
{
dragHandling.parentToReturnTo = this.transform; // change parent based on drop zone
if (this.transform.gameObject == dragHandling.trashCan)
{
Debug.Log("You've dragged something into the trash!");
Destroy(this.transform.gameObject);
}
}
}
Honnestly i don't think you should put "this" into the destroy function, see one asking the question directly : http://answers.unity3d.com/questions/19223/is-destroygameobject-the-same-as-destroythis.html
You'r trying to destroy the drop zone instead of destroying the gameObject. Destroy only the gameObject and everything should be ok.
If the trash can destroy itself along with the game object, do not make that object be a child of the trash can. What probably happens here is that destroy() function wants to also destroy the parents of the object in order to maintain coherence in the datas.

Categories