Unity Swipe Inputs - c#

I wrote a method for objectCreation at random places in the scene. I want this to happen in my game when a player Swipes the Screen. I am using the following code
void Start(){
StartCoroutine (SwipeInput ());
}
void Update(){
if (Swiped) {
if (Direction == Vector2.up) {
RandomObjects ();
} else if (Direction == Vector2.right) {
RandomObjects ();
} else if (Direction == -1 * Vector2.up) {
RandomObjects ();
} else if (Direction == -1 * Vector2.right) {
RandomObjects ();
}
}
}
IEnumerator SwipeInput ()
{
while(true){
if (Input.touchCount > 0) {
Touch t = Input.GetTouch (0);
Swiped = false;
Vector2 initial = t.position;
yield return new WaitForSeconds (0.5f);
Direction = (t.position - initial).normalised;
Swiped = true;
yield return new WaitForSeconds (0.5f);
} else {
Swiped = false;
}
}
}
But the game is not working with while(true) in Coroutine. Thanks.

You should write "normaliZed" instead of "normaliSed"

Related

How to add the animations in my script in unity "C#"?

I'm new to C#, I'm making a game to learn.
Can anyone help me, I found some scripts on the web for my player. I tried to make animations for it and I used the "Bool", but sometimes when the player starts to walk it doesn't get animated. What can I do?
I added the flip to flip the player left and right. And I added the "If" with the SetBool for the transition from "Idle" to "IsWalking".
Screenshot of my animator
My player has 4 scripts.
The other 3 are in the following link: [Link] (https://drive.google.com/drive/folders/1F_zbQJgihv82zjg5pcQ9L_dp0sgA2O2Q?usp=sharing)
using UnityEngine;
using System.Collections;
[RequireComponent (typeof (Player))]
public class PlayerInput : MonoBehaviour {
private Animator anim;
private bool m_FacingRight = true;
void Start () {
player = GetComponent<Player> ();
anim = GetComponent<Animator>();
}
void Update () {
Vector2 directionalInput = new Vector2 (Input.GetAxisRaw ("Horizontal"), Input.GetAxisRaw ("Vertical"));
player.SetDirectionalInput (directionalInput);
if (Input.GetAxisRaw("Horizontal") > 0 && !m_FacingRight)
{
Flip();
anim.SetBool("IsWalking", true);
}
if (Input.GetAxisRaw("Horizontal") < 0 && m_FacingRight)
{
Flip();
anim.SetBool("IsWalking", true);
}
if (Input.GetAxisRaw("Horizontal") == 0 && !m_FacingRight)
{
anim.SetBool("IsWalking", false);
}
if (Input.GetAxisRaw("Horizontal") == 0 && m_FacingRight)
{
anim.SetBool("IsWalking", false);
}
if (Input.GetKeyDown (KeyCode.Space)) {
player.OnJumpInputDown ();
anim.SetBool("IsJumping", true);
}
if (Input.GetKeyUp (KeyCode.Space)) {
player.OnJumpInputUp ();
anim.SetBool("IsJumping", false);
}
}
private void Flip()
{
// Switch the way the player is labelled as facing.
m_FacingRight = !m_FacingRight;
// Multiply the player's x local scale by -1.
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerInput : MonoBehaviour
{
private Animator anim;
private bool _right ;
private bool _left ;
public float MoveSpeed;
void Start()
{
anim = GetComponent<Animator>();
player = GetComponent<Player> ();
}
void Update()
{
Vector2 directionalInput = new Vector2(Input.GetAxisRaw("Horizontal")*Time.deltaTime, Input.GetAxisRaw("Vertical") * Time.deltaTime);
player.SetDirectionalInput (directionalInput);
if (Input.GetAxisRaw("Horizontal") > 0)
{
TurnRight();
anim.SetBool("IsWalking", true);
}
if (Input.GetAxisRaw("Horizontal") < 0)
{
TurnLeft();
anim.SetBool("IsWalking", true);
}
if (Input.GetAxisRaw("Horizontal") == 0)
{
anim.SetBool("IsWalking", false);
}
if (Input.GetKeyDown (KeyCode.Space)) {
player.OnJumpInputDown ();
anim.SetBool("IsJumping", true);
}
if (Input.GetKeyUp (KeyCode.Space)) {
player.OnJumpInputUp ();
anim.SetBool("IsJumping", false);
}
}
public void TurnRight()
{
if (_right) return;
transform.localScale = new Vector3(Mathf.Abs(transform.localScale.x), transform.localScale.y, 0);
_right = true;
_left = false;
}
public void TurnLeft()
{
if (_left) return;
transform.localScale = new Vector3(-transform.localScale.x, transform.localScale.y, 0);
_left = true;
_right = false;
}
}
there is some problems in your script.
For Example Once I start moving right, m_FacingRight will be true, and then I stop moving. Still, m_FacingRight is true. Since m_FacingRight is still true, if I start moving to the right again, the animation of walk will not play. Because you have used
if (Input.GetAxisRaw("Horizontal") > 0 && !m_FacingRight)
Same for the left side

How and where in the code should I use the loop bool flag to decide if to loop or to make once movement between the waypoints?

The goal is to be able to decide if to loop or to move only once between the waypoints.
I added the loop bool flag for that.
Added the most details I can.
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.AI;
public class Move : MonoBehaviour
{
public Transform[] targets;
public LineRenderer lineRenderer;
public float speed;
public bool go = false;
public bool countOrigPosAsWaypoint = true;
public bool startFromFirstPositionOnStart = false;
public bool goForward = true;
public bool loop = true;
private List<Vector3> pos = new List<Vector3>();
private List<Vector3> positions = new List<Vector3>();
private int index = 0;
private List<GameObject> objectsToMoveCopy = new List<GameObject>();
// Start is called before the first frame update
void Start()
{
if (lineRenderer != null)
{
pos = GetLinePointsInWorldSpace();
}
else
{
if (countOrigPosAsWaypoint == true)
{
pos.Add(transform.position);
}
for (int i = 0; i < targets.Length; i++)
{
pos.Add(targets[i].position);
}
}
if (startFromFirstPositionOnStart == true)
{
transform.position = pos[index];
}
if (pos.Count <= 1)
{
Debug.LogWarning("Targets list count must be more then 1");
}
}
List<Vector3> GetLinePointsInWorldSpace()
{
positions = new Vector3[lineRenderer.positionCount].ToList();
//Get the positions which are shown in the inspector
lineRenderer.GetPositions(positions.ToArray());
//the points returned are in world space
return positions;
}
// Update is called once per frame
void Update()
{
if (go == true && pos.Count > 1)
{
Moving();
}
}
void Moving()
{
Vector3 newPos = transform.position;
float distanceToTravel = speed * Time.deltaTime;
bool stillTraveling = true;
while (stillTraveling)
{
Vector3 oldPos = newPos;
newPos = Vector3.MoveTowards(oldPos, pos[index], distanceToTravel);
distanceToTravel -= Vector3.Distance(newPos, oldPos);
if (newPos == pos[index]) // Vector3 comparison is approximate so this is ok
{
// when you hit a waypoint:
if (goForward)
{
bool atLastOne = index >= pos.Count - 1;
if (!atLastOne) index++;
else { index--; goForward = false; }
}
else
{ // going backwards:
bool atFirstOne = index <= 0;
if (!atFirstOne) index--;
else { index++; goForward = true; }
}
}
else
{
stillTraveling = false;
}
}
transform.position = newPos;
}
}
If true make a loop between the waypoints either backward or forward and if false just move forward or backward once and stop the last/first waypoint.
I'ld say e.g. at
if (!atLastOne)
{
index++;
}
else if(!loop)
{
stillTraveling = false;
}
else
{
index--;
goForward = false;
}
and accordingly
if (!atFirstOne)
{
index--;
}
else if(!loop)
{
stillTraveling = false;
}
else
{
index++;
goForward = true;
}
And probably remove the current
else
{
stillTraveling = false;
}
as it will be the case most of the time between the points.
In general though: Currently this will all happen in one single frame without any animation... This should probably rather happen in a Coroutine or only do one step at a time .. not in a while loop at all.

Ladder climbing function in C# script for Unity won't allow the character to come off the ladder

I created a function in Unity that is supposed to allow the character to climb. It creates two problems, first of all it somehow interacts with the general movement function. When the character starts running their animation won't stop even when the player isn't moving them. Second of all the character can climb up and down the ladder but won't get off them, even though technically the logic is constructed in such a way that they should just go back to their normal state.
I have tried turning off the climb function in the Update() function so I know the running problem is caused by it, because it works fine without it.
private void Climb()
{
RaycastHit2D ladder = Physics2D.Raycast(transform.position, Vector2.up, 5, whatIsLadder);
float hDirection = Input.GetAxisRaw("Horizontal");
float vDirection = Input.GetAxisRaw("Vertical");
if (ladder.collider != null)
{
if (vDirection > 0.1f)
{
isClimbing = true;
}
}
else
{
if (hDirection > 0.1f)
{
isClimbing = false;
}
}
if (isClimbing == true && ladder.collider != null)
{
rb.gravityScale = 0;
rb.velocity = new Vector2(rb.velocity.x, climbSpeed * vDirection);
if (Mathf.Abs(vDirection) > 0.1f)
{
anim.speed = 1f;
}
else
{
anim.speed = 0f;
}
}
else
{
rb.gravityScale = naturalGravity;
}
}
I'll also give a link to the whole PlayerController script since that might help some people:
https://github.com/Pacal2/Platformer/blob/master/Assets/Scripts/PlayerController.cs
Try resetting the velocity on the rigidbody when he stops climbing, near the end of the function:
//....
{
rb.gravityScale = naturalGravity;
}
into:
{
rb.gravityScale = naturalGravity;
rb.velocity = new Vector2(0.0f, 0.0f);
}
this code also looks suspect
if (ladder.collider != null)
{
if (vDirection > 0.1f)
{
isClimbing = true;
}
}
else
{
if (hDirection > 0.1f)
{
isClimbing = false;
}
}
change to:
if (ladder.collider != null)
{
if (vDirection > 0.1f || vDirection < -0.1f) //if allowed to climb down
{
isClimbing = true;
}
if (hDirection > 0.1f || hDirection < -0.1f) //moving left
{
isClimbing = false;
}
}
for animation speed try:
anim.speed = rb.velocity.x;

Unity3d Touch Swipe

If a player touch he jump and on swipe (left - right simply moves from left to right .. like any runner).
Everything seems good but as always there is a BUT
Here's the code:
Vector3 startPos;
float minSwipeDistX, minSwipeDistY;
bool isJump = false;
void Start()
{
minSwipeDistX = minSwipeDistY = Screen.width / 6;
}
bool isSwipe = false;
bool isTouch = false;
void Update()
{
if (Input.touchCount > 0)
{
Touch touch = Input.touches[0];
switch (touch.phase)
{
case TouchPhase.Began:
startPos = touch.position;
break;
case TouchPhase.Moved:
isTouch = true;
float swipeDistHorizontal = (new Vector3(touch.position.x, 0, 0) - new Vector3(startPos.x, 0, 0)).magnitude;
float swipeDistVertical = (new Vector3(0, touch.position.y, 0) - new Vector3(0, startPos.y, 0)).magnitude;
if (swipeDistHorizontal > minSwipeDistX)
{
float swipeValue = Mathf.Sign(touch.position.x - startPos.x);
if (swipeValue > 0 && !isSwipe)//to right swipe
{
isTouch = false;
isSwipe = true;
Debug.Log("Right");
}
else if (swipeValue < 0 && !isSwipe)//to left swipe
{
isTouch = false;
isSwipe = true;
Debug.Log("Left");
}
}
// add swipe to up
if (swipeDistVertical > minSwipeDistY)
{
float swipeValueY = Mathf.Sign(touch.position.y - startPos.y);
if (swipeValueY > 0 && !isSwipe)
{
isTouch = false;
isSwipe = true;
Debug.Log("Up");
}
}
break;
case TouchPhase.Stationary:
isJump = true;
break;
case TouchPhase.Ended:
case TouchPhase.Canceled:
isTouch = false;
isSwipe = false;
break;
}
}
}
void FixedUpdate()
{
if (isJump && !isTouch)
{
Debug.Log("Tap");
isJump = false;
}
}
When doing a simple touch (TouchPhase.Stationary) immediately reacts to the player jump.
And when do Jump Swipe UP then jump player when I let go of the finger. I understand it all through what I use (TouchPhase.Ended).
I tried to put TouchPhase.Moved but then all the time before the motion and use jump (TouchPhase.Stationary).
Mauger who faced such a problem?
If so then tell me how to do so was to touch and swipe swipe touch.
This my code:
void Update()
{
#if UNITY_ANDROID || UNITY_IPHONE
if (Input.touchCount > 0)
{
Touch touch = Input.touches[0];
switch (touch.phase)
{
case TouchPhase.Began:
startPos = touch.position;
StartCoroutine(Jump());
break;
case TouchPhase.Moved:
isSwipe = true;
float swipeDistHorizontal = (new Vector3(touch.position.x, 0, 0) - new Vector3(startPos.x, 0, 0)).magnitude;
float swipeDistVertical = (new Vector3(0, touch.position.y, 0) - new Vector3(0, startPos.y, 0)).magnitude;
if (swipeDistHorizontal > minSwipeDistX)
{
float swipeValue = Mathf.Sign(touch.position.x - startPos.x);
if (swipeValue > 0 && !isTouch)//to right swipe
{
isTouch = true;
StartCoroutine(Right());
}
else if (swipeValue < 0 && !isTouch)//to left swipe
{
isTouch = true;
StartCoroutine(Left());
}
}
//add swipe to up
if(swipeDistVertical > minSwipeDistY)
{
float swipeValue = Mathf.Sign(touch.position.y - startPos.y);
if(swipeValue > 0 && !isTouch)
{
isTouch = true;
StartCoroutine(Jump2());
}
}
break;
case TouchPhase.Ended:
isSwipe = false;
isTouch = false;
break;
}
}
#endif
}
IEnumerator Jump2()
{
yield return new WaitForSeconds(0.05f);
if(playerVelocity <= 0.2f)
{
Debug.Log("Swipe Up");
}
}
IEnumerator Jump()
{
if (!isSwipe)
{
yield return new WaitForSeconds(0.05f);
if (!isSwipe && playerVelocity <= 0.2f)
{
Debug.Log("Tap");
}
else
{
yield break;
}
}
else
{
yield break;
}
}
IEnumerator Right()
{
Debug.Log("Right");
}
IEnumerator Left()
{
Debug.Log("Left");
}
I came up with that :
It should put you in the proper direction
float validInputThresold = 5f;
enum Gestures {
None,
Stationary,
SwipeRight,
SwipeLeft,
SwipeUp,
SwipeDown
}
Gestures currentGesture;
public void Update() {
currentGesture = Gestures.None;
HandleTouch(Input.GetTouch(0));
HandleCharacterMovement(currentGesture);
}
Vector3 originalPosition;
void HandleTouch(Touch touch) {
if (touch == null) return;
switch (touch.phase) {
case TouchPhase.Began:
originalPosition = touch.position;
break;
case TouchPhase.Moved:
Vector3 delta = touch.position - originalPosition;
if (delta.magnitude > validInputThresold) Moved(touch, delta);
break;
case TouchPhase.Stationary:
currentGesture = Gestures.Stationary;
break;
case TouchPhase.Ended:
case TouchPhase.Canceled:
currentGesture = Gestures.None;
break;
}
}
public float gestureThresold = 10f;
void Moved(Touch touch, Vector3 delta) {
if ((Mathf.Abs(delta.x)<=gestureThresold && Mathf.Abs(delta.y)<=gestureThresold)
|| (Mathf.Abs(delta.x)>gestureThresold && Mathf.Abs(delta.y)>gestureThresold) )
currentGesture = Gestures.Stationary; //IF FINGER MOVED IN DIAGONAL, INVALID STATE FALLSBACK TO STATIONARY
else if (delta.x > gestureThresold) currentGesture = Gestures.SwipeRight;
else if (delta.x < -gestureThresold) currentGesture = Gestures.SwipeLeft;
else if (delta.y > gestureThresold) currentGesture = Gestures.SwipeUp;
else if (delta.y < -gestureThresold) currentGesture = Gestures.SwipeDown;
}
bool playerIsMoving = false;
// ALL THE ROUTINES HERE SET THE PLAYER IS MOVING FLAG
// TO TRUE AND THEN TO FALSE WHEN THE MOVEMENT IS DONE
void HandleCharacterMovement(Gestures gesture) {
if (playerIsMoving) return;
switch (gesture) {
default:
case Gestures.None:
case Gestures.Stationary:
return;
case Gestures.SwipeRight:
StartCoroutine(MovePlayerRight());
return;
case Gestures.SwipeLeft:
StartCoroutine(MovePlayerLeft());
return;
case Gestures.SwipeUp:
StartCoroutine(Jump());
return;
case Gestures.SwipeDown:
StartCoroutine(Crouch());
return;
}
}
Not sure it is valid, did it by head. feel free to correct it.
The idea behind that :
Find the finger
If any and it is moving get the delta
if delta is over certain amount validate it
if valid assign a gesture state that you can track
process player movement accordingly if player is not already moving

Switching between sprites in Unity

I've been working on a game in unity for a school project. Currently I'm trying to make a countdown before my game starts. I'm sure this is basic knowledge but I'm fairly new to Unity.
This is my Script:
using UnityEngine;
using System.Collections;
public class StartScreen : MonoBehaviour {
static bool sawOnce = false;
// Use this for initialization
void Start () {
if(!sawOnce) {
GetComponent<SpriteRenderer>().enabled = true;
Time.timeScale = 0;
}
sawOnce = true;
}
// Update is called once per frame
void Update () {
if(Time.timeScale==0 && (Input.GetKeyDown(KeyCode.Space) || Input.GetMouseButtonDown(0)) ) {
Time.timeScale = 1;
GetComponent<SpriteRenderer>().enabled = false;
}
}
}
I want to change between three different sprites before "Time.timeScale = 1;" and after "GetComponent().enabled = false;". Each sprite should just show for a second before the next one shows up.
You should create a new function with a wait statement.
Something like this would work.
void Update () {
if(Time.timeScale==0 && (Input.GetKeyDown(KeyCode.Space) || Input.GetMouseButtonDown(0)) ) {
Time.timeScale = 1;
changeSprites();
GetComponent<SpriteRenderer>().enabled = false;
}
}
IEnumerator changeSprites(){
GetComponent<SpriteRenderer>().sprite = SPRITE1
yield return new WaitForSeconds(1);
GetComponent<SpriteRenderer>().sprite = SPRITE2
yield return new WaitForSeconds(1);
GetComponent<SpriteRenderer>().sprite = SPRITE3
yield return new WaitForSeconds(1);
}
}

Categories