Change unity input to crossplatform input - c#

This is the code i have coded through the online tutorial it is a normal swiping input but i want to change it to cross-platform input. I have no idea how to change it hope you guys can help me out
if (Input.touchCount == 1)
{
if (isSwipping)
{
Vector2 diff = Input.GetTouch(0).position - startingTouch;
diff = new Vector2(diff.x / Screen.width, diff.y /
Screen.width);
if (diff.magnitude > 0.01f)
{
if (Mathf.Abs(diff.y) > Mathf.Abs(diff.x))
{
if (diff.y < 0)
{
Slide();
}
else
{
Jump();
}
}
else
{
if (diff.x < 0)
{
ChangeLane(-1);
}
else
{
ChangeLane(1);
}
}
isSwipping = false;
}
}
if (Input.GetTouch(0).phase == TouchPhase.Began)
{
startingTouch = Input.GetTouch(0).position;
isSwipping = true;
}
else if (Input.GetTouch(0).phase == TouchPhase.Ended)
{
isSwipping = false;
}
}

Related

Remove sudden animation change

I have the following code which works very well. I mean... pretty well. The only problem, is when the animation state switches, it's very edgy and sudden, and it doesn't look natural AT ALL. Does anyone know how I can fix that? Thank you in advance!!!
//this runs in Update()
if (Input.GetKey(KeyCode.Space) || jumped) {
if (!characterController.isGrounded)
jumped = true;
else
jumped = false;
if (jumped) {
animator.Play("jump");
return;
}
}
if (characterController.velocity == Vector3.zero) {
animator.Play("idle");
if (!weaponEquipped && !switchingWeapon)
animator.Play("idleArms", 1);
return;
} else if (Input.GetKey("a")) {
if (isRunning && !vitals.isEmpty("stamina")) {
animator.Play("runLeft");
return;
}
animator.Play("walkLeft");
return;
}
if (Input.GetKey("d")) {
if (isRunning && !vitals.isEmpty("stamina")) {
animator.Play("runRight");
return;
}
animator.Play("walkRight");
return;
} else if (Input.GetKey("s")) {
if (isRunning && !vitals.isEmpty("stamina")) {
animator.Play("runBack");
if (!weaponEquipped && !switchingWeapon)
animator.Play("runBackArms", 1);
return;
}
animator.Play("walkBack");
if (!weaponEquipped && !switchingWeapon)
animator.Play("walkBackArms", 1);
return;
} else if (isRunning && !vitals.isEmpty("stamina")) {
animator.Play("run");
if (!weaponEquipped && !switchingWeapon)
animator.Play("runArms", 1);
return;
} else {
animator.Play("walk");
if (!weaponEquipped && !switchingWeapon)
animator.Play("walkArms", 1);
} if (!isRunning && characterController.velocity.magnitude > 0) {
animator.Play("walk");
return;
}
What you're looking for is a Blend Tree, which, combined with Animator, smoothly fades between animations, based on the variable that you define. I can't rewrite your whole code and setup your Blend Tree, but here's a starting point:
using UnityEngine;
using System.Collections;
using System.Collections.Generics;
public class YourClass: MonoBehaviour
{
public Animator animator;
float vertical = 0f;
float horizontal = 0f;
void Update()
{
if (Input.GetButtonDown("Jump"))
{
animator.SetTrigger("Jump");
}
else
{
vertical = Input.GetAxis("Vertical");
horizontal = Input.GetAxis("Horizontal");
animator.setFloat("Vertical Movement", vertical);
animator.setFloat("Horizontal Movement", horizontal);
}
}
}

Falling animation when on slopes

I'm pretty new to all of this so sorry for rookie mistakes.
I've built a State Machine that I'm pretty happy with, with just one problem, whenever the player jumps on a slope and keeps running (either up or down) the animation won't switch to running and stays at falling.
private void FixedUpdate()
{
GroundCheck();
if (state != State.hurt)
{
Movement();
DoubleJump();
StateMachine();
}
HurtCheck();
anim.SetInteger("state", (int)state);
}
private void Movement()
{
float hDirection = Input.GetAxis("Horizontal");
//holding down "D" makes the value positive and vice versa
if (hDirection < 0)
{
rb.velocity = new Vector2(-speed, rb.velocity.y);
transform.localScale = new Vector2(-1, 1);
}
else if (hDirection > 0)
{
rb.velocity = new Vector2(speed, rb.velocity.y);
transform.localScale = new Vector2(1, 1);
}
else
{
}
if (Input.GetButtonDown("Jump") && isGrounded == true)
{
Jump();
}
}
private void StateMachine()
{
if(rb.velocity.y > 2f && isGrounded == false)
{
state = State.jumping;
}
if(rb.velocity.y < 2f && isGrounded == false)
{
state = State.falling;
}
if(rb.velocity.y == 0 && Mathf.Abs(rb.velocity.x) > 2f)
{
state = State.running;
}
if(rb.velocity.magnitude == 0)
{
state = State.idle;
}
}
It looks like you intend rb.velocity.y to be greater than 0 when on a slope. But in order to enter the running state you have a condition that rb.velocity.y == 0. If you want to run on a slope, then maybe you should change that condition like this.
if((rb.velocity.y < 2f) && (Mathf.Abs(rb.velocity.x) > 2f))
{
state = State.running;
}

How to find which collider with same tag is touching my character firstly when multiple colliders are touching my character same time

