How to create Unity 2D enemy AI varying directional Animation? - c#

So basically what i am trying to do is create an animation script that does not just take simple direction like Up(0,1),Down(0,-1),Left(-1,0),Right(1,0)(Those numbers being vectors) but to have range of directions for to fill in the gap between those directions and play the more dominant direction Up,Down,Left,Right.
So each quarter section below to be set to an animation.
I have created a few scripts to try and achieve this i came up with one that wasn't perfect but it did work when dragging the enemies around in the scene editor while the game was running. When using their movements scripts for their movement it did not work. The animation script is below and underneath that how i move the enemies.
Below would be how i calculate the direction the enemy was moving:
IEnumerator directionFinder()
{
// while (true)
//{
Vector3 previousPosition = transform.position;
yield return new WaitForSeconds(1/10);
currentPosition = transform.position;
currentPosition.x = currentPosition.x - previousPosition.x;
currentPosition.y = currentPosition.y - previousPosition.y;
currentPosition.z = 0f;
angle = (Mathf.Atan2(currentPosition.y, currentPosition.x) * Mathf.Rad2Deg);
if(angle < 0)
{
angle = Mathf.Abs(angle) + 180;
}
// }
}
Then this is what calculated which animation to use:
void animationDirection()
{
if (angle == 0)
{
anim.SetInteger("Move", currentAnim);
}
if (angle > 45 && angle <135)//W
{
anim.SetInteger("Move", 1);
currentAnim = 1;
}
else if (angle > 135 && angle < 225)//A
{
anim.SetInteger("Move", 2);
currentAnim = 2;
}
else if (angle > 225 && angle < 315)//S
{
anim.SetInteger("Move", 3);
currentAnim = 3;
}
else if((angle < 45 && angle >= 0) || (angle > 315 && angle <= 0))//D
{
anim.SetInteger("Move", 4);
currentAnim = 4;
}
}
This using the code below it would move to the waypoint that was selected via the rest of my code that would just loop through a set of waypoints changing the waypoint when it arrived at one.
transform.position = Vector2.MoveTowards(transform.position, waypoints[waypointNUmber].transform.position, speed * Time.deltaTime);
Below I tried another way but it did not work and created weird buggy animations:
IEnumerator directionalAnimation()
{
while (true)
{
Debug.Log("working");
Vector2 previousPosition = transform.position;
yield return new WaitForSeconds(1/10);
Vector2 currentPosition = transform.position;
Vector2 direction = (previousPosition - currentPosition).normalized;
float moveX = direction.x;
float moveY = direction.y;
if (moveX < 0)
{
moveXNegative = true;
moveX = Mathf.Abs(moveX);
}
if (moveY < 0)
{
moveYNegative = true;
moveY = Mathf.Abs(moveY);
}
if (direction.magnitude != 0)
{
if (moveX > moveY)
{
if (moveXNegative)
{
//left
Walking = true;
anim.SetInteger("Move", 2);
moveYNegative = false;
}
else
{
//Right
Walking = true;
anim.SetInteger("Move", 4);
moveYNegative = false;
}
}
else if (moveY > moveX)
{
if (moveYNegative)
{
//Down
Walking = true;
anim.SetInteger("Move", 3);
}
else
{
//Up
Walking = true;
anim.SetInteger("Move", 1);
}
}
}
else
{
source.Pause();
Walking = false;
}
if (Walking)
{
source.UnPause();
}
}
}

Related

Slope code not working with movement code

