I have been making a game on Unity following the tutorial by Sykoo, this one.
And I have a problem with the crafting system, when I want the items to be destroyed when the craft is made, but I dont know how to do it. Can someone help me please?
here is the craft item script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class CraftableItem : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
public GameObject thisItem;
public int requiredItems;
public GameObject[] item;
private bool hovered;
private GameObject player;
private GameObject itemManager;
public void Start()
{
player = GameObject.FindWithTag("Player");
itemManager = GameObject.FindWithTag("ItemManager");
}
public void Update()
{
if (hovered == true)
{
if(Input.GetMouseButtonDown(0))
{
CheckForRequiredItems();
}
}
}
public void CheckForRequiredItems()
{
int itemsInManager = itemManager.transform.childCount;
if (itemsInManager > 0)
{
int itemsFound = 0;
for(int i = 0; i < itemsInManager; i++)
{
for (int z = 0; z < requiredItems; z++)
{
if (itemManager.transform.GetChild(i).GetComponent<Item>().type == item[z].GetComponent<Item>().type)
{
itemsFound++;
break;
}
}
}
if (itemsFound >= requiredItems)
{
GameObject spawndedItem = Instantiate(thisItem, /* pos,*/player.transform.position, Quaternion.identity);
}
}
}
public void OnPointerEnter(PointerEventData eventData)
{
hovered = true;
}
public void OnPointerExit(PointerEventData eventData)
{
hovered = false;
}
}
the inventory script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Inventory : MonoBehaviour
{
//Instructions *correct
public GameObject inventory;
public GameObject slotHolder;
public GameObject itemManager;
private bool inventoryEnabled;
private int slots;
private Transform[] slot;
private GameObject itemPickedUp;
private bool itemAdded;
private GameObject player;
//Start *correct
public void Start()
{
// slots being detected
inventoryEnabled = true;
slots = slotHolder.transform.childCount;
slot = new Transform[slots];
DetectInventorySlots();
}
// Inventory GUI
public void Update()
{
if (Input.GetKeyDown(KeyCode.I))
{
inventoryEnabled = !inventoryEnabled;
}
if(inventoryEnabled)
{
inventory.GetComponent<Canvas>().enabled = true;
Time.timeScale = 0;
Cursor.visible = true;
Cursor.lockState = CursorLockMode.None;
}
else
{
inventory.GetComponent<Canvas>().enabled = false;
Time.timeScale = 1;
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
}
}
// Inventory Pick *correct
public void OnTriggerStay(Collider other)
{
if (other.tag == "Item")
{
itemPickedUp = other.gameObject;
AddItem(itemPickedUp);
}
}
public void OnTriggerExit(Collider other)
{
if (other.tag == "Item")
{
itemAdded = false;
}
}
// Add Item *correct
public void AddItem(GameObject item)
{
for (int i = 0; i < slots; i++)
{
if (slot[i].GetComponent<Slot>().empty && itemAdded == false)
{
slot[i].GetComponent<Slot>().item = itemPickedUp;
slot[i].GetComponent<Slot>().itemIcon = itemPickedUp.GetComponent<Item>().icon;
//attachs the item to the hand *correct
item.transform.parent = itemManager.transform;
item.transform.position = itemManager.transform.position;
//equipar arma
item.transform.localPosition = item.GetComponent<Item>().position;
item.transform.localEulerAngles = item.GetComponent<Item>().rotation;
item.transform.localScale = item.GetComponent<Item>().scale;
Destroy(item.GetComponent<Rigidbody>());
itemAdded = true;
item.SetActive(false);
}
}
}
// Detect slots *correct
public void DetectInventorySlots()
{
for (int i = 0; i < slots; i++)
{
slot[i] = slotHolder.transform.GetChild(i);
}
inventory.GetComponent<Canvas>().enabled = true;
inventoryEnabled = false;
}
}
and the slot script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems; // Required when using Event data.
using UnityEngine.UI;
public class Slot : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler
{
//instructions *correct
private bool hovered;
public bool empty;
public Image image;
public GameObject item;
public Texture itemIcon;
private GameObject player;
//Update *correct
void Start()
{
player = GameObject.FindWithTag("Player");
hovered = false;
image.enabled = false;
}
void Update()
{
if (item)
{
empty = false;
itemIcon = item.GetComponent<Item>().icon;
this.GetComponent<RawImage>().texture = itemIcon;
} else {
empty = true;
this.GetComponent<RawImage>().texture = null;
}
}
//Pointer *correct
public void OnPointerEnter(PointerEventData eventData)
{
hovered = true;
}
public void OnPointerExit(PointerEventData eventData)
{
hovered = false;
}
public void OnPointerClick(PointerEventData eventData)
{
if(item)
{
Item thisItem = item.GetComponent<Item>();
//water
if(thisItem.type == "Water")
{
player.GetComponent<Player>().Drink(thisItem.decreaseRate);
Destroy(item);
}
//food
if (thisItem.type == "Food")
{
player.GetComponent<Player>().Eat(thisItem.decreaseRate);
Destroy(item);
}
//weapon
if(thisItem.type == "Weapon" && player.GetComponent<Player>().weaponEquipped == false)
{
thisItem.equipped = true;
item.SetActive(true);
imageEnabled();
}
if (thisItem.type == "Weapon" && player.GetComponent<Player>().weaponEquipped == true)
{
thisItem.equipped = false;
item.SetActive(false);
image.enabled = false;
player.GetComponent<Player>().weaponEquipped = false;
}
}
}
public void imageEnabled()
{
image.enabled = !image.enabled;
}
public class StackItem
{
public Item item = new Item();
public int amount = 1;
}
}
but i think you will only need the craft system script. Hope someone can help me.
Seems like your craft is completed on this instruction:
if (itemsFound >= requiredItems)
{
GameObject spawndedItem = Instantiate(thisItem, /* pos,*/player.transform.position, Quaternion.identity);
}
Next to GameObject spawndedItem... string you can specify your element deletion code, as an example:
if (itemsFound >= requiredItems)
{
GameObject spawndedItem = Instantiate(thisItem, /* pos,*/player.transform.position, Quaternion.identity);
Destroy(GameObject.Find("ObjectThatYouWantToDestroyName"));
}
Related
I am working on a dialogue and questing system for a 2d game I am working on. I am attempting to have multiple NPCs that will give different quests with different dialogue that is unique to each quest. I attempt to trigger my dialogue whenever a player presses the E key. Currently my game displays the dialogue whenever the player becomes in contact with the NPCs collider. The dialogue also begins with the second sentence of the dialogue array. Additionally, once the player has interacted with multiple npcs, the dialogue for all npc becomes the dialogue of the last npc that was interacted with.
Here is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
public class QuestGiver : NPC
{
public bool AssignedQuest { get; set; }
public bool Helped { get; set; }
[SerializeField]
private GameObject quests;
[SerializeField]
private string questType;
private Quest Quest { get; set; }
public CharacterController2D player;
public GameObject questWindow;
public Text titleText;
public Text descriptionText;
public Text expRewardText;
public Text currencyRewardText;
private void Start()
{
}
public override void Interact()
{
if (!AssignedQuest && !Helped)
{
DialogueManager.Instance.AddNewDialogue(dialogue, name);
AssignQuest();
}
else if (AssignedQuest && !Helped)
{
CheckQuest();
}
else
{
DialogueManager.Instance.AddNewDialogue(Quest.completedDialogue, name);
}
}
void AssignQuest()
{
AssignedQuest = true;
Quest = (Quest)quests.AddComponent(Type.GetType(questType));
}
void CheckQuest()
{
if (Quest.Completed)
{
Quest.GiveReward();
Helped = true;
AssignedQuest = false;
DialogueManager.Instance.AddNewDialogue(Quest.rewardDialogue, name);
Destroy(quests.GetComponent(Type.GetType(questType)));
}
else
{
DialogueManager.Instance.AddNewDialogue(Quest.inProgressDialogue, name);
}
}
public void OpenQuestWindow()
{
questWindow.SetActive(true);
titleText.text = Quest.QuestName;
descriptionText.text = Quest.Description;
expRewardText.text = Quest.ExpRewards.ToString();
currencyRewardText.text = Quest.CurrencyReward.ToString();
}
public void AcceptQuest()
{
questWindow.SetActive(false);
Quest.Completed = false;
player.questsList.Add(Quest);
}
}
This is the Quest script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
[System.Serializable]
public class Quest : MonoBehaviour
{
public List<QuestGoal> Goals { get; set; } = new List<QuestGoal>();
public string[] inProgressDialogue, rewardDialogue, completedDialogue;
public string QuestName { get; set; }
public string Description { get; set; }
public int ExpRewards { get; set; }
public int CurrencyReward { get; set; }
public Item ItemReward { get; set; }
public bool Completed { get; set; }
public void CheckGoals()
{
Completed = Goals.All(q => q.Completed);
if (Completed) GiveReward();
}
public void GiveReward()
{
if (ItemReward != null)
Inventory.inventory.Add(ItemReward);
}
This is the NPC:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NPC : Interactable
{
public string[] dialogue;
public string name;
public override void Interact()
{
base.Interact();
DialogueManager.Instance.AddNewDialogue(dialogue, name);
Debug.Log("Interacting with " + name);
}
public void TriggerDialogue()
{
FindObjectOfType<DialogueManager>().AddNewDialogue(dialogue, name);
}
}
This is my dialogue script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
public class DialogueManager : MonoBehaviour
{
#region
public static DialogueManager Instance { get; set; }
public GameObject dialoguePanel;
private void Awake()
{
dialoguePanel.SetActive(false);
if (Instance != null && Instance != this)
{
Debug.Log(Instance);
Destroy(Instance);
}
else
{
Instance = this;
}
}
#endregion
public Text nameText, dialogueText;
public Button continueButton;
public Animator animator;
public string npcName;
int dialogueIndex;
public List<string> dialogueLines = new List<string>();
void Start()
{
}
public void AddNewDialogue(string[] lines, string npcName)
{
dialogueIndex = 0;
dialogueLines = new List<string>();
foreach (string line in lines)
{
dialogueLines.Add(line);
}
this.npcName = npcName;
Debug.Log(dialogueLines.Count);
Debug.Log(npcName);
CreateDialogue();
}
public void CreateDialogue()
{
nameText.text = npcName;
dialogueText.text = dialogueLines[dialogueIndex];
dialoguePanel.SetActive(true);
animator.SetBool("IsOpen", true);
ContinueDialogue();
}
public void ContinueDialogue()
{
if (dialogueIndex < dialogueLines.Count - 1)
{
dialogueIndex++;
dialogueText.text = dialogueLines[dialogueIndex];
}
else
{
EndDialogue();
}
StopAllCoroutines();
StartCoroutine(TypeSentence(dialogueText.text));
}
IEnumerator TypeSentence (string sentence)
{
dialogueText.text = "";
foreach (char letter in sentence.ToCharArray())
{
dialogueText.text += letter;
yield return null;
}
}
void EndDialogue()
{
animator.SetBool("IsOpen", false);
Debug.Log("End of conversation");
}
}
This is part of the Player controller:
using UnityEngine;
using UnityEngine.Events;
using Spine.Unity;
using UnityEngine.EventSystems;
using System.Collections.Generic;
public class CharacterController2D : MonoBehaviour
{
private GameObject triggeringNpc;
public GameObject npcText;
public List<Quest> questsList = new List<Quest>();
private bool triggering;
private void OnTriggerEnter2D(Collider2D other)
{
Interactable interactable = other.gameObject.GetComponent<Interactable>();
if (interactable != null)
{
interactable.Interact();
}
if (other.tag == "NPC")
{
triggering = true;
triggeringNpc = other.gameObject;
}
if (other.tag == "QuestGiver")
{
triggering = true;
triggeringNpc = other.gameObject;
}
}
private void OnTriggerExit2D(Collider2D other)
{
if (other.tag == "NPC")
{
triggering = false;
triggeringNpc = null;
}
if (other.tag == "QuestGiver")
{
triggering = false;
triggeringNpc = null;
}
}
private void Update()
{
if (triggering)
{
npcText.SetActive(true);
if (Input.GetKeyDown(KeyCode.E))
{
FindObjectOfType<QuestGiver>().TriggerDialogue();
}
}
else
{
npcText.SetActive(false);
}
}
}
Thank you in advance, sorry for the long post.
Dialogue starting on the second line:
In the CreateDialogue() method, at the end you are calling ContinueDialogue(). So you create dialogue and then immediately tell it to go to the next line. I think instead you might want to be calling StartCoroutine(TypeSentence(dialogueText.text)) at the end of CreateDialogue().
Interaction issues:
You're calling Interact() at the beginning of OnTriggerEnter2D by doing interactable.Interact(). Here, erase all the code inside your OnTriggerEnter2D method and replace it with this.
if (other.tag == "NPC" || other.tag == "QuestGiver") {
triggering = true;
triggeringNpc = other.gameObject;
} else if (interactable != null) { interactable.Interact(); }
I have one problem, I am not running the "OnTriggerEnter2D" method on the prefab.
I took the object, threw a script on it, added the right components and made it prefab.
I have a hero when he attacks a collider appears which is a trigger.
If this collider is a player's sword then the enemy receives damage.
A regular object (not a prefab) gets damaged, but if I do this object a prefab and drag it onto the stage then the "OnTriggerEnter2D" method does not work.
Here's the enemy script. I also poured my project on the Github, for a better understanding. I will be very grateful for the help, because I could not understand the reason. My project -
https://github.com/OleksandrKupchuk/SimpleGame
//Enemy Archer
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyArcher : EnemyBase
{
[SerializeField] GameObject arrowPrefab;
[SerializeField] Transform startPositionArrow;
public override void Start()
{
base.Start();
ChangeStateEnemy(new IdleState());
}
public new void Update()
{
//ChangeState(currentState);
StateEnemy();
}
private void StateEnemy()
{
currentState.Execute();
}
public override void Attack()
{
timeAttack += Time.deltaTime;
enemyAnimator.SetFloat("animatorEnemyRun", 0);
if (timeAttack >= delayAttack)
{
CanAttack = true;
timeAttack = 0;
}
if (CanAttack)
{
enemyAnimator.SetTrigger("animatorEnemyAttack");
CanAttack = false;
}
}
public void FireArrow()
{
if (facingRight)
{
enemyAnimator.SetTrigger("animatorEnemyAttack");
GameObject arrow = Instantiate(arrowPrefab, startPositionArrow.position, Quaternion.identity);
arrow.GetComponent<EnemyArrowMove>().ArrowInitialization(Vector2.right);
}
else
{
GameObject arrow = Instantiate(arrowPrefab, startPositionArrow.position, Quaternion.Euler(new Vector3(0f, 180f, 0f)));
arrow.GetComponent<EnemyArrowMove>().ArrowInitialization(Vector2.left);
}
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.CompareTag("PlayerSword"))
{
Debug.Log("Take");
TakeDamage();
EnemyTarget = collision.gameObject;
}
}
}
//////
//Enemy Base
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Rigidbody2D))]
[RequireComponent(typeof(Animator))]
[RequireComponent(typeof(BoxCollider2D))]
[RequireComponent(typeof(CircleCollider2D))]
public class EnemyBase : CharacterBase
{
public IStateEnemy currentState;
protected float timeAttack;
[SerializeField] protected float delayAttack;
public bool CanAttack { get; set; }
protected float dirPlayer;
public GameObject EnemyTarget { get; set; }
[SerializeField] protected float enemyRangeAttack;
[SerializeField] int experienceForTheEnemy;
public bool EnemyRangeAttack
{
get
{
if (EnemyTarget != null)
{
if (Vector2.Distance(EnemyTarget.transform.position, transform.position) <= enemyRangeAttack)
{
return true;
}
}
return false;
}
}
public bool EnemyOutsideEdge
{
get
{
if(transform.position.x >= rightEdge.position.x || transform.position.x <= leftEdge.position.x)
{
return true;
}
return false;
}
}
//edges for enemy
[SerializeField] protected Transform leftEdge;
[SerializeField] protected Transform rightEdge;
public bool EnemyDie
{
get
{
if(health <= 0)
{
return true;
}
return false;
}
}
[SerializeField] EdgeCollider2D enemySword;
[SerializeField] private Rigidbody2D enemyRigidbody;
public Rigidbody2D EnemyRigidbody { get => enemyRigidbody; set => enemyRigidbody = value; }
public Animator enemyAnimator;
[SerializeField] int takeDamage;
public bool EnemyAttack { get; set; }
public bool EnemyHit { get; set; }
protected float directionEnemy;
public override void Start()
{
base.Start();
enemyAnimator = GetComponent<Animator>();
}
public void Update()
{
}
public void TakeDamage()
{
if (!EnemyDie)
{
enemyAnimator.SetTrigger("animatorEnemyHit");
health -= takeDamage;
if (health <= 0)
{
enemyAnimator.SetTrigger("animatorEnemyDie");
Destroy(gameObject, 1.5f);
Player.PlayerInstance.AddIndicatorForPlayer(experienceForTheEnemy);
}
}
}
public void EnemySwordEnabled()
{
enemySword.enabled = true;
}
public void EnemySwordDisabled()
{
enemySword.enabled = false;
}
public void Flip()
{
//Debug.Log("Flip");
facingRight = !facingRight;
transform.localScale = new Vector2(transform.localScale.x * -1, transform.localScale.y);
//transform.Rotate(0f, 180f, 0f);
}
public void Walk()
{
if (!EnemyAttack && !EnemyDie && !EnemyHit)
{
if ((ChangeSide().x > 0 && transform.position.x < rightEdge.position.x) || (ChangeSide().x < 0 && transform.position.x > leftEdge.position.x))
{
enemyAnimator.SetFloat("animatorEnemyRun", 1);
transform.Translate(ChangeSide() * speed * Time.deltaTime);
}
}
}
public Vector2 ChangeSide()
{
if (facingRight)
{
return Vector2.right;
}
return Vector2.left;
}
public void ChangeDirection()
{
if (transform.position.x >= rightEdge.position.x || transform.position.x <= leftEdge.position.x)
{
Flip();
}
}
public void EnemyLookTarget()
{
if (!EnemyDie && EnemyTarget != null)
{
directionEnemy = EnemyTarget.transform.position.x - transform.position.x;
if (directionEnemy < 0 && facingRight || directionEnemy > 0 && !facingRight)
{
Flip();
}
}
}
public virtual void Attack()
{
timeAttack += Time.deltaTime;
//enemyAnimator.SetFloat("animatorEnemyRun", 0);
if (timeAttack >= delayAttack)
{
CanAttack = true;
timeAttack = 0;
}
if (CanAttack)
{
enemyAnimator.SetTrigger("animatorEnemyAttack");
CanAttack = false;
}
}
public void ChangeStateEnemy(IStateEnemy newState)
{
currentState = newState;
currentState.Enter(this);
}
}
I have a list, list_of_targetable, into which I spawn enemy instances. I can see during play in the inspector that the instances are spawning correctly and being put in the list correctly.
When I try to reference those instances, from within the same script, they seemly do not exist, and the list.Count returns 0. Furthermore, the way I am calling TargetEnemySlot1 is via button, so long after Start, when the enemies are initialized.
What gives?
public class Targeting : MonoBehaviour
{
public List<Combatant> current_targets;
public List<Combatant> list_of_targetable;
public void TargetEnemySlot1()
{
Debug.Log(list_of_targetable.Count);
current_targets.Add(list_of_targetable[0]);
current_targets[0].is_target = true;
current_targets[0].targeting_panel.SetActive(false);
}
}
Things that interact directly with the lists:
public class AbAttack : MonoBehaviour, IAbility
{
public Targeting targeting_for_attack;
public int block_attack_damage = 10;
public int block_attack_repeats = 2;
public bool needs_targets = true;
public bool targets_allies = false;
public bool targets_enemies = true;
public int number_of_targets = 1;
public void Use()
{
if (needs_targets == true)
{
if (targets_enemies == true)
{
foreach (Combatant enemy in targeting_for_attack.list_of_targetable)
{
enemy.targeting_panel.SetActive(true);
}
}
}
}
public void Enact()
{
foreach (Combatant enemy in targeting_for_attack.current_targets)
{
for (int i = 0; i < block_attack_repeats; i++)
{
enemy.health = enemy.health - block_attack_damage;
}
}
}
}
public class EnemySpawner : MonoBehaviour
{
public List<Combatant> CombatantList = new List<Combatant>();
public List<Combatant> CombatantInWaitingList = new List<Combatant>();
public List<Combatant> CombatantInCombatList = new List<Combatant>();
Inventory inventory;
public List <GameObject> targeting_panel;
public Targeting targeting_panel_targeting;
public Sprite icon1;
// Start is called before the first frame update
void Start()
{
inventory = Inventory.instance;
DrainList();
SpawnList();
}
public void DrainList()
{
List<Combatant> ToRemoveList = new List<Combatant>();
foreach (Combatant item in CombatantInWaitingList)
{
if (CombatantInCombatList.Count <= 3)
{
CombatantInCombatList.Add(item);
ToRemoveList.Add(item);
}
}
foreach (Combatant item in ToRemoveList)
{
CombatantInWaitingList.Remove(item);
}
}
public void SpawnList()
{
List<Combatant> ToRemoveList = new List <Combatant>();
foreach (Combatant item in CombatantInCombatList)
{
if (Inventory.instance.items1.Count == 0)
{
Combatant data1 = Combatant.CreateInstance("spider", icon1, targeting_panel[0]);
Inventory.instance.items1.Add(data1);
targeting_panel_targeting.list_of_targetable.Add(data1);
ToRemoveList.Add(item);
}
if (Inventory.instance.items1.Count == 1)
{
Combatant data1 = Combatant.CreateInstance("spider", icon1, targeting_panel[1]);
Inventory.instance.items1.Add(data1);
targeting_panel_targeting.list_of_targetable.Add(data1);
ToRemoveList.Add(item);
}
if (Inventory.instance.items1.Count == 2)
{
Combatant data1 = Combatant.CreateInstance("spider", icon1, targeting_panel[2]);
Inventory.instance.items1.Add(data1);
targeting_panel_targeting.list_of_targetable.Add(data1);
ToRemoveList.Add(item);
}
}
foreach (Combatant item in ToRemoveList)
{
// Add new combataant at that list location FIRST
CombatantInCombatList.Remove(item);
}
}
}
The IN GAME inspector with the instances spawned correctly:
http://prntscr.com/o629xb
I am getting #endregoin diretive expected in this class:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MobileInput : MonoBehaviour {
private const float DEADZONE = 100.0f;
public static MobileInput Instance { set; get; }
private bool tap, swipeLeft, swipeLeft, swipeRight, swipeUp, swipeUp, swipeDown;
private Vector2 swipeDelta, startTouch;
public bool Tap { get { return tap; } }
public Vector2 SwipeDelta { get { return swipeDelta; } }
public Vector2 SwipeLeft { get { return swipeLeft; } }
public Vector2 SwipeRight { get { return swipeRight; } }
public Vector2 SwipeUp { get { return swipeUp; } }
public Vector2 SwipeDown { get { return swipeDown; } }
private void Awake()
{
Instance = this;
}
private void Update()
{
//reseting all the bool
tap = swipeLeft = swipeRight = swipeDown = swipeUp = false;
//lets check input
#region Standalone Inputs
if (Input.GetMouseButtonDown(0))
{
tap = true;
startTouch = Input.mousePosition;
}
else if (Input.GetMouseBottonUp(0))
{
startTouch = swipeDelta = Vector2.zero;
}
#region Mobile Inputs
if (Input.touches.Length != 0)
{
if (Input.touches[0].phase == TouchPhase.Began)
{
tap = true;
startTouch = Input.mousePosition;
}
else if (Input.touches[0].phase == TouchPhase.Ended || Input.touches[0].phase == TouchPhase.Canceled)
{
startTouch = swipeDelta = Vector2.zero;
}
}
#endregion
//Calculate
swipeDelta = Vector2.zero;
if (startTouch != Vector2.zero)
{
//let's check
if (Input.touches.Length != 0)
{
swipeDelta = Input.touches[0].position - startTouch;
}
//lets check standalone
else if (Input.GetMouseButton(0))
{
swipeDelta = (Vector2)Input.mousePosition - startTouch;
}
}
//Check dead zone
if (swipeDelta.magnitude > DEADZONE)
{
// this is a confirmed swip
float x = swipeDelta.x;
float y = swipeDelta.y;
if (Mathf.Abs(x) > Mathf.Abs(y))
{
//left
if (x < 0)
swipeLeft = true;
else
swipeRight = true;
}
else
{
//up or down
if (y < 0)
swipeDown = true;
else
swipeUp = true;
}
startTouch = swipeDelta = Vector2.zero;
}
}
}
Your #region Standalone Inputs is missing an #endregion further down in your code.
In my 2D Unity project my player does not always jump while pressing the "jump" button. He does no jump the second i land on the ground but after a second of "being grounded" he can jump again. What can this problem be?
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class player : MonoBehaviour {
private static player instance;
public static player Instance
{
get
{
if (instance == null)
{
instance = GameObject.FindObjectOfType<player>();
}
return instance;
}
}
private Animator myAnimator;
[SerializeField]
public static float movementSpeed;
private bool facingRight = true;
[SerializeField]
private Transform[] groundPoints;
[SerializeField]
private float groundRadius;
[SerializeField]
private LayerMask whatIsGround;
[SerializeField]
private bool airControl;
[SerializeField]
private float jumpForce;
public bool canMove;
public AudioClip jump001;
public AudioClip jump002;
private float direction;
private bool move;
private float btnHorizontal;
public Rigidbody2D MyRigidbody { get; set; }
public bool Attack { get; set; }
public bool Jump { get; set; }
public bool OnGround { get; set; }
// Use this for initialization
void Start() {
facingRight = true;
MyRigidbody = GetComponent<Rigidbody2D>();
myAnimator = GetComponent<Animator>();
}
void Update()
{
HandleInput();
}
// Update is called once per frame
void FixedUpdate()
{
OnGround = IsGrounded();
float horizontal = Input.GetAxis("Horizontal");
if (move)
{
this.btnHorizontal = Mathf.Lerp(btnHorizontal, direction, Time.deltaTime * 5);
HandleMovement(btnHorizontal);
Flip(direction);
}
else
{
HandleMovement(horizontal);
Flip(horizontal);
}
if (!canMove)
{
GetComponent<Rigidbody2D>().velocity = new Vector2(0, GetComponent<Rigidbody2D>().velocity.y);
myAnimator.SetFloat("speed", 0);
return;
}
HandleLayers();
}
private void HandleMovement(float horizontal)
{
if (MyRigidbody.velocity.y < 0)
{
myAnimator.SetBool("land", true);
}
if (!Attack && (OnGround || airControl))
{
MyRigidbody.velocity = new Vector2(horizontal * movementSpeed, MyRigidbody.velocity.y);
}
if (Jump && MyRigidbody.velocity.y == 0)
{
SoundManager.instance.RandomizeSfx(jump001, jump002);
MyRigidbody.AddForce(new Vector2(0, jumpForce));
}
myAnimator.SetFloat("speed", Mathf.Abs(horizontal));
}
private void HandleInput()
{
if (canMove)
{
//Input.GetKeyDown(KeyCode.Space) || Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.W) ||
if (Input.GetButtonDown("Jump"))
{
myAnimator.SetTrigger("jump");
}
if (Input.GetKeyDown(KeyCode.Z) || Input.GetButton("Fight") && OnGround && !Jump)
{
myAnimator.SetTrigger("attack");
}
}
}
private void Flip(float horizontal)
{
if (horizontal > 0 && !facingRight || horizontal < 0 && facingRight && canMove)
{
facingRight = !facingRight;
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}
private bool IsGrounded()
{
{
}
if (MyRigidbody.velocity.y <= 0)
{
foreach (Transform point in groundPoints)
{
Collider2D[] colliders = Physics2D.OverlapCircleAll(point.position, groundRadius, whatIsGround);
for (int i = 0; i < colliders.Length; i++)
{
if (colliders[i].gameObject != gameObject)
{
return true;
}
}
}
}
return false;
}
private void HandleLayers()
{
if (!OnGround)
{
myAnimator.SetLayerWeight(1, 1);
}
else
{
myAnimator.SetLayerWeight(1, 0);
}
}
//TouchKnappar
public void BtnJump()
{
if (canMove)
{
myAnimator.SetTrigger("jump");
Jump = true;
}
}
public void BtnAttack()
{
myAnimator.SetTrigger("attack");
Attack = true;
}
public void BtnMove(float direction)
{
this.direction = direction;
this.move = true;
}
public void BtnStopMove()
{
this.direction = 0;
this.btnHorizontal = 0;
this.move = false;
}
public void BtnStopJump()
{
Jump = false;
}
}
I had the same problem and this fixed it for me.
This code identifies if the character is grounded in FixedUpdate()
Collider2D groundCol = Physics2D.OverlapBox(groundCheck.position, groundBoxRadius, 0f, whatIsGround);
this.grounded = (groundCol != null && !groundCol.isTrigger && this.rigbody2d.velocity.y > -0.01f && this.rigbody2d.velocity.y < 0.01f);
Some explanation:
groundCheck is an empty object at the feet of the character
In the condition I'm checking if the Overlay box collided with something a and if that something is not a trigger
Lastly the velocity speed can sometimes be not exactly a 0 so +-0.01f worked for me