I'm trying to figure out which collider with same tag is touching my character firstly when multiple colliders are touching my character same time.
if (col.transform.gameObject.tag == "enemy") {
hit = true;
rgd.AddForce(new Vector2(0, 2.150f), ForceMode2D.Impulse);
if (transform.position.x-col.transform.gameObject.transform.position.x < 0)
{
rgd.AddForce(-1*rgd.transform.right * 40);
}
else
{
rgd.AddForce(1*rgd.transform.right * 40);
}
if (Mathf.Approximately (angle, 0)) {
Destroy (col.transform.gameObject);
damage = 0;
} else {
damage = 25;
}
enemydamageSound.Play();
}
I solved it by adding a few code.Here is my new code:
private int jumpCount = 0;
if (col.transform.gameObject.tag == "ground")
{
isGround = true;
jumpped = true;
jumpCount = 0;
}
if (col.transform.gameObject.tag == "enemy")
{
hit = true;
if (!isGround && jumpCount == 0)
{
rgd.AddForce(new Vector2(0, 2.150f), ForceMode2D.Impulse);
jumpCount++;
}
if (transform.position.x - col.transform.gameObject.transform.position.x < 0)
{
if (jumpCount == 0)
{
rgd.AddForce(new Vector2(0, 2f), ForceMode2D.Impulse);
}
rgd.AddForce(-1 * rgd.transform.right * 40);
}
else
{
if (jumpCount == 0)
{
rgd.AddForce(new Vector2(0, 2f), ForceMode2D.Impulse);
}
rgd.AddForce(1 * rgd.transform.right * 40);
}
if (Mathf.Approximately(angle, 0))
{
Destroy(col.transform.gameObject);
damage = 0;
}
else
{
damage = 25;
}
enemydamageSound.Play();
}

Function in Unity3d(c#) doesnt work correctly

I try to creacte some buildings in 2d, but it should not be touched with the other buildings.I have a
private GameObject building;
From Update i called function
buildFence(Vector2 nextPos)
where i create new building
And from this function i called function which must return boolean type
public bool canbuild()
{
//Debug.Log(building);
if (building.GetComponent<Rigidbody2D>().IsTouchingLayers(LayerMask.GetMask("Buildings")))
{
building.GetComponent<SpriteRenderer>().color = Color.red;
//Debug.Log("canb=false");
return false;
}
else {
building.GetComponent<SpriteRenderer>().color = Color.green;
return true;
}
}
but this function always return true. If i called the same function from Update,
everything works well.
All code here
void Update()
{
if (mode)
{
if (TEST)
{
if (!UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject())
{
if (Input.GetMouseButtonDown(0) && idBuilding != 0 && buildFlag)
{
buildFlag = false;
startpos = cam.ScreenToWorldPoint(Input.mousePosition);
if (idBuilding != 1)
{
building = (GameObject)Instantiate(buildings[idBuilding - 1], startpos, new Quaternion(0, 0, 0, 0));
building.GetComponent<Collider2D>().isTrigger = true;
canbuild();
}
else
{
}
}
if (Input.GetMouseButton(0) && idBuilding != 0)
{
if (idBuilding != 1)
{
Vector2 pos = cam.ScreenToWorldPoint(Input.mousePosition);
building.transform.position = pos;
canbuild();
}
else
{
buildFence(cam.ScreenToWorldPoint(Input.mousePosition));
if (!canbuild())
{
Debug.Log("succes");
}
}
}
if (Input.GetMouseButtonUp(0) && idBuilding != 0)
{
if (canbuild())
{
buildFlag = false;
Vector2 viewportPoint = Camera.main.WorldToViewportPoint(building.transform.position + new Vector3(2, 2, 0));
bAccept.anchorMin = viewportPoint;
bAccept.anchorMax = viewportPoint;
bAccept.gameObject.active = true;
}
else
{
Debug.Log("CantBuild");
Destroy(building);
buildFlag = true;
}
//building.GetComponent<Collider2D>().enabled = true;
}
}
}
else
{
}
}
}
void buildFence(Vector2 nextPos)
{
Vector2 delta = nextPos - startpos;
//Debug.Log("v2" + (nextPos - startpos));
//Debug.Log("v2.angle="+ Vector2.Angle(new Vector2(x, y), (nextPos - startpos)));
//Debug.Log("v2.angle=" +);
if (delta.magnitude >= 2.55 && canBuildNext)
{
if (delta.x < 0)
building = (GameObject)Instantiate(buildings[0], startpos, Quaternion.Euler(0, 0, Vector2.Angle(new Vector2(x, y), (nextPos - startpos))));
else
building = (GameObject)Instantiate(buildings[0], startpos, Quaternion.Euler(0, 0, -Vector2.Angle(new Vector2(x, y), (nextPos - startpos))));
building.GetComponent<Collider2D>().isTrigger = true;
canBuildNext = false;
}
if (!canBuildNext)
{
if (!canbuild(ref building))
{
Debug.Log("HERE");
if (delta.x < 0)
building.transform.rotation = Quaternion.Euler(0, 0, Vector2.Angle(new Vector2(x, y), (nextPos - startpos)));
else
building.transform.rotation = Quaternion.Euler(0, 0, -Vector2.Angle(new Vector2(x, y), (nextPos - startpos)));
}
else
{
startpos = nextPos;
//building.GetComponent<Collider2D>().isTrigger = false;
Zabor.Push(building);
canBuildNext = true;
}
}
}
public bool canbuild()
{
//Debug.Log(b);
//Debug.Log(building);
if (building.GetComponent<Rigidbody2D>().IsTouchingLayers(LayerMask.GetMask("Buildings")))
{
building.GetComponent<SpriteRenderer>().color = Color.red;
//Debug.Log("canb=false");
buildfail = false;
return false;
}
else {
building.GetComponent<SpriteRenderer>().color = Color.green;
buildfail = true;
return true;
}
}

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

Categories