I was coding movement code for my game using this video: Movement code video.
Pardon my garbage code...
void Move(float dir,bool crouchFlag)
{
if(!crouchFlag)
{
if(Physics2D.OverlapCircle(OverheadChecker.position,CelingCirSize,gLayerMask))
{
crouchFlag = true;
}
}
Stand.enabled = !crouchFlag;
Stand2.enabled = !crouchFlag;
Croucher.enabled = crouchFlag;
#region Move & run
if (isGrounded && !crouchFlag && !isOnSlope)
{
Controller.XMove(dir,Speed,rb2d,velPower,acceleration,decceleration);
} else if (isGrounded && isOnSlope && canWalkOnSlope)
{
float TargetSpeed = -dir * Speed;
float TargetSpeedDif = TargetSpeed - rb2d.velocity.x;
float accelerRate = (Mathf.Abs(TargetSpeed) > 0.01f) ? airacceleration : airdecceleration;
float MoveDir = Mathf.Pow(Mathf.Abs(TargetSpeedDif) * accelerRate, velPower) * Mathf.Sign(TargetSpeedDif);
float MoveDirX = MoveDir * slopeNormalPerp.x * MultSlope;
float MoveDirY = MoveDir * slopeNormalPerp.y * MultSlope;
rb2d.AddForce(MoveDirX * Vector2.right);
rb2d.AddForce(MoveDirY * Vector2.up);
}
else if (!isGrounded)
{
float TargetSpeed = dir * Speed;
float TargetSpeedDif = TargetSpeed - rb2d.velocity.x;
float accelerRate = (Mathf.Abs(TargetSpeed) > 0.01f) ? airacceleration : airdecceleration;
float MoveDir = Mathf.Pow(Mathf.Abs(TargetSpeedDif) * accelerRate, velPower) * Mathf.Sign(TargetSpeedDif);
if (rb2d.velocity.y > 0 && !Input.GetButton("Jump"))
{
MoveDir = MoveDir * xJumpForce;
}
rb2d.AddForce(MoveDir * Vector2.right);
}else if (isGrounded && crouchFlag)
{
rb2d.sharedMaterial = noFriction;
float TargetSpeed = dir * CrouchSpeed;
float TargetSpeedDif = TargetSpeed - rb2d.velocity.x;
float accelerRate = (Mathf.Abs(TargetSpeed) > 0.01f) ? acceleration : Crouchdecceleration;
float MoveDir = Mathf.Pow(Mathf.Abs(TargetSpeedDif) * accelerRate, velPower) * Mathf.Sign(TargetSpeedDif);
rb2d.AddForce(MoveDir * Vector2.right);
}
if (isGrounded && Mathf.Abs(HorizontalValue) < 0.01f)
{
float amount = Mathf.Min(Mathf.Abs(rb2d.velocity.x), Mathf.Abs(fricAmount));
amount *= Mathf.Sign(rb2d.velocity.x);
rb2d.AddForce(Vector2.right * -amount, ForceMode2D.Impulse);
}
Vector3 CurrentScale = transform.localScale;
if(Right && dir > 0)
{
transform.localScale = new Vector3(1.4f, 1.4f
, 1);
Right = false;
}
else if (!Right == dir < 0)
{
transform.localScale = new Vector3(-1.4f, 1.4f, 1);
Right = true;
}
#endregion
}
Then I made slopes using a Sprite Shape Controller:
But, the character got stuck on the slopes when going up them, so I used this video for slopes:Fixing slopes video
Irrelevant code is removed:
private void SlopeCheck()
{
checkPos = transform.position - (Vector3)(new Vector2(0.0f, colliderSize.y / 2));
SlopeCheckHorizontal(checkPos);
SlopeCheckVertical(checkPos);
}
private void SlopeCheckHorizontal(Vector2 checkPos)
{
RaycastHit2D slopeHitFront = Physics2D.Raycast(checkPos, transform.right, slopeCheckDistance, gLayerMask);
RaycastHit2D slopeHitBack = Physics2D.Raycast(checkPos, -transform.right, slopeCheckDistance, gLayerMask);
if (slopeHitFront)
{
isOnSlope = true;
slopeSideAngle = Vector2.Angle(slopeHitFront.normal, Vector2.up);
}
else if (slopeHitBack)
{
isOnSlope = true;
slopeSideAngle = Vector2.Angle(slopeHitBack.normal, Vector2.up);
}
else
{
slopeSideAngle = 0.0f;
isOnSlope = false;
}
}
private void SlopeCheckVertical(Vector2 checkPos)
{
RaycastHit2D hit = Physics2D.Raycast(checkPos, Vector2.down, slopeCheckDistance, gLayerMask);
if (hit)
{
slopeNormalPerp = Vector2.Perpendicular(hit.normal).normalized;
slopeDownAngle = Vector2.Angle(hit.normal, Vector2.up);
if(slopeDownAngle != lastSlopeAngle)
{
isOnSlope = true;
}
lastSlopeAngle = slopeDownAngle;
Debug.DrawRay(hit.point, slopeNormalPerp, Color.blue);
Debug.DrawRay(hit.point, hit.normal, Color.green);
}
if (slopeDownAngle > maxSlopeAngle || slopeSideAngle > maxSlopeAngle)
{
canWalkOnSlope = false;
}
else
{
canWalkOnSlope = true;
}
if (isOnSlope && canWalkOnSlope && HorizontalValue == 0.0f)
{
rb2d.sharedMaterial = fullFriction;
}
else
{
rb2d.sharedMaterial = noFriction;
}
}
void Update()
{
if(slopeDownAngle != 0)
{
isOnSlope = true;
} else {
isOnSlope = false;
}
if (CanMove() == true){
HorizontalValue = Input.GetAxisRaw("Horizontal");
}
}
void FixedUpdate()
{
Gcheck();
Move(HorizontalValue, Crouch);
SlopeCheck();
}
Rigidbody>
Mass:0.5
BodyType: Dynamic
LinearDrag: 0
AngularDrag: 0
Gravity: 11
FreezeRotation: Only Z axis
::Friction Is Handled In The Movement Code::
But, when I finished the character got stuck again,
so I tried multiplying the slopeNormalPerp by a variable(MultSlope) and he just bounced up and down if made made it too high and if it was too low nothing happened.
I tried messing with varibles such as the ground-checking circles size, various colliders, the aforementioned MultSlope ,and slopeCheckDistance...
Nothing Helped...
I've been working on this for 7 months(with breaks working on other code) and I have improved greatly in coding, but I still can't fix it.
I tried messing with every relevant variable, watching the video many time, downloading and copy-pasting the code ,and following other tutorials of the slope code, No Dice.

Unity HingeJoint have weird behavior in autogeneration problem with rotation?

I am a beginner and I have cube in air with element attached him with no rotation like a node, i have a couple cubes for simulate rope with hint joint. I have clicking right click at a cube and spawn rope from direction player to node and attaching last element rope with player and this working very well. When player doesn't have velocity, and blocked rotation on rigidbody elements. But sometimes if I have been jumped and try to spawn rope in moving elements rope have weird rotations, and sometimes cubes rotation blocks. How could I work with rotations rope or I don't know, any advice? Thanks.
PS: sorry for my bad English.
private void CheckMouseActivity()
{
float x = Input.mousePosition.x;
float y = Input.mousePosition.y;
float z = Input.mousePosition.z;
Vector3 point = new Vector3(x, y, z);
if (Input.GetMouseButton(1) && !m_ropeIsActive)
{
m_aiming = true;
Ray ray = Camera.main.ScreenPointToRay(point);
GenerateRope(ray);
}
if (Input.GetButton("Jump") && m_ropeIsActive)
{
for (int i = 0; i < rope.Count; i++)
{
DestroyImmediate(rope[i]);
//rope[i].active = false;
}
playerRb.AddForce(new Vector3(6f, 6f), ForceMode.Impulse);
m_ropeIsActive = false;
m_hooked = false;
}
// check bounds in playing area
}
void GenerateRope(Ray ray)
{
layerMask = ~layerMask;
if (Physics.Raycast(ray, out RaycastHit hit, 10f, layerMask))
{
if (hit.transform.CompareTag("node") && !m_ropeIsActive)
{
activeHook = hit.transform.gameObject;
m_CanMove = false;
Vector3 hitPos = hit.transform.position;
Transform hook = hit.transform.GetChild(0);
Vector3 hookInverseNormal = hook.up * -1f;
Rigidbody previosRb = hit.transform.GetChild(0).GetComponent<Rigidbody>();//hook
Vector3 distanceFromNode = transform.position - hit.point;
int distance = (int)distanceFromNode.magnitude;
BoxCollider link = linkPrefub.GetComponent<BoxCollider>();
int length = (int)((distance - 1f) / sizeCell);
float ropeLength = sizeCell * 10f;
if (length < minLength)
{
length = minLength;
}
//else if (length > ropeLength)
//{
// length = (int)ropeLength * 2;
//}
for (int i = 1; i < length - 1; i++)
{
var t = sizeCell * i; //позиция под новый куб
Vector3 dirToPlayer = transform.position - hit.transform.position;
Vector3 newPos = dirToPlayer.normalized * t;
GameObject toInstantiate = Instantiate(linkPrefub, hit.transform.position + new
Vector3(newPos.x, -t, default), Quaternion.identity, hit.transform);
rope.Add(toInstantiate);
HingeJoint joint = toInstantiate.GetComponent<HingeJoint>();
if (i == 1)
{
joint.autoConfigureConnectedAnchor = true;
}
else
{
joint.autoConfigureConnectedAnchor = false;
joint.connectedAnchor = new Vector3(0f, -0.4f);
}
joint.enableCollision = false;
joint.connectedBody = previosRb;
previosRb = toInstantiate.GetComponent<Rigidbody>();
}
m_ropeIsActive = true;
m_hooked = true;
m_CanMove = true;
}
}
else
{
// what to do if not did hit
}
}
void FixedUpdate()
{
if (m_ropeIsActive)
{
if (m_hooked && activeHook)
{
//TODO крутить нод хука чтобы выглядило красиво
}
if (rope.Count != 0)
{
Rigidbody lastElementRope = rope[rope.Count - 1].GetComponent<Rigidbody>();
if (lastElementRope)
{
HingeJoint joint = GetComponent<HingeJoint>();
//joint.autoConfigureConnectedAnchor = false;
//joint.connectedBody = lastElementRope;
//joint.anchor = Vector2.zero;
//joint.connectedAnchor = new Vector2(0f, -0.4f);
}
}
}
}
Can put code from github with project.
I experimented here trying to achieve obedience, but I am convinced that this is the wrong direction, I just do not know how to work with rotations, I got confused
if (i == 1)
{
joint.autoConfigureConnectedAnchor = true;
}
else
{
joint.autoConfigureConnectedAnchor = false;
joint.connectedAnchor = new Vector3(0f, -0.4f);
}
GitHub https://github.com/Heges/first-2d-platformer/tree/main/2D-platformer
i am not sure but
void GenerateRope(Ray ray)
{
layerMask = ~layerMask;
if (Physics.Raycast(ray, out RaycastHit hit, 10f, layerMask))
{
Vector3 direction = transform.position - hit.transform.position;
if (direction.magnitude <= sizeOfRope)
{
if (hit.transform.CompareTag("node") && !m_ropeIsActive)
{
activeHook = hit.transform.gameObject;
m_CanMove = false;
Transform hook = hit.transform.GetChild(0);
Vector3 hookInverseNormal = hook.up * -1f;
float dot = Vector3.Dot(hookInverseNormal, ray.direction.normalized);
Debug.Log(dot);
Quaternion rotation = hit.transform.rotation;
Rigidbody previosRb = hit.transform.GetChild(0).GetComponent<Rigidbody>();//hook
Vector3 distanceFromNode = transform.position - hit.point;
int distance = (int)distanceFromNode.magnitude;
BoxCollider link = linkPrefub.GetComponent<BoxCollider>();//(int)link.size.magnitude / 2;
int length = (int)((distance - 1f) / sizeCell); //size of cell rope -1f размер игрока
float ropeLength = sizeCell * sizeOfRope;
if (length < minLength)
{
length = minLength;
}
//else if (length > ropeLength) // и слишком длинных
//{
// length = (int)ropeLength * 2;
//}
for (int i = 1; i < length - 1; i++)
{
var t = sizeCell * i; //позиция под новый куб
Vector3 dirToPlayer = transform.position - hit.transform.position;//направление до игрока,
Vector3 newPos = dirToPlayer.normalized * t;
GameObject toInstantiate = Instantiate(linkPrefub, hit.transform.position + new Vector3(newPos.x, -t, default), Quaternion.identity, hit.transform);
rope.Add(toInstantiate);
HingeJoint joint = toInstantiate.GetComponent<HingeJoint>();
joint.anchor = Vector2.up;
joint.connectedAnchor = new Vector2(0f, -0.4f);
joint.connectedBody = previosRb;
previosRb = toInstantiate.GetComponent<Rigidbody>();
}
m_ropeIsActive = true;
m_hooked = true;
}
}
else
{
//what to do if not did hit
}
}
it is still don't work very well but.like my problem is solved.
limited the distance from which the rope can be summoned, and as it turned out, when autogenerating parts of the rope, the Hint Joint defaults to its values ​​such as AutoAnchor. disabling them during creation, it seems that everything seems to work as it should
HingeJoint joint = toInstantiate.GetComponent<HingeJoint>();
joint.anchor = Vector2.up;
joint.connectedAnchor = new Vector2(0f, -0.4f);
joint.connectedBody = previosRb;
previosRb = toInstantiate.GetComponent<Rigidbody>();

Playing animation with swipe controls and transform.position problem Unity

I've set up my swipe controls to transform my player left/right/up/down and I've restricted the movement on 3 lines; -1, 0, 1. Everything works fine but the movement is not smooth at all and the player seems to be "teleporting" from one position to another. I wanted to smooth the movement by playing the animation but the result was that the animation was being played after the player has changed his position.
Is there any way to play the animation while the player is changing his position or a way to smooth the movement so it looks right ?
I've tried everything and now I'm stuck with the problem, please help
Here's my code
public class SwipeControls : MonoBehaviour {
public float speed = 5.0f;
private Vector3 startpos; // start position
private Vector3 endpos; //end position
public int pozioma = 0;
public int pionowa = 0;
Animator anim;
void Start() {
GetComponent<Animator>();
}
void Update() {
foreach (Touch touch in Input.touches) {
Vector3 newPosition;
if (touch.phase == TouchPhase.Began) {
startpos = touch.position;
endpos = touch.position;
}
if (touch.phase == TouchPhase.Moved) {
endpos = touch.position;
}
if (touch.phase == TouchPhase.Ended) {
newPosition = transform.position;
if (Mathf.Abs(startpos.y - endpos.y) > Mathf.Abs(startpos.x - endpos.x)) {
if ((startpos.y - endpos.y) > 100 && pionowa > -1) //swipe down
{
pionowa--;
newPosition.y -= speed;
transform.position = newPosition;
anim.SetTrigger("Flydown");
}
if ((startpos.y - endpos.y) < -100 && pionowa < 1) //swipe up
{
pionowa++;
newPosition.y += speed;
transform.position = newPosition;
anim.SetTrigger("Flyup");
}
}
else {
if ((startpos.x - endpos.x) > 100 && pozioma > -1) //swipe left
{
pozioma--;
newPosition.z -= speed;
transform.position = newPosition;
anim.SetTrigger("Flyleft");
}
}
if ((startpos.x - endpos.x) < -100 && pozioma < 1) //swipe right
{
pozioma++;
newPosition.z += speed;
transform.position = newPosition;
anim.SetTrigger("Flyright");
}
}
}
}
}
Modify your code instead of using just
transform.position = newPosition;
in all position use
transform.position = Vector3.Lerp(transform.position, newPosition, smooth * Time.deltaTime);
where smooth is float variable assign it required value may be 0.5f or whatever you want
Note : What it actually does is that it makes game object to move little based on smooth value, every frame
Note that we do not know your animator setup. If in those animation clips there is anywhere a keyframe for the position then the animator will always overrule anything done by scripts!
Instead of setting the new position immediately you could use a Coroutine with StartCoroutine like (also fixing some coding styles)
public class SwipeControls : MonoBehaviour
{
// Flag for ignoring input until current animation finished
private bool routineRunning;
// Configure in the Inspector distance to swipe
// in unity units
[SerializeField] private float swipeDistance = 5;
// configure this in the Inspector
// How long should the swiping take in seconds
[SerializeField] private float swipeDuration = 1;
private Vector3 _startpos; // start position
private Vector3 _endpos; //end position
public int pozioma = 0;
public int pionowa = 0;
private Animator _anim;
private void Start()
{
GetComponent<Animator>();
}
private void Update()
{
// Ignore any Input while a routine is running
if (routineRunning) return;
foreach (var touch in Input.touches)
{
switch (touch.phase)
{
case TouchPhase.Began:
_startpos = touch.position;
_endpos = touch.position;
break;
case TouchPhase.Moved:
_endpos = touch.position;
break;
case TouchPhase.Ended:
if (Mathf.Abs(_startpos.y - _endpos.y) > Mathf.Abs(_startpos.x - _endpos.x))
{
if (_startpos.y - _endpos.y > 100 && pionowa > -1) //swipe down
{
pionowa--;
StartCoroutine(MoveSmooth(Vector3.up * -1, swipeDuration));
_anim.SetTrigger("Flydown");
}
else if (_startpos.y - _endpos.y < -100 && pionowa < 1) //swipe up
{
pionowa++;
StartCoroutine(MoveSmooth(Vector3.up, swipeDuration));
_anim.SetTrigger("Flyup");
}
}
else
{
if (_startpos.x - _endpos.x > 100 && pozioma > -1) //swipe left
{
pozioma--;
StartCoroutine(MoveSmooth(Vector3.forward * -1, swipeDuration));
_anim.SetTrigger("Flyleft");
}
else if (_startpos.x - _endpos.x < -100 && pozioma < 1) //swipe right
{
pozioma++;
StartCoroutine(MoveSmooth(Vector3.forward, swipeDuration));
_anim.SetTrigger("Flyright");
}
}
break;
}
}
}
private IEnumerator MoveSmooth(Vector3 direction, float duration)
{
routineRunning = true;
var currentPosition = transform.localPosition;
var targetPosition = currentPosition + direction * swipeDistance;
var timePassed = 0f;
do
{
// Additionally add some ease in and out to the movement to get
// even smoother movement
var lerpFactor = Mathf.SmoothStep(0, 1, timePassed / duration);
// Interpolate the position between currentPosition and targetPosition
// using the factor between 0 and 1
transform.localPosition = Vector3.Lerp(currentPosition, targetPosition, lerpFactor);
// increase by time since last frame
timePassed += Time.deltaTime;
// let this frame render and go on from
// here in the next frame
yield return null;
} while (timePassed <= duration);
// To avoid over or undershooting in the end set a fixed value
transform.localPosition = targetPosition;
routineRunning = false;
}
}
I don't know why you are using y+= and z+= .. it seems to me that it meeans the Camera is facing left in your scene e.g. with rotation = 0, -90, 0 and e.g. position = 10, 0, 0 than this should be the result (Note I copied the same code into if(GetMouseButtonDown(0)) etc in order to simulate the touch on the PC.)

How do I move and flip my character in Unity2D?

I am new to Unity. I am playing around with a 2D sidescroller. Here are the features of the script I am trying to write:
Move left and right
Flip character when changing direction
Increase speed to a cap while continuously moving
Currently, the only thing working is Animation transitions. I am not sure what is wrong. Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Avatar_Manager : MonoBehaviour {
private Animator anim;
private Rigidbody2D rigidbody2D;
private Transform trans;
private int direction;
private bool moving;
public const float acceleration = 1.0f / 180;
public float horizontal_speed;
public float vertical_speed;
// Use this for initialization
void Start () {
anim = GetComponent<Animator>();
rigidbody2D = GetComponent<Rigidbody2D>();
trans = GetComponent<Transform>();
//Default facing right
direction = 1;
moving = false;
vertical_speed = 0;
}
// Update is called once per frame
void Update () {
//Check direction
if (rigidbody2D.velocity.x < 0)
{
direction = -1;
}
else if (rigidbody2D.velocity.x > 0)
{
direction = 1;
}
// Move right
if (Input.GetKeyDown(KeyCode.D))
{
//Flip Avatar if facing left
if (direction == -1)
{
direction = 1;
trans.rotation.Set(trans.rotation.x, trans.rotation.y + 180, trans.rotation.z, trans.rotation.w);
}
//Start moving
if (!moving)
{
moving = true;
horizontal_speed = 10;
rigidbody2D.velocity = new Vector2(horizontal_speed, vertical_speed);
anim.SetInteger("State", 1);
}
//Update speed
else
{
if(horizontal_speed < 20)
{
horizontal_speed += acceleration;
rigidbody2D.velocity.Set(horizontal_speed, vertical_speed);
}
}
}
//Stop moving right
if (Input.GetKeyUp(KeyCode.D))
{
moving = false;
horizontal_speed = 0;
rigidbody2D.velocity.Set(horizontal_speed, vertical_speed);
anim.SetInteger("State", 0);
}
// Move left
if (Input.GetKeyDown(KeyCode.A))
{
//Flip Avatar if facing right
if (direction == 1)
{
direction = -1;
trans.rotation.Set(trans.rotation.x, trans.rotation.y - 180, trans.rotation.z, trans.rotation.w);
}
//Start moving
if (!moving)
{
moving = true;
horizontal_speed = -10;
rigidbody2D.velocity = new Vector2(horizontal_speed, vertical_speed);
anim.SetInteger("State", 1);
}
//Update speed
else
{
if (horizontal_speed > -20)
{
horizontal_speed -= acceleration;
rigidbody2D.velocity.Set(horizontal_speed, vertical_speed);
}
}
}
//Stop moving right
if (Input.GetKeyUp(KeyCode.A))
{
moving = false;
horizontal_speed = 0;
rigidbody2D.velocity.Set(horizontal_speed, vertical_speed);
anim.SetInteger("State", 0);
}
}
}
change this
if (rigidbody2D.velocity.x < 0)
{
direction = -1;
}
else if (rigidbody2D.velocity.x > 0)
{
direction = 1;
}
to this
if (rigidbody2D.velocity.x < 0)
{
transform.localscale = new Vector3 (-1,1,1);
}
else if (rigidbody2D.velocity.x > 0)
{
transform.localscale = new Vector3 (1,1,1);
}

Determine swipe or tap

I'm trying to determine between tapping the screen and swiping the screen.
I want to determine swipes from left, right, up and down.
Right now when I swipe left or right, it also turns my player.
Which isn't suppose to happen. It should be one or the other, either turn or move left or right. My question is how can I determine all five things?
Swipe left, right, up, and down as-well as just tapping the screen.
Here is my code
using UnityEngine;
using System.Collections;
public class PlayerMotor : MonoBehaviour {
private CharacterController controller;
private Vector3 moveVector;
private float speed = 2.0f;
private float verticalVelocity = 0.0f;
private float gravity = 12.0f;
public Touch touch;
private void Start() {
controller = GetComponent<CharacterController> ();
}
private void Update()
{
moveVector = Vector3.zero;
if (controller.isGrounded)
{
verticalVelocity = -0.5f;
}
else
{
verticalVelocity -= gravity * Time.deltaTime;
}
if (Input.GetMouseButton (0))
{
if (touch.position.x == touch.deltaPosition.x && touch.position.x == touch.deltaPosition.x)
{ //3px accuracy, stationery :P
moveVector.x = transform.forward.x * speed;
transform.Rotate (new Vector3 (0, -90, 0));
}
else if (touch.position.x != touch.deltaPosition.x && touch.position.x != touch.deltaPosition.x)
{
if (Input.mousePosition.x > Screen.width / 2)
moveVector.x = speed;
else
moveVector.x = -speed;
}
}
moveVector.y = verticalVelocity;
moveVector.z = transform.forward.z * speed;
controller.Move (moveVector * Time.deltaTime);
}
}
I found this code with a little bit of searching. (Here)
Adding an else statement after all the if (currentSwipe...) statements should work to detect the click
//inside class
Vector2 firstPressPos;
Vector2 secondPressPos;
Vector2 currentSwipe;
public void Swipe()
{
if(Input.touches.Length > 0)
{
Touch t = Input.GetTouch(0);
if(t.phase == TouchPhase.Began)
{
//save began touch 2d point
firstPressPos = new Vector2(t.position.x,t.position.y);
}
if(t.phase == TouchPhase.Ended)
{
//save ended touch 2d point
secondPressPos = new Vector2(t.position.x,t.position.y);
//create vector from the two points
currentSwipe = new Vector3(secondPressPos.x - firstPressPos.x, secondPressPos.y - firstPressPos.y);
//normalize the 2d vector
currentSwipe.Normalize();
//swipe upwards
if(currentSwipe.y > 0 currentSwipe.x > -0.5f currentSwipe.x < 0.5f)
{
Debug.Log("up swipe");
}
//swipe down
if(currentSwipe.y < 0 currentSwipe.x > -0.5f currentSwipe.x < 0.5f)
{
Debug.Log("down swipe");
}
//swipe left
if(currentSwipe.x < 0 currentSwipe.y > -0.5f currentSwipe.y < 0.5f)
{
Debug.Log("left swipe");
}
//swipe right
if(currentSwipe.x > 0 currentSwipe.y > -0.5f currentSwipe.y < 0.5f)
{
Debug.Log("right swipe");
}
}
}
}

Categories

Resources