1.i have an issue when i start dragging object its clonning itself, i need that in panel zone(my object respawning in there) not in dropzone im trying to find solution for this can i make clone invisible? if i can how ?here is the code :
enter code here
public class DragHandler : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
public enum Slot { ileri, sağa, sola, fonksiyon };
public Slot typeofMove;
public Transform ParentreturnTo = null;
public Transform PlaceholderParent = null;
GameObject placeholder = null;
public GameObject ileriprefab;
public GameObject x;
public GameObject panel;
public void OnBeginDrag(PointerEventData eventData)
{
placeholder = new GameObject();
placeholder.transform.SetParent(this.transform.parent);
LayoutElement le = placeholder.AddComponent<LayoutElement>();
le.preferredWidth = this.GetComponent<LayoutElement>().preferredWidth;
le.preferredHeight = this.GetComponent<LayoutElement>().preferredHeight;
le.flexibleWidth = 0;
le.flexibleHeight = 0;
placeholder.transform.SetSiblingIndex(this.transform.GetSiblingIndex());
//sibling index kartı aldıgımız yeri döndürür.
Debug.Log("OnBeginDrag");
ParentreturnTo = this.transform.parent;
PlaceholderParent = ParentreturnTo;
this.transform.SetParent(this.transform.parent.parent);
if (this.transform.parent.position == GameObject.FindGameObjectWithTag("carddroparea").transform.position)
{
x = Instantiate(moveforwardprefab, moveforvardprefab.transform.position, Quaternion.identity);
x.transform.SetParent(PlaceholderParent.transform);
//im trying to saying here if the object "this" in drop zone dont instantiate it or make it invisible ??????? but its not working
}
GetComponent<CanvasGroup>().blocksRaycasts = false;
}
public void OnDrag(PointerEventData eventData)
{
Debug.Log("OnDrag");
this.transform.position = eventData.position;
if (placeholder.transform.parent != PlaceholderParent)
placeholder.transform.SetParent(PlaceholderParent);
int newSiblingIndex = PlaceholderParent.childCount;
for (int i = 0; i < PlaceholderParent.childCount; i++)
{
//**parentreturnto. getchild(i)**//
if (this.transform.position.x < PlaceholderParent.GetChild(i).position.x)
{
newSiblingIndex = i;
// placeholder.transform.SetSiblingIndex(i);
if (PlaceholderParent.transform.GetSiblingIndex() < newSiblingIndex)
newSiblingIndex--;
break;
}
}
placeholder.transform.SetSiblingIndex(newSiblingIndex);
}
public void OnEndDrag(PointerEventData eventData)
{
Debug.Log("OnEndDrag");
this.transform.SetParent(ParentreturnTo);
this.transform.SetSiblingIndex(placeholder.transform.GetSiblingIndex());
//Kartın alındıgı yere konulması için gerekli
GetComponent<CanvasGroup>().blocksRaycasts = true;
Destroy(placeholder);
if (this.transform.parent.position == GameObject.FindGameObjectWithTag("panel").transform.position)
{
Destroy(x);
Debug.Log("destroyed");
}
if (x.transform.parent.position == GameObject.FindGameObjectWithTag("carddroparea").transform.position)
{
Destroy(x);
Debug.Log("destroyed");
}
}
}
If you just want to make a GameObject invisible there are many ways to do it.
You can, for example:
yourGameObject.SetActive(false);
You can also deactivate your gameobject Renderer
yourGameObject.GetComponent<Renderer>().enabled = false;
how to adapt it to your code is up to you.
Related
I'm really just a beginner and trying to learn game development, but i can't seem to figure out the logic behind this.. if the inventory has already an item inside and if the current object can't be stacked on top of it, then swap out the 2 object
the script i'm trying to implement it:
public void OnDrop(PointerEventData eventData)
{
//on drop if the inventory slot doesn't have child object then we know it's a free slot, so we can drag there the grabbed item.
if(transform.childCount == 0)
{
GameObject dropped = eventData.pointerDrag;
InventoryItem inventoryItem = dropped.GetComponent<InventoryItem>();
inventoryItem.parentAfterDrag = transform;
}
else
{
//on drop if the inventory has already an item inside and if the current object can't be stacked on top of it, then swap out the 2 object
//but how do i know what is the object that is inside this slot?
}
}
}
here is the InventoryManager script:
public class InventoryManager : MonoBehaviour
{
public int maxStackedItems = 4;
int selectedSlot = -1;
public InventorySlot[] inventorySlots;
public GameObject inventoryItemPrefab;
public GameObject mainInventory;
public bool isMainInventoryOpened;
public bool AddItem(Item item)
{
//checks if there is any slot with the same kind of item as this, which isnt in max stack
for (int i = 0; i < inventorySlots.Length; i++)
{
InventorySlot slot = inventorySlots[i];
InventoryItem itemInSlot = slot.GetComponentInChildren<InventoryItem>();
if (itemInSlot != null && itemInSlot.item == item && itemInSlot.count < maxStackedItems && itemInSlot.item.stackable == true)
{
itemInSlot.count++;
itemInSlot.RefreshCount();
return true;
}
}
//looks for an empty slot
for (int i = 0; i < inventorySlots.Length; i++)
{
InventorySlot slot = inventorySlots[i];
InventoryItem itemInSlot = slot.GetComponentInChildren<InventoryItem>();
if(itemInSlot == null)
{
SpawnNewItem(item, slot);
return true;
}
}
return false;
}
void SpawnNewItem(Item item, InventorySlot slot)
{
GameObject newItemGo = Instantiate(inventoryItemPrefab, slot.transform);
InventoryItem inventoryItem = newItemGo.GetComponent<InventoryItem>();
inventoryItem.InitializeItem(item);
}
public Item GetSelectedItem(bool use)
{
InventorySlot slot = inventorySlots[selectedSlot];
InventoryItem itemInSlot = slot.GetComponentInChildren<InventoryItem>();
if (itemInSlot != null)
{
Item item = itemInSlot.item;
if(use == true)
{
itemInSlot.count--;
if(itemInSlot.count <= 0)
{
Destroy(itemInSlot.gameObject);
}
else
{
itemInSlot.RefreshCount();
}
}
return item;
}
return null;
}
}
and the InventoryItem script:
public class InventoryItem : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
[HideInInspector] public Transform parentAfterDrag;
[HideInInspector] public Item item;
[HideInInspector] public int count = 1;
public Image image;
public TMP_Text countText;
public void InitializeItem (Item newItem)
{
item = newItem;
image.sprite = newItem.image;
RefreshCount();
}
public void RefreshCount()
{
countText.text = count.ToString();
bool textActive = count > 1;
countText.gameObject.SetActive(textActive);
}
public void OnBeginDrag(PointerEventData eventData)
{
parentAfterDrag = transform.parent;
transform.SetParent(transform.root);
transform.SetAsLastSibling();
image.raycastTarget = false;
}
public void OnDrag(PointerEventData eventData)
{
transform.position = Input.mousePosition;
}
public void OnEndDrag(PointerEventData eventData)
{
transform.SetParent(parentAfterDrag);
image.raycastTarget = true;
}
}
i've tried to figure out what is the item on that occupied slot but i don't seem to understand this logic yet.
I build a brand new cards game every thing is work with out any errors ,
But wen i start to drag my object in this case is a card in to the drop zone my card is not visible for some reason , i am not sure but i thing they out of screen range or some thing like that i can not find the way to correct this , i try to debug but there is no error on it so i am not able to find the way to solve this.
This is my code for the draggable object
using UnityEngine.UI;
using System.Collections;
using UnityEngine.EventSystems;
public class Draggable : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler {
public Transform parentToReturnTo = null;
public Transform placeholderParent = null;
GameObject placeholder = null;
public void OnBeginDrag(PointerEventData eventData) {
Debug.Log ("OnBeginDrag");
placeholder = new GameObject();
placeholder.transform.SetParent( this.transform.parent );
LayoutElement le = placeholder.AddComponent<LayoutElement>();
le.preferredWidth = this.GetComponent<LayoutElement>().preferredWidth;
le.preferredHeight = this.GetComponent<LayoutElement>().preferredHeight;
le.flexibleWidth = 0;
le.flexibleHeight = 0;
placeholder.transform.SetSiblingIndex( this.transform.GetSiblingIndex() );
parentToReturnTo = this.transform.parent;
placeholderParent = parentToReturnTo;
this.transform.SetParent( this.transform.parent.parent );
GetComponent<CanvasGroup>().blocksRaycasts = false;
}
public void OnDrag(PointerEventData eventData) {
//Debug.Log ("OnDrag");
this.transform.position = eventData.position;
if(placeholder.transform.parent != placeholderParent)
placeholder.transform.SetParent(placeholderParent);
int newSiblingIndex = placeholderParent.childCount;
for(int i=0; i < placeholderParent.childCount; i++) {
if(this.transform.position.x < placeholderParent.GetChild(i).position.x) {
newSiblingIndex = i;
if(placeholder.transform.GetSiblingIndex() < newSiblingIndex)
newSiblingIndex--;
break;
}
}
placeholder.transform.SetSiblingIndex(newSiblingIndex);
}
public void OnEndDrag(PointerEventData eventData) {
Debug.Log ("OnEndDrag");
this.transform.SetParent( parentToReturnTo );
this.transform.SetSiblingIndex( placeholder.transform.GetSiblingIndex() );
GetComponent<CanvasGroup>().blocksRaycasts = true;
Destroy(placeholder);
}
}
so I have like 5 game object in my scene but I only scale each of them separately. However when I try to do that all of them start scaling simultaneously. Also, I have a placement indicator that would be used to instantiate the object on the plane. It seems that instead of the object itself, the placement indicator is the one that gets scaled. How should I fix that?
I have tried deactivating the placement indicator but did not work.
Here is the code for instantiating objects:
I limited the obj number to 5.
I use this script instead of the usual "PlaceonPlane" script.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.Experimental.XR;
using UnityEngine.UI;
using UnityEngine.XR.ARSubsystems;
public class ARTaptoPlaceObject : MonoBehaviour
{
private ARSessionOrigin arOrigin;
GameObject spawnedobj;
public GameObject placementIndicator;
private ARRaycastManager arRaycast;
public Pose placementPose;
public UIContoller sc;
public bool placementPoseIsValid = false;
private int count;
private string valu;
string prefabs;
void Start()
{
arOrigin = FindObjectOfType<ARSessionOrigin>();
arRaycast = FindObjectOfType<ARRaycastManager>();
count = 0;
}
// Update is called once per frame
void Update()
{
UpdatePlacementPose();
UpdatePlacementIndicator();
for (var i = 0; i < Input.touchCount; ++i)
{
if (Input.GetTouch(i).phase == TouchPhase.Began)
{
if (placementPoseIsValid && Input.GetTouch(i).tapCount == 2)
{
PlaceObject();
}
}
}
}
public void PlaceObject()
{
if (count <= 4)
{
if (sc.objectToPlace != null)
{
spawnedobj = Instantiate(sc.objectToPlace, placementPose.position, placementPose.rotation);
arOrigin.MakeContentAppearAt(spawnedobj.transform, spawnedobj.transform.position, spawnedobj.transform.rotation);
count++;
}
}
else
{
placementIndicator.SetActive(false);
}
}
private void UpdatePlacementIndicator()
{
if (placementPoseIsValid && count <= 4 && sc.active == false)
{
placementIndicator.SetActive(true);
placementIndicator.transform.SetPositionAndRotation(placementPose.position, placementPose.rotation);
}
else
{
placementIndicator.SetActive(false);
}
}
private void UpdatePlacementPose()
{
var screenCenter = Camera.current.ViewportToScreenPoint(new Vector3(0.5f, 0.5f));
var hits = new List<ARRaycastHit>();
arRaycast.Raycast(screenCenter, hits, UnityEngine.XR.ARSubsystems.TrackableType.Planes);
placementPoseIsValid = hits.Count > 0;
if (placementPoseIsValid)
{
placementPose = hits[0].pose;
var cameraForward = Camera.current.transform.forward;
var cameraBearing = new Vector3(cameraForward.x, 0, cameraForward.z).normalized;
placementPose.rotation = Quaternion.LookRotation(cameraBearing);
}
}
}
and here is the Scaler script that's attached to the button that would scale the object.
public class Scaler : MonoBehaviour
{
public UIContoller uc;
public ARTaptoPlaceObject ap;
private GameObject ReferenceToScale;
public void OnValueChange()
{
ReferenceToScale = (UnityEngine.GameObject)Resources.Load(uc.s_count, typeof(GameObject));
Vector3 t = ReferenceToScale.transform.localScale;
Vector3 scaleValue = t * 1.1f;
ReferenceToScale.transform.localScale = scaleValue;
}
Also the "objectToPlace" itself is in the "UI.Controller" script as I could not view it in the scene when it was in the "ARTaptoPlace" script
I have been working on a minecraft clone game in Unity 2017.3 and C# and i started all right but when i worked on the super flat world generation system there began a problem. Inside the World mono behaviour, in the Generate void, there are three nested for loops which should generate a new dirt block on every possible position between 0 and 5
But it only makes a line of dirt block stretching along the Z axis.
Here is the code for PlaceableItem(attached to dirtPrefab) and World(attached to World)
Placeable Item class
using UnityEngine;
using System.Collections;
public class PlaceableItem : MonoBehaviour
{
public string nameInInventory = "Unnamed Block";
public int maxStack = 64;
public bool destructible = true;
public bool explodesOnX = false;
public bool abidesGravity = false;
public bool isContainer = false;
public bool canBeSleptOn = false;
public bool dropsSelf = false;
private Rigidbody rb;
// Use this for initialization
void Start()
{
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
if (abidesGravity) {
rb.useGravity = true;
} else {
rb.useGravity = false;
}
}
private void OnDestroy()
{
if (dropsSelf) {
//Drop this gameObject
}
}
public void Explode() {
if (!explodesOnX)
return;
}
public void OnMouseDown()
{
if (isContainer && !canBeSleptOn) {
//Open the container inventory
} else if (canBeSleptOn && !isContainer) {
//Make the character sleep on the item
}
}
private void OnMouseOver()
{
if (Input.GetMouseButtonDown(1) && destructible) {
Destroy(gameObject);
}
}
}
World class
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class World : MonoBehaviour {
public GameObject dirtPrefab;
public bool generateAutomatically = true;
// Use this for initialization
void Start () {
if (generateAutomatically) {
Generate();
}
}
// Update is called once per frame
void Update () {
}
void Generate() {
for (int x = 0; x <= 5; x++) {
for (int y = 0; y <= 5; y++) {
for (int z = 0; z <= 5; z++) {
Instantiate(dirtPrefab, new Vector3(x, y, z), Quaternion.identity);
}
}
}
}
void RemoveAllBlocks() {
foreach (PlaceableItem placeableItem in GetComponentsInChildren<PlaceableItem>()) {
Destroy(placeableItem.gameObject);
}
}
}
Thanks in advance, fellow developers!
Hope this is not a stupid question!
[SOLVED] I realised i had a recttransform somehow attached to my dirt prefab. Removing it and adding a transform instead helped.
It may sound stupid but how can i reference a class from one script in child in another script in parent? I cant find anything on google. Note: There are couple errors in my script, that's not the point of the post.
//Public
//Private
private Rigidbody myRigidbody;
private Renderer myRenderer;
private Material tileDefaultMaterial;
private Material tileSelectedMaterial;
private Material tileSameGroupMaterial;
void Start () {
myRigidbody = GetComponent<Rigidbody> ();
myRenderer = GetComponent<Renderer> ();
tileDefaultMaterial = Resources.Load ("TileDefault", typeof(Material)) as Material;
tileSelectedMaterial = Resources.Load ("TileSelected", typeof(Material)) as Material;
tileSameGroupMaterial = Resources.Load ("TileSameGroup", typeof(Material)) as Material;
}
void Update () {
}
public class TileClass {
public int tileGroup = 0; //Indicates the Tile Group Number.
}
//Public
public GameObject[] allTiles; //Aray of all Tile GameObject.
public bool tileIsSelected = false; //If a Tile is Selected.
public int selectedTileGroup = 0; //Indicates the Selected Tile Group Number.
public int tileGroup = 0; //Indicates the Tile Group Number.
//Private
void Start () {
allTiles = new GameObject[transform.childCount];
for(int i = 0; i < transform.childCount; i++){
allTiles [i] = transform.GetChild (i).gameObject;
}
}
void Update () {
}
void OnMouseDown (){
RaycastHit hitInfo = new RaycastHit ();
bool hit = Physics.Raycast (Camera.main.ScreenPointToRay (Input.mousePosition), out hitInfo);
if (hitInfo.transform.gameObject.tag == "Tile" && tileIsSelected == false) {
Debug.Log ("A Tile is Selected!");
tileIsSelected = true;
selectedTileGroup = ;
for(int i = 0; i < allTiles.Length; i++){
if (this.tileGroup == selectedTileGroup) {
allTiles [i].GetComponent<Renderer> ().material = tileSameGroupMaterial;
}
}
myRenderer.material = tileSelectedMaterial;
} else if (hitInfo.transform.gameObject.tag == "Tile" && tileIsSelected == true) {
Debug.Log ("Second Tile is Clicked! (Should Swap them!)");
myRenderer.material = tileDefaultMaterial;
}
}
There is a famous saying :
var allTiles = transform.GetComponentsInChildren<Tile>();
And as I told you yesterday, Add OnMouseDown() in Tile.cs and write myRenderer.material = tileDefaultMaterial; there. No need to write this in TileManager.cs. And NO need to use Raycast when using OnMouseDown().
I can't read your image code, so I'll make up my own class names for the example. I'll call the parent class TileManager and the child class Tile.
Say in Tile you want access to the array of tiles in the TileManager. If allTiles is declared as public, you'd do in Tile somewhere.
TileManager tileManager = transform.parent.GetComponent<TileManager>();
var allTiles = tileManager.allTiles;
Now the Tile child has a reference to the array. Was this what you were wanting?
how about base.Method?
That should do it