Я следил за учебным пособием на YouTube (доступно на этом связь), чтобы показать, как перетаскивать элементы в моей игре. Кто-нибудь знает, как я могу адаптировать код, чтобы игра автоматически заканчивалась или меняла сцену, когда все плитки были размещены в доступных слотах? Я также хотел бы знать, есть ли способ запретить пользователю бросать плитку в слот, на котором она уже есть? Это весь исходный код, который у меня уже есть:
Исходный код слотов
public class Slot : MonoBehaviour, IDropHandler {
public GameObject item {
get {
if (transform.childCount>0){
return transform.GetChild (0).gameObject;
}
return null;
}
}
#region IDropHandler implementation
public void OnDrop (PointerEventData eventData)
{
if (!item){
DragHandeler.itemBeingDragged.transform.SetParent (transform);
ExecuteEvents.ExecuteHierarchy<IHasChanged>(gameObject,null,(x,y) => x.HasChanged ());
}
}
Исходный код DragHandler:
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)
{
transform.position = eventData.position;
}
#endregion
#region IEndDragHandler implementation
public void OnEndDrag (PointerEventData eventData)
{
itemBeingDragged = null;
GetComponent<CanvasGroup>().blocksRaycasts = true;
if (transform.parent == startParent){
transform.position = startPosition;
}
}
Я снова много обновил свой ответ после ваших новых вопросов в комментариях ниже. Пожалуйста, проверь это. знак равно
Привет @Ллойд. Итак, как ваши успехи? Не могли бы вы принять ответ, чтобы закрыть вопрос уже? Я уже помог вам с 5 разными вопросами после множества комментариев и редактирования поста. Я надеюсь, что вы все это реализовали и у вас есть хороший прогресс в вашем проекте, и надеюсь, вы понимаете... :)
OMG, мне очень жаль @Dest, что я не ответил тебе! Я совсем забыл! Мои извенения. Все ваши решения сработали! Большое вам спасибо за вашу помощь.





Чтобы изменить сцену, вам нужно использовать это:
SceneManager.LoadScene(scenename);
Вот Документация по LoadScene.
Если вам также нужно помочь вам с логикой, куда ее поместить в вашем проекте - пожалуйста, добавьте свой код и еще какое-то объяснение того, что вы делаете, вместо ссылки на 22 минуты какого-то учебника.
Обновлять:
Вот как вы можете изменить сцену, когда все слоты заполнены:
public void OnDrop (PointerEventData eventData)
{
if (!item)
{
DragHandeler.itemBeingDragged.transform.SetParent (transform);
ExecuteEvents.ExecuteHierarchy<IHasChanged>(gameObject,null,(x,y) => x.HasChanged ());
// This code will check if all slots are full and load new scene if they are
// If you already have an array/list of all your slots, you can replace this "FindObjectsOfType" with it
Slot[] allSlots = FindObjectsOfType<Slot>();
bool areAllBackpackSlotsFull = true;
foreach (Slot slot in allSlots)
{
if (slot.isBackpack == true && slot.item == null)
{
areAllBackpackSlotsFull = false;
break;
}
}
if (areAllBackpackSlotsFull)
{
string nextSceneName = "YourScene"; // Place the name of scene you want to load next
UnityEngine.SceneManagement.SceneManager.LoadScene(nextSceneName);
}
}
}
Вы также спросили:
I'd also like to know if there's any way to restrict the user from dropping a tile onto a slot which has one on it already?
Но я вижу, что это уже реализовано в вашем коде. Существует проверка, является ли текущий элемент нулевым в функции «OnDrop» слота, которая должна делать именно то, что вы хотите - размещать плитку, только если слот пуст. Так что это уже должно быть ограничено. Вы уверены, что это не так?
Обновление 2:
Обновление для вашего нового вопроса о рюкзаке и инвентаре. Вы можете просто добавить переменную bool в класс Slot, чтобы отличать рюкзак от инвентаря:
public class Slot : MonoBehaviour, IDropHandler
{
public bool isBackpack = false;
...
Затем в редакторе отметьте во всех слотах рюкзака переменную «isBackpack» true. Это был бы простой и удобный способ их различать.
Также я обновил приведенный выше код (который проверяет, заполнен ли рюкзак), поэтому теперь он будет проверять только слоты рюкзака.
Обновление 3:
Я заметил, что вы задали еще один вопрос в комментариях:
Would there be a way to lock a tile once it has been dragged from the inventory and dropped to the 'backpack'? i.e. that they can't move it again?
Это явно не связано с исходным постом и вопросом, но ладно, я постараюсь помочь и с этим...
Я думаю, что что-то вроде этого может достичь того, чего вы хотите (я изменил ваш код DragHandler):
public void OnBeginDrag (PointerEventData eventData)
{
Slot currentSlot = gameObject.GetComponentInParent<Slot>();
if (currentSlot.isBackpack == false)
{
itemBeingDragged = gameObject;
startPosition = transform.position;
startParent = transform.parent;
GetComponent<CanvasGroup>().blocksRaycasts = false;
}
else
{
itemBeingDragged = null;
}
}
#endregion
#region IDragHandler implementation
public void OnDrag (PointerEventData eventData)
{
if (itemBeingDragged != null)
transform.position = eventData.position;
}
#endregion
#region IEndDragHandler implementation
public void OnEndDrag (PointerEventData eventData)
{
if (itemBeingDragged != null)
{
itemBeingDragged = null;
GetComponent<CanvasGroup>().blocksRaycasts = true;
if (transform.parent == startParent)
transform.position = startPosition;
}
}
Надеюсь, поможет.
P.S. Я уже помог вам примерно с 5 разными вопросами. Пожалуйста, если у вас есть еще вопросы, не связанные с исходным сообщением - я бы предложил принять ответ, чтобы закрыть эту проблему, и задать другие вопросы в отдельных сообщениях с новым обновленным кодом и информацией (и вы можете добавить ссылку на это пишите в новых постах(вопросы)). Потому что это просто неправильный способ использования этого сайта, задавать новые несвязанные вопросы в комментариях и постоянно обновлять вопрос и ответ, это просто неудобно.
Спасибо за ваш комментарий, я действительно ценю его. Вы правы, извините, что не указали код. Я обновлю свой вопрос своим кодом!
Вова, большое спасибо за помощь! Сейчас я далеко от ПК, но попробую ваш код позже! Странно насчет функции OnDrop. Вы правы, это должно сработать. Есть ли другой способ добиться того же? Я знаю, что много прошу здесь, но могу я спросить еще кое о чем? Есть ли способ заблокировать плитку после того, как ее перетащили из инвентаря и бросили в «рюкзак»? то есть, что они не могут переместить его снова? Я бы хотел, чтобы они взяли плитку из инвентаря и снова поместили ее в инвентарь, то есть чтобы она не была заблокирована, если ее нет в рюкзаке.
О, я вижу, «слоты» есть как в инвентаре, так и в рюкзаке ... В предоставленном вами коде нет способа отличить их (слоты рюкзака от слотов инвентаря). Поэтому мне нужно больше кода/информации от вас, чтобы помочь с этим новым вопросом. Объясните как отличить рюкзак от инвентаря, может есть еще код? или что-то в редакторе?
есть только один код для всех слотов! :/ способ, которым это сделано в учебнике, заключается в том, что вы выбираете все слоты, а затем добавляете компонент, который связывает их все с одним и тем же скриптом слота ..... извините, я должен был уточнить ранее, инвентарь - это место, где пользователь выбирает доступные карты и перетаскивает/бросает их в свой личный рюкзак. Надеюсь, это имело смысл?
Извините, @Dest, я забыл отметить вас в своем предыдущем комментарии. Как вы думаете, мне нужно будет создать код слота для инвентаря и рюкзака? по 1 скрипту? Затем я мог бы связать скрипт инвентаря со слотами инвентаря и тот же принцип для слотов рюкзака? Хотя как мне заставить оба скрипта взаимодействовать? то есть как скрипт инвентаря узнает, когда все слоты рюкзака заняты?
Еще раз привет, @Lloyd. С новой информацией и новым вопросом я снова обновил свой ответ, указав, как вы можете различать свой рюкзак и инвентарь, и обновил предыдущий код, чтобы проверять только слоты рюкзака.
@Lloyd, я заметил еще один вопрос в вашем предыдущем комментарии о блокировке предметов рюкзака. Поэтому я снова обновил свой ответ, указав и это решение. Пожалуйста, проверьте, я надеюсь, что это тоже поможет; и проверьте мой "P.S." прокомментируйте и там пожалуйста :)
Я обновил свой ответ после того, как вы добавили код и описали, что вы хотите. Я думаю, что мое решение должно работать нормально. Пожалуйста, проверьте ниже.