I have the following script attached to my game object:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TouchDragDrop : MonoBehaviour
{
// Components
private Rigidbody2D myRigidbody2D;
private CanvasGroup canvasGroup;
private Collider2D myCollider2D;
// Drop Zones
[SerializeField] public List<GameObject> dropZones = new List<GameObject>();
// Indicators
private bool isMoving = false;
private bool debuglog = true;
public bool isDropped = false;
// Numbers
private Vector2 touchPosition;
private float deltaX, deltaY;
private Vector2 oldVelocity;
// Start is called before the first frame update
void Start()
{
myRigidbody2D = GetComponent<Rigidbody2D>();
myCollider2D = GetComponent<Collider2D>();
canvasGroup = GetComponent<CanvasGroup>();
}
// Update is called once per frame
void Update()
{
if (Input.touchCount > 0)
{
Touch touch = Input.GetTouch(0);
// touchPosition = touch.position;
touchPosition = Camera.main.ScreenToWorldPoint(touch.position);
switch (touch.phase)
{
case TouchPhase.Began: beginTouchMove(); break;
case TouchPhase.Moved: moveTouch(); break;
case TouchPhase.Stationary: stationaryTouch(); break;
case TouchPhase.Ended: endTouchMove(); break;
}
}
}
private void beginTouchMove()
{
if (myCollider2D == Physics2D.OverlapPoint(touchPosition))
{
if(debuglog) Debug.Log("Begin Touch # x: " + touchPosition.x.ToString() + " y: " + touchPosition.y.ToString());
//if(debuglog) Debug.Log("RigidBody: " + myRigidbody2D.position.ToString());
deltaX = touchPosition.x - transform.position.x;
deltaY = touchPosition.y - transform.position.y;
isMoving = true;
myRigidbody2D.bodyType = RigidbodyType2D.Kinematic;
oldVelocity = myRigidbody2D.velocity;
myRigidbody2D.velocity = new Vector2(0f, 0f);
}
}
private void moveTouch()
{
if (isMoving)
{
Vector2 newPosition = new Vector2(touchPosition.x - deltaX, touchPosition.y - deltaY);
//gameObject.transform.position = newPosition;
myRigidbody2D.MovePosition(newPosition);
//if(debuglog) Debug.Log("Touch Position: x: " + touchPosition.x.ToString() + " y: " + touchPosition.y.ToString());
//if(debuglog) Debug.Log("RigidBody: " + myRigidbody2D.position.ToString());
}
}
private void endTouchMove()
{
if (debuglog) Debug.Log("On End Touch");
canvasGroup.blocksRaycasts = true;
// Check drop zones for overlap
foreach(GameObject dropZone in dropZones)
{
if (debuglog) Debug.Log("Checking " + dropZone.name);
if(dropZone.GetComponent<Collider2D>() == Physics2D.OverlapPoint(myCollider2D.transform.position))
{
isDropped = true;
if (debuglog) Debug.Log("TOUCH: Found Collider");
dropZone.GetComponent<DropZone>().EndGameObjectLife(gameObject);
}
}
if(!isDropped) {
myRigidbody2D.bodyType = RigidbodyType2D.Dynamic;
myRigidbody2D.velocity = oldVelocity;
}
}
private void stationaryTouch()
{
//Debug.Log("Stationary Touch");
}
}
My problem is I dont know how to check that the Collider in gameObject has hit one of the colliders in the dropZones List. I dont get any errors, but I don't get the message "Touch: Found Collider" either. So the game doesnt acknoledge that the object has found its target.
What is the best way to go about this?
I tried doing
if(dropZone.GetComponent<Collider2D>() == Physics2D.OverlapPoint(touchPosition))
Which works to a point, but it does mean that the user can just touch the target without dragging the object and it'll recognize a drop. With the MouseEvents I have Ondrop, is there an equivilent for Touch?
To check if a collider hit other collider you can use Collider2D messages like OnCollisionEnter2D, OnCollisionExit2D, OnCollisionStay2D. There are similar messages if your collider is set to trigger like OnTriggerEnter2D.
Once you detect the collision check if the collider is in the dropZones list.
Related
I have a problem where when I click the dialogue while passing through an NPC or while moving, the character will continue moving in the direction of the joystick before it is set active to false.
I have tried setting the horizontal and vertical input to zero and even the movement direction which is the calculated horizontal and vertical input, but the character still moves in the last direction it was moving. I'm not sure if the if statement that I created is correct but that was the idea that came to mind.
This is the script for the movement of the player:
using UnityEngine;
using UnityEngine.EventSystems;
public class PlayerMovement : MonoBehaviour
{
[SerializeField] private GameObject interactButton;
public float speed, rotationSpeed, ySpeed, originalStepOffset;
public Joystick joystick;
private Animator animator;
private CharacterController characterController;
void Start()
{
animator = GetComponent<Animator>();
characterController = GetComponent<CharacterController>();
originalStepOffset = characterController.stepOffset;
}
// Update is called once per frame
void FixedUpdate()
{
float horizontalInput = joystick.Horizontal;
float verticalInput = joystick.Vertical;
Vector3 movementDirection = new Vector3(horizontalInput, 0, verticalInput);
movementDirection = Quaternion.Euler(0, 45f, 0) * movementDirection;
float magnitude = Mathf.Clamp01(movementDirection.magnitude) * speed;
movementDirection.Normalize();
ySpeed += Physics.gravity.y * Time.deltaTime;
if(characterController.isGrounded)
{
characterController.stepOffset = originalStepOffset;
ySpeed = -0.5f;
}
else
{
characterController.stepOffset = 0;
}
Vector3 velocity = movementDirection * magnitude;
velocity = AdjustVelocityToSlope(velocity);
velocity.y += ySpeed;
//transform.Translate(movementDirection * speed * Time.deltaTime, Space.World);
characterController.Move(velocity * Time.deltaTime);
if (movementDirection != Vector3.zero)
{
if(EventSystem.current.currentSelectedGameObject != null)
{
if (EventSystem.current.currentSelectedGameObject.name == "InteractButton")
{
horizontalInput = 0f;
verticalInput = 0f;
movementDirection = Vector3.zero;
animator.SetBool("IsMoving", false);
}
else
{
//transform.forward = movementDirection;
animator.SetBool("IsMoving", true);
Quaternion toRotation = Quaternion.LookRotation(movementDirection, Vector3.up);
transform.rotation = Quaternion.RotateTowards(transform.rotation, toRotation, rotationSpeed * Time.deltaTime);
}
}else
{
animator.SetBool("IsMoving", true);
Quaternion toRotation = Quaternion.LookRotation(movementDirection, Vector3.up);
transform.rotation = Quaternion.RotateTowards(transform.rotation, toRotation, rotationSpeed * Time.deltaTime);
}
} else
{
animator.SetBool("IsMoving", false);
}
}
private Vector3 AdjustVelocityToSlope(Vector3 velocity)
{
var ray = new Ray(transform.position, Vector3.down);
if(Physics.Raycast(ray, out RaycastHit hitInfo, 0.2f))
{
var slopeRotation = Quaternion.FromToRotation(Vector3.up, hitInfo.normal);
var adjustedVelocity = slopeRotation * velocity;
if(adjustedVelocity.y < 0)
{
return adjustedVelocity;
}
}
return velocity;
}
}
The function that will make the button to set active to true and add its onclick listeners is a trigger enter function and a trigger exit for setting it active to false and removing the onclick listeners. It is attached to multiple NPC whenever I go near them, the button will appear. In case someone needs to see the script for the button here it is, but I'm gonna paste only until the related part:
using System;
using System.Collections;
using System.Drawing;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
[System.Serializable]
public class DialogueManager : MonoBehaviour
{
/*
// NPC INTERACTION
private static DialogueManager buttonOwner;
private Camera mainCamera;
*/
// NPC DATA
private Character characterJson;
// FOR DIALOG FLOW
private int multiDialogCycle;
public static int dialogId;
// GAME OBJECTS REFERENCE
[SerializeField] private GameObject dialogBox, addPanel, m1, id, darkPanel;
[SerializeField] private Button nameBtn, choiceOneBtn, choiceTwoBtn;
[SerializeField] private TextMeshProUGUI npcName, choiceOne, choiceTwo, dialogName, dialogMessage, addedText;
[SerializeField] private TextAsset characterData;
// FOR MULTIPLE DIALOGUES WITHOUT CHOICES
private bool clickEnable;
private string[] multiDialog;
// CHOICES STORAGE
private static Choice[] choices = new Choice[2];
//private TryInstantiate tryInstantiate = new TryInstantiate();
private GameData gameData;
private void Start()
{
// LOAD NPC DATA
characterJson = JsonUtility.FromJson<Character>(characterData.text);
// SET DEFAULT VALUE
//dialogId = 0;
multiDialogCycle = 0;
clickEnable = false;
// SET SCRIPTABLE OBJECT FOR DATA STORAGE
gameData = Resources.Load<GameData>("GameData/GameData");
}
private void Update()
{
if(nameBtn.gameObject.activeInHierarchy)
{
if(Input.GetKey(KeyCode.Space))
{
EventSystem.current.SetSelectedGameObject(nameBtn.gameObject);
}
}
// FOR ENDING DIALOGUES WITHOUT CHOICES
if (Input.GetMouseButtonDown(0) && clickEnable == true)
{
if (multiDialog.Length > 1 )
{
if(getDialog(dialogId).choices.Length == 0 && multiDialogCycle == multiDialog.Length - 1)
{
addArticles();
addObjectives();
addClues();
closeDialog();
Debug.Log(getDialog(dialogId).minigame);
}
else
{
if(getDialog(dialogId).minigame != "" && multiDialogCycle < multiDialog.Length - 1)
{
if(!gameData.idShown)
{
darkPanel.SetActive(true);
id.SetActive(true);
}
}else
{
multiDialogCycle++;
loadCharacterData();
}
}
}
else
{
if (getDialog(dialogId).minigame != "")
{
if(getDialog(dialogId).minigame == "spot_object")
{
m1.SetActive(true);
}
dialogBox.SetActive(false);
gameData.dialogActive = false;
}
else
{
addArticles();
addObjectives();
addClues();
closeDialog();
}
}
}
if(gameData.idShown)
{
multiDialogCycle++;
loadCharacterData();
gameData.idShown = false;
}
if (gameData.dialogActive && dialogId != 0 && getDialog(dialogId).minigame != "" && !gameData.loadedData)
{
updateID();
loadCharacterData();
}
// FOR NPC NAMES
/*
if (buttonOwner != this) return;
if (!mainCamera) mainCamera = Camera.main;
var position = mainCamera.WorldToScreenPoint(head.position + offset);
//uiUse.transform.position = position;
nameBtn.transform.position = position;
*/
}
private void OnTriggerEnter(Collider collisionInfo)
{
if (collisionInfo.CompareTag("Player"))
{
nameBtn.gameObject.SetActive(true);
nameBtn.GetComponent<Image>().sprite = Resources.Load<Sprite>("InteractionAsset/DIALOGUE");
nameBtn.transform.GetChild(0).GetComponent<TextMeshProUGUI>().color = new Color32(75,75,75,255);
//buttonOwner = this;
nameBtn.onClick.RemoveListener(onNameClick);
nameBtn.onClick.AddListener(onNameClick);
choiceOneBtn.onClick.RemoveListener(onChoiceClick);
choiceOneBtn.onClick.AddListener(onChoiceClick);
choiceTwoBtn.onClick.RemoveListener(onChoiceClick);
choiceTwoBtn.onClick.AddListener(onChoiceClick);
npcName.text = characterJson.name;
}
}
private void OnTriggerExit(Collider collisionInfo)
{
if (collisionInfo.CompareTag("Player"))
{
nameBtn.onClick.RemoveListener(onNameClick);
choiceOneBtn.onClick.RemoveListener(onChoiceClick);
choiceTwoBtn.onClick.RemoveListener(onChoiceClick);
nameBtn.gameObject.SetActive(false);
//buttonOwner = null;
}
}
// DIALOGUE SYSTEM
public void onNameClick()
{
nameBtn.gameObject.SetActive(false);
dialogBox.SetActive(true);
gameData.dialogActive = true;
FindObjectOfType<AudioManager>().Play("ButtonSound");
if (dialogBox.activeInHierarchy)
{
if (dialogMessage != null && dialogName != null)
{
loadCharacterData();
interactedNPC();
}
else
{
// Debug.Log("null dialog message");
}
}
}
public void updateID()
{
if (gameData.win && !gameData.loadedData)
{
dialogId = gameData.targetId_1;
gameData.loadedData = true;
}
else if (!gameData.win && !gameData.loadedData)
{
dialogId = gameData.targetId_2;
gameData.loadedData = true;
}
}
How can I atleast reset the Joystick's position. I am currently using the Joystick Pack from Unity Asset Store.
I for one would start the Conversation flow from the dialogue step. Once the dialog starts, you can either set a bool or any other type of property (even a referenced object such as the dialogue itself or the NPC that it's chatting to, but a bool is simpler) that would be a marker. Simply put: public bool IsTalking;. This could be in PlayerMovement or the main Player-like component (or SO) which you can access from PlayerMovement via GameObject or a different public variable.
Next, once the dialogue mechanism starts, you can set the marker (such as the bool or NPC ref) in the Player-like component or PlayerMovement to true, false when the chatting stops.
Then in PlayerMovement.FixedUpdate() you can just stop code execution:
// Update is called once per frame
void FixedUpdate()
{
// or if (Player.IsTalking == true) if you want the marker there,
// but you can have it inside PlayerMovement if you wish as long as
// you can reference it without overhead - meaning don't do crazy
// stuff like searching all game objects/components for PlayerMovement)
if (IsTalking == true)
{
if (characterController != null)
characterController.Move(Vector3.zero);
if (animator != null)
animator.SetBool("IsMoving", false);
return;
}
// everything starts executing once the player stops talking to NPCs
float horizontalInput = joystick.Horizontal;
float verticalInput = joystick.Vertical;
Vector3 movementDirection = new Vector3(horizontalInput, 0, verticalInput);
movementDirection = Quaternion.Euler(0, 45f, 0) * movementDirection;
float magnitude = Mathf.Clamp01(movementDirection.
As I understood you dialogue window is modal. Depending on your needs you can stop the internal increment of time progression with
Time.timeScale = 0f;
But this will stop e.g. (UI) animations and the proper function of the event system, so some people use
Time.timeScale = 0.0001f;
This has the drawback that the gameplay continues slowly and our player hero could be hit by a very slow rocket while the user was resting in a pause screen.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveToTarget : MonoBehaviour
{
public enum TransitionState
{
None,
MovingTowards,
Transferring
}
public Transform destinationTransform;
public Transform navi;
public Transform player;
public bool isChild = false;
public AnimationCurve curve = AnimationCurve.EaseInOut(0.0f, 0.0f, 1.0f, 1.0f);
public float duration = 10.0f;
public bool go = false;
private float t;
private Transform originTransform;
private float timer;
private TransitionState state = TransitionState.MovingTowards;
private Vector3 originPosition;
void Start()
{
t = 0.0f;
curve.postWrapMode = WrapMode.Once;
originPosition = transform.position;
}
void Update()
{
if (go)
{
switch (state)
{
case TransitionState.MovingTowards:
var v = destinationTransform.position - transform.position;
if (v.magnitude < 0.001f)
{
state = TransitionState.Transferring;
originTransform = destinationTransform;
timer = 0;
return;
}
t += Time.deltaTime;
float s = t / duration;
transform.position = Vector3.Lerp(originPosition,
destinationTransform.position, curve.Evaluate(s));
break;
case TransitionState.Transferring:
timer += Time.deltaTime;
this.transform.position = Vector3.Lerp(originTransform.position, destinationTransform.position, timer);
if (timer >= 1.0f)
{
this.transform.parent = destinationTransform;
transform.localPosition = new Vector3(0, 0, 0);
isChild = true;
state = TransitionState.None;
this.enabled = false;
return;
}
break;
default:
this.enabled = false;
return;
}
}
}
}
I want to set the starting position before running the game in the editor when I drag the transform to some position when running the game it's changing back to the originPosition if I mark not to use the line at the Start()
//originPosition = transform.position;
Than it will start from the other side at all.
I want it to start moving from where I set it at the start position.
Moving the line
originPosition = transform.position;
To the Update() is also not a solution.
If transform.position returns something different from what you’ve set in edit mode, it’s affected by something else on Start() or Awake() in some script. Also it is possible, that some script sets public go variable to true on awake.
so i've been working on some code for a game in Unity and i am using the Input.GetMouseButtonDown(1) function. However, it only works the first time i press the left click in the game and no other times after that. The code for the player controller where it's used is below:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PlayerController : MonoBehaviour {
public float speed;
public Transform enemy;
public Transform shot;
public GameObject shotObj;
public Text scoreT;
public Text timeT;
public Text roundT;
public float health;
public float damageTaken;
public Vector3 lookPoint;
public float shotSpeed;
private Camera mainCamera;
private int round = 1;
private int tempRound = 0;
private float time = 300;
private bool win = false;
private bool allowShoot;
private EnemyController enemyScript;
private ShotController shotScript;
private bool tempImune = false;
private int targetTime;
private int score = 0;
private int defeatedEnemy = 0;
private GameObject enemyObj;
//coroutine
IEnumerator Pause(float timE)
{
allowShoot = false;
//time since the object was created
float start = Time.realtimeSinceStartup;
//sets the game to slow down to 0 movement
Time.timeScale = 0.0f;
//loops until start up time is less than start time + pause time
while (Time.realtimeSinceStartup < start + timE)
{
//returns null from the subroutine and restarts the subroutine at this point after null (0) time has passed
yield return null;
}
//sets the gamne to be running at normal speed
Time.timeScale = 1.0f;
allowShoot = true;
if (timE == 5.0f)
{
roundT.gameObject.SetActive(false);
}
}
void Start () {
//center mouse
Cursor.lockState = CursorLockMode.Locked;
Cursor.lockState = CursorLockMode.None;
//set camera to be the camera in the scene (should only ever be one camera in the scene)
mainCamera = FindObjectOfType<Camera>();
//set default text values
scoreT.text = "Score: 000000";
timeT.text = "Time Left: 600";
roundT.text = "Round: " + round;
//pause game before first round begins
StartCoroutine(Pause(5.0f));
}
void Update () {
//looka at mouse script
Ray cameraRay = mainCamera.ScreenPointToRay(Input.mousePosition);
Plane ground = new Plane(Vector3.up, Vector3.zero);
float rayLength;
if (ground.Raycast(cameraRay, out rayLength))
{
lookPoint = cameraRay.GetPoint(rayLength);
transform.LookAt(new Vector3(lookPoint.x, transform.position.y, lookPoint.z));
}
//enemy spawner check and win criteria check
if (defeatedEnemy != 45)
{
if (round != tempRound)
{
spawnEnemy();
roundT.gameObject.SetActive(true);
if (round == 5)
{
roundT.text = "Round: " + round + "(Final Round)";
}
else
{
roundT.text = "Round: " + round;
}
StartCoroutine(Pause(5.0f));
}
}
else
{
win = true;
}
//timer and win check
if (health == 0f)
{
win = true;
}
if (!win)
{
time -= Time.deltaTime;
timeT.text = "Time Left: " + time;
}
else
{
if (health == 0f)
{
roundT.gameObject.SetActive(true);
int finalScore = Mathf.RoundToInt(score * ((time / 2) / 10));
roundT.text = "To Bad, You Loose! Score = " + finalScore;
Debug.Log(finalScore);
StartCoroutine(Pause(99999f));
}
else
{
roundT.gameObject.SetActive(true);
int finalScore = Mathf.RoundToInt(score * ((time / 2) / 10));
roundT.text = "Congratulations! Score = " + finalScore;
Debug.Log(finalScore);
}
}
//movement controlls
if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
{
transform.Translate(new Vector3(0.0f, 0.0f, speed * Time.deltaTime));
}
if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
{
transform.Translate(new Vector3(-speed * Time.deltaTime, 0.0f, 0.0f));
}
if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
{
transform.Translate(new Vector3(0.0f, 0.0f, -speed * Time.deltaTime));
}
if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
{
transform.Translate(new Vector3(speed * Time.deltaTime, 0.0f, 0.0f));
}
//shoot controll
if (allowShoot)
{
Debug.Log("shot allowed");
if (Input.GetMouseButtonDown(0))
{
//var spawnShot = Instantiate(shot, this.transform.position + new Vector3(0.0f, 0.0f, 0.5f), this.transform.rotation);
//shotScript = shotObj.GetComponent<ShotController>();
//if (shotScript.enemy)
//{
// Debug.Log("enemy found");
// enemyScript = shotScript.enemy.GetComponent<EnemyController>();
// if(enemyScript.health <= 0.0f)
// {
// score += 20;
// defeatedEnemy += 1;
// scoreT.text = "Score: " + score;
// Debug.Log("enemy killed : " + defeatedEnemy);
// }
//}
Debug.Log("mouseDown");
int layermask = 1 << 8;
RaycastHit hit;
if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit, Mathf.Infinity, layermask))
{
enemyObj = hit.transform.gameObject;
enemyScript = enemyObj.GetComponent<EnemyController>();
Debug.Log("hit");
//hit.transform.SendMessage("HitByRay");
if (enemyScript.health == 0f)
{
Destroy(hit.transform.gameObject);
score += 20;
defeatedEnemy += 1;
scoreT.text = "Score: " + score;
Debug.Log("enemy killed : " + defeatedEnemy);
}
}
}
}
//enemy existance check
if (GameObject.Find("Enemy(Clone)") == null)
{
round = round + 1;
}
if (tempImune)
{
if (Mathf.RoundToInt(time) == targetTime)
{
tempImune = false;
}
}
}
void spawnEnemy()
{
tempRound = round;
for (int i = 1; i <= round * 3; i++)
{
var spawnEnemy = Instantiate(enemy, new Vector3(Random.Range(-14.5f, 14.5f), 0.25f, Random.Range(-6f, 6f)), Quaternion.identity);
}
}
void OnCollisionEnter(Collision col)
{
if (col.gameObject.tag == "Enemy")
{
if (!tempImune)
{
health = health - damageTaken;
Debug.Log(health);
tempImune = true;
targetTime = Mathf.RoundToInt(time) - 1;
}
}
}
}
Any help with this would be greatly appreciated as it's for a school project. Thanks.
You need to call this function from the Update function, since the state gets reset each frame. It will not return true until the user has released the mouse button and pressed it again. button values are 0 for the primary button (often the left button), 1 for secondary button, and 2 for the middle button
using UnityEngine;
using System.Collections;
public class ClassName : MonoBehaviour
{
void Update()
{
if (Input.GetMouseButtonDown(0))
Debug.Log("Pressed primary button.");
if (Input.GetMouseButtonDown(1))
Debug.Log("Pressed secondary button.");
if (Input.GetMouseButtonDown(2))
Debug.Log("Pressed middle click.");
}
}
I'm building a game like the roll a ball game on the tutorials in the Unity website, now I'm focused on the gameover menu, when the player lose all his lives I activate the gameover text, the yes and no text and the rawImage that is displayed behind the yes text by default, the thing is I want the image that is behind the yes text to go down to no and up to yes with the arrow keys. I think I implemented it right with the keys, but I feel like I need a coroutine to build this, because it just leaves the gameover function, without waiting the user input, so after this how can I build this in a right mode?
I did this at the moment:
public class Manager : MonoBehaviour {
private float checkPoint = 0;
public GameObject Ball;
private GameObject cam;
private Object newBall;
public int lifes;
public Text Lifetext;
private bool gameIsOver = false;
private Text gameOver;
private Text playAgain;
private Text yes;
private Text no;
private RawImage TopMenuBall;
void Awake(){
Lifetext = GameObject.Find("Lifes").GetComponent<Text>();
gameOver = GameObject.Find("GameOver").GetComponent<Text>();
playAgain = GameObject.Find("PlayAgain").GetComponent<Text>();
yes = GameObject.Find("Yes").GetComponent<Text>();
no = GameObject.Find("No").GetComponent<Text>();
TopMenuBall = GameObject.Find("TopMenuBall").GetComponent<RawImage>();
gameOver.enabled = false;
playAgain.enabled = false;
yes.enabled = false;
no.enabled = false;
TopMenuBall.enabled = false;
TopMenuBall.transform.localPosition = new Vector3(-68,-41,0);
}
void Start(){
lifes = 3;
Lifetext.text = " x" + lifes;
SpawnBall ();
cam = GameObject.Find ("Main Camera");
}
public void LifeUp(){
lifes++;
Lifetext.text = "X " + lifes;
}
public void LifeDown(){
if (lifes <= 0) {
GameOver ();
} else {
lifes--;
Lifetext.text = "X " + lifes;
}
}
public void GameOver(){
Debug.Log ("gameover");
gameOver.enabled = true;
playAgain.enabled = true;
yes.enabled = true;
no.enabled = true;
TopMenuBall.enabled = true;
if (Input.GetKeyDown (KeyCode.DownArrow)) {
TopMenuBall.transform.localPosition = new Vector3 (-68, -82, 0);
Debug.Log ("up");
}
else if (Input.GetKeyDown(KeyCode.UpArrow))
TopMenuBall.transform.localPosition = new Vector3(-68,-41,0);
}
void SpawnBall(){
Vector3 spawnPosition = new Vector3 (0.02f,1.4f,-39f);
Quaternion spawnRotation = Quaternion.identity;
newBall = Instantiate (Ball, spawnPosition, spawnRotation);
Camera.main.GetComponent<cameraMove>().player = (GameObject)newBall;
}
when the user lose all the lifes it enters the gameover function and there is the problem, how can I solve this?
You should use Update() method to get the user inputs. Because you need it to be constantly checked and the Update method exists exactly for this kind of situation, once it is called every frame.
So, your code should look like this:
void Update() {
if (TopMenuBall.enabled) {
if (Input.GetKeyDown (KeyCode.DownArrow)) {
TopMenuBall.transform.localPosition = new Vector3 (-68, -82, 0);
Debug.Log ("up");
}
else if (Input.GetKeyDown(KeyCode.UpArrow))
TopMenuBall.transform.localPosition = new Vector3(-68,-41,0);
}
}
So I have a player movement script that is supposed to allow the player to double jump by counting the number of times the space bar is pressed. It was working a couple versions early, but now has just randomly stopped working. No idea why it randomly stopped working.
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour
{
public float jumpPower = 2f;
[SerializeField]
public bool isGrounded = true;
[SerializeField]
private LayerMask groundLayer, waterLayer;
private int numSpacePress = 0;
private Rigidbody2D rb;
// Ground Checker Stuff
public Transform groundChecker;
public float groundCheckRadius = 0.1f;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space) && isGrounded && numSpacePress < 2)
{
numSpacePress++;
Debug.Log("Num spaces pressed = " + numSpacePress);
rb.velocity = new Vector2(rb.velocity.x, jumpPower);
if (numSpacePress >= 2)
{
isGrounded = false;
}
}
Collider2D[] hits = Physics2D.OverlapCircleAll(groundChecker.position, groundCheckRadius);
foreach (Collider2D hit in hits)
{
if (hit.gameObject != gameObject)
{
Debug.Log("Hit = " + hit.gameObject.name);
if (((1 << hit.GetComponent<Collider2D>().gameObject.layer) & groundLayer) != 0)
{
isGrounded = true;
numSpacePress = 0;
}
}
}
}
}
What's Happening Gif, clearly in the gif I am pressing space twice, but it is only printing the number of spaces pressed by one. If the player is on the ground the number of spaces pressed is reset, but the gif also shows that the player is not touching the ground. Why is the space bar not being registered when pressed?
What was happening was a hit was occurring just after the space bar was pressed, which reset the variable counting the number of spaces pressed.
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour
{
public float jumpPower = 2f;
[SerializeField]
public bool isGrounded = true;
[SerializeField]
private LayerMask groundLayer, waterLayer;
private int numSpacePress = 0;
private Rigidbody2D rb;
// Ground Checker Stuff
public Transform groundChecker;
public float groundCheckRadius = 0.1f;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
Collider2D[] hits = Physics2D.OverlapCircleAll(groundChecker.position, groundCheckRadius);
foreach (Collider2D hit in hits)
{
if (hit.gameObject != gameObject)
{
Debug.Log("Hit = " + hit.gameObject.name);
if (((1 << hit.GetComponent<Collider2D>().gameObject.layer) & groundLayer) != 0)
{
isGrounded = true;
numSpacePress = 0;
}
}
}
if (Input.GetKeyDown(KeyCode.Space) && isGrounded && numSpacePress < 2)
{
numSpacePress++;
Debug.Log("Num spaces pressed = " + numSpacePress);
rb.velocity = new Vector2(rb.velocity.x, jumpPower);
if (numSpacePress >= 2)
{
isGrounded = false;
}
}
}
}