Move two player objects simultaneously with Raycast - unity3d

We have our player controller script setup and working for an individual player object, but when we want to add a second one, we are running into complications. I know we could potentially use a LayerMask to have the RayCast ignore a player object, but when that happens, both objects will try to move into the same space and cause problems. I'm stumped at this point.
Player Controller Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PlayerController : MonoBehaviour
{
public float speed;
bool isMoving;
float distance;
Vector3 endPos;
public Text parText;
private int par;
public static int moves;
bool upDetect;
bool downDetect;
bool rightDetect;
bool leftDetect;
Vector3 upLine;
Vector3 downLine;
Vector3 leftLine;
Vector3 rightLine;
public bool actionCheck;
Vector3 actionLine;
void Start()
{
isMoving = false;
par = Counter.levelPar;
endPos = transform.position;
//setPar();
}
private void FixedUpdate()
{
upLine = new Vector3(transform.position.x, transform.position.y, transform.position.z + 0.1f);
upDetect = Physics.Linecast(transform.position, upLine);
Debug.DrawLine(transform.position, upLine);
downLine = new Vector3(transform.position.x, transform.position.y, transform.position.z - 0.1f);
downDetect = Physics.Linecast(transform.position, downLine);
Debug.DrawLine(transform.position, downLine);
leftLine = new Vector3(transform.position.x - 0.1f, transform.position.y, transform.position.z);
leftDetect = Physics.Linecast(transform.position, leftLine);
Debug.DrawLine(transform.position, leftLine);
rightLine = new Vector3(transform.position.x + 0.1f, transform.position.y, transform.position.z);
rightDetect = Physics.Linecast(transform.position, rightLine);
Debug.DrawLine(transform.position, rightLine);
// actionLine = new Vector3(transform.position.x, transform.position.y - 1, transform.position.z);
// actionCheck = Physics.Linecast(transform.position, actionLine);
// Debug.DrawLine(transform.position, actionLine);
if (Input.GetKey("left") && isMoving == false && leftDetect == false)
{
isMoving = true;
RaycastHit hit;
Ray leftRay = new Ray(transform.position, Vector3.left);
if (Physics.Raycast(leftRay, out hit))
{
if (hit.collider != null)
{
endPos = new Vector3(hit.collider.transform.position.x + 1, endPos.y, endPos.z);
}
}
//countMove();
}
if (Input.GetKey("right") && isMoving == false && rightDetect == false)
{
isMoving = true;
RaycastHit hit;
Ray rightRay = new Ray(transform.position, Vector3.right);
if (Physics.Raycast(rightRay, out hit))
{
if (hit.collider != null)
{
endPos = new Vector3(hit.collider.transform.position.x - 1, endPos.y, endPos.z);
}
}
//countMove();
}
if (Input.GetKey("up") && isMoving == false && upDetect == false)
{
isMoving = true;
RaycastHit hit;
Ray upRay = new Ray(transform.position, Vector3.forward);
if (Physics.Raycast(upRay, out hit))
{
if (hit.collider != null)
{
endPos = new Vector3(endPos.x, endPos.y, hit.collider.transform.position.z - 1);
}
}
//countMove();
}
if (Input.GetKey("down") && isMoving == false && downDetect == false)
{
isMoving = true;
RaycastHit hit;
Ray downRay = new Ray(transform.position, -Vector3.forward);
if (Physics.Raycast(downRay, out hit))
{
if (hit.collider != null)
{
endPos = new Vector3(endPos.x, endPos.y, hit.collider.transform.position.z + 1);
}
}
//countMove();
}
distance = Vector3.Distance(transform.position, endPos);
//Debug.Log(distance);
//Debug.Log(rightDetect);
//Debug.Log(leftDetect);
//Debug.Log(upDetect);
//Debug.Log(downDetect);
if (distance < 0.01)
{
distance = 0;
}
if (distance > 0)
{
transform.position = Vector3.Lerp(
transform.position, endPos,
Time.deltaTime * speed / distance);
transform.rotation = Quaternion.identity;
}
else
{
isMoving = false;
endPos = transform.position;
}
//setPar();
}
/*void countMove()
{
moves++;
if (par > 0)
{
par--;
}
}
void setPar()
{
parText.text = "Par: " + par.ToString();
}*/
}

Figured it out. I had to use the Raycast hit to figure out what object it had hit. If the object had a "Player" tag, then it would go to that object's PlayerController script and get the value for it's end pos. Then I just had to adjust the endPos variable to compensate for the extra space. Here's my code.
PlayerController:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PlayerController : MonoBehaviour
{
public float speed;
bool isMoving;
public float distance;
public Vector3 endPos;
public Text parText;
private int par;
public static int moves;
bool upDetect;
bool downDetect;
bool rightDetect;
bool leftDetect;
Vector3 upLine;
Vector3 downLine;
Vector3 leftLine;
Vector3 rightLine;
Vector3 actionLine;
Rigidbody rb;
void Start()
{
isMoving = false;
par = Counter.levelPar;
endPos = transform.position;
rb = GetComponent<Rigidbody>();
//setPar();
}
private void FixedUpdate()
{
upLine = new Vector3(transform.position.x, transform.position.y, transform.position.z + 1);
upDetect = Physics.Linecast(transform.position, upLine);
Debug.DrawLine(transform.position, upLine);
downLine = new Vector3(transform.position.x, transform.position.y, transform.position.z - 1);
downDetect = Physics.Linecast(transform.position, downLine);
Debug.DrawLine(transform.position, downLine);
leftLine = new Vector3(transform.position.x - 1, transform.position.y, transform.position.z);
leftDetect = Physics.Linecast(transform.position, leftLine);
Debug.DrawLine(transform.position, leftLine);
rightLine = new Vector3(transform.position.x + 1, transform.position.y, transform.position.z);
rightDetect = Physics.Linecast(transform.position, rightLine);
Debug.DrawLine(transform.position, rightLine);
// actionLine = new Vector3(transform.position.x, transform.position.y - 1, transform.position.z);
// actionCheck = Physics.Linecast(transform.position, actionLine);
// Debug.DrawLine(transform.position, actionLine);
if (Input.GetKey("left") && isMoving == false && leftDetect == false)
{
isMoving = true;
RaycastHit hit;
Ray leftRay = new Ray(transform.position, Vector3.left);
if (Physics.Raycast(leftRay, out hit))
{
if (hit.collider != null && hit.collider.tag != "Player")
{
endPos = new Vector3(hit.collider.transform.position.x + 1, endPos.y, endPos.z);
}
if (hit.collider.tag == "Player")
{
GameObject oPlayer = hit.collider.gameObject;
endPos = GetOtherEndPos(oPlayer);
endPos = new Vector3(endPos.x + 1, endPos.y, endPos.z);
}
}
//countMove();
}
if (Input.GetKey("right") && isMoving == false && rightDetect == false)
{
isMoving = true;
RaycastHit hit;
Ray rightRay = new Ray(transform.position, Vector3.right);
if (Physics.Raycast(rightRay, out hit))
{
if (hit.collider != null && hit.collider.tag != "Player")
{
endPos = new Vector3(hit.collider.transform.position.x - 1, endPos.y, endPos.z);
}
if (hit.collider.tag == "Player")
{
GameObject oPlayer = hit.collider.gameObject;
endPos = GetOtherEndPos(oPlayer);
endPos = new Vector3(endPos.x - 1, endPos.y, endPos.z);
}
}
//countMove();
}
if (Input.GetKey("up") && isMoving == false && upDetect == false)
{
isMoving = true;
RaycastHit hit;
Ray upRay = new Ray(transform.position, Vector3.forward);
if (Physics.Raycast(upRay, out hit))
{
if (hit.collider != null && hit.collider.tag != "Player")
{
endPos = new Vector3(endPos.x, endPos.y, hit.collider.transform.position.z - 1);
}
if (hit.collider.tag == "Player")
{
GameObject oPlayer = hit.collider.gameObject;
endPos = GetOtherEndPos(oPlayer);
endPos = new Vector3(endPos.x , endPos.y, endPos.z - 1);
}
}
//countMove();
}
if (Input.GetKey("down") && isMoving == false && downDetect == false)
{
isMoving = true;
RaycastHit hit;
Ray downRay = new Ray(transform.position, -Vector3.forward);
if (Physics.Raycast(downRay, out hit))
{
if (hit.collider != null && hit.collider.tag != "Player")
{
endPos = new Vector3(endPos.x, endPos.y, hit.collider.transform.position.z + 1);
}
if (hit.collider.tag == "Player")
{
GameObject oPlayer = hit.collider.gameObject;
endPos = GetOtherEndPos(oPlayer);
endPos = new Vector3(endPos.x, endPos.y, endPos.z + 1);
}
}
//countMove();
}
distance = Vector3.Distance(transform.position, endPos);
//Debug.Log(distance);
//Debug.Log("Name: " + this.name + " distance = " + distance + " vel = " + rb.velocity.magnitude + " isMoving: " + isMoving);
//Debug.Log(rightDetect);
//Debug.Log(leftDetect);
//Debug.Log(upDetect);
//Debug.Log(downDetect);
//Debug.Log(isMoving);
//Debug.Log("Velocity = " + rb.velocity.magnitude);
if (distance < 0.1)
{
distance = 0;
}
if (distance > 0)
{
transform.position = Vector3.Lerp(
transform.position, endPos,
Time.deltaTime * speed / distance);
transform.rotation = Quaternion.identity;
}
else
{
isMoving = false;
endPos = transform.position;
}
//setPar();
}
Vector3 GetOtherEndPos(GameObject oPlayer)
{
PlayerController script = oPlayer.GetComponent<PlayerController>();
return script.endPos;
}
/*void countMove()
{
moves++;
if (par > 0)
{
par--;
}
}
void setPar()
{
parText.text = "Par: " + par.ToString();
}*/
}

Related

How do I freeze Y-axis Transform, in unity 3D. I want to select any GameObject in the game play Using "TAG" & move it along either in X-axis or Z-axis

That the User Game View Panel
Here is an Editor view
That the GameObject Movement in all axis, I don't wants that behavior to move in 3-Directions, I just want it to move in either X-axis OR Z_axis
I'm making a 3d game, in which a user can move vehicles using touch-controls that will allows the user to clear the parking area. this script is allied on the camera. this game this is like a 3D_Traffic_Jam_Parking clearance... I'm confused. I just tried to go on multiple learning platforms, but don't get it...!!!
public class ZarSwipe2D_Control : MonoBehaviour
{
#region Variables
private float distance;
private bool isDraging = false;
private bool swipeLeft, swipeRight, swipeUp, swipeDown;
public Vector3 desiredPosition;
private Vector2 Swipe2D;
private Transform Player;
#region Getter-Setter
public bool SwipeLeft { get { return swipeLeft; } }
public bool SwipeRight { get { return swipeRight; } }
public bool SwipeUp { get { return swipeUp; } }
public bool SwipeDown { get { return swipeDown; } }
#endregion
#endregion
#region Controller Functionality
private void Update()
{
Vector3 v3;
float x = Swipe2D.x;
float y = Swipe2D.y;
Touch touch = Input.touches[0];
Vector3 pos = touch.position;
if (Input.touchCount != 1)
{
isDraging = false;
return;
}
if (touch.phase == TouchPhase.Began)
{
Ray ray = Camera.main.ScreenPointToRay(pos);
if (Physics.Raycast(ray, out RaycastHit hit))
{
if (hit.collider.tag == "Player")
{
Player = hit.transform;
distance = hit.transform.position.z - pos.z;
v3 = new Vector3(pos.x, pos.y, distance);
v3 = Camera.main.ScreenToWorldPoint(v3);
desiredPosition = Player.position - v3;
isDraging = true;
}
}
}
if (isDraging && touch.phase == TouchPhase.Moved)
{
v3 = new Vector3(Input.mousePosition.x, Input.mousePosition.y, distance);
v3 = Camera.main.ScreenToWorldPoint(v3);
Player.position = v3 + desiredPosition;
}
if (isDraging && (touch.phase == TouchPhase.Ended || touch.phase ==TouchPhase.Canceled))
{
isDraging = false;
}
}
#endregion
}
If you are using a rigidbody component there is an option to disable rotation or movement along 1 axis only
#region Variables
//private float dist; // for old Code
private bool dragging = false;
//private Vector3 offset; // for old Code
private Transform toDrag;
private Vector2 StartSwipePos, EndSwipePos;
#endregion
#region Swipe Controller - Axis Along X&Z
void Update()
{
//Vector3 v3;
if (Input.touchCount != 1)
{
dragging = false;
return;
}
Touch touch = Input.touches[0];
Vector3 pos = touch.position;
if (Input.touchCount == 1)
{
if (touch.phase == TouchPhase.Began)
{
StartSwipePos = touch.position;
dragging = true;
#region OldCode - Touch Begin
//Ray ray = Camera.main.ScreenPointToRay(pos);
//if (Physics.Raycast(ray, out RaycastHit hit))
//{
// if (hit.collider.CompareTag("Player"))
// {
// toDrag = hit.transform;
// dist = hit.transform.position.z - Camera.main.transform.position.z;
// v3 = new Vector3(pos.x, pos.y, dist);
// v3 = Camera.main.ScreenToWorldPoint(v3);
// offset = toDrag.position - v3;
// dragging = true;
// }
//}
#endregion
}
if (dragging && touch.phase == TouchPhase.Moved)
{
EndSwipePos = touch.position;
Ray ray = Camera.main.ScreenPointToRay(pos);
if (Physics.Raycast(ray, out RaycastHit hit))
{
Vector2 Distance = EndSwipePos - StartSwipePos;
float x_Distance = Mathf.Abs(Distance.x);
float Y_Distance = Mathf.Abs(Distance.y);
if (x_Distance > Y_Distance)
{
if (Distance.x > 0)
{
if (hit.collider.CompareTag("Player"))
{
toDrag = hit.transform;
toDrag.transform.Translate(25f * Time.deltaTime, 0, 0);
Debug.Log("Right");
}
}
if (Distance.x < 0)
{
if (hit.collider.CompareTag("Player"))
{
toDrag = hit.transform;
toDrag.transform.Translate(-25f * Time.deltaTime, 0, 0);
Debug.Log("Left");
}
}
}
if (Y_Distance > x_Distance)
{
if (Distance.y > 0)
{
if (hit.collider.CompareTag("Player"))
{
toDrag = hit.transform;
toDrag.transform.Translate(0, 0, 25f * Time.deltaTime);
Debug.Log("Up");
}
}
if (Distance.y < 0)
{
if (hit.collider.CompareTag("Player"))
{
toDrag = hit.transform;
toDrag.transform.Translate(0, 0, -25f * Time.deltaTime);
Debug.Log("Down");
}
}
}
}
#region Old Code - Touch Move
//v3 = new Vector3(Input.mousePosition.x, Input.mousePosition.y, dist);
//v3 = Camera.main.ScreenToWorldPoint(v3);
//toDrag.position = v3 + offset;
#endregion
}
if (dragging && (touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled))
{
dragging = false;
}
}
}
#endregion

Moving player in Subway Surf like game using left/right swipe

I am developing endless runner game like subway surfer in Unity.
I want to move my player, smoothly on swipe left or right.
How can do it?
Here is my code:
using UnityEngine;
using System.Collections;
public class SwipeScript3 : MonoBehaviour {
private Touch initialTouch = new Touch();
private float distance = 0;
private bool hasSwiped = false;
//Quaternion targetx = Quaternion.Euler(0, -3f, 0);
//Quaternion targety = Quaternion.Euler(0, 3f, 0);
void FixedUpdate()
{
foreach(Touch t in Input.touches)
{
if (t.phase == TouchPhase.Began)
{
initialTouch = t;
}
else if (t.phase == TouchPhase.Moved && !hasSwiped)
{
float deltaX = initialTouch.position.x - t.position.x;
float deltaY = initialTouch.position.y - t.position.y;
distance = Mathf.Sqrt((deltaX * deltaX) + (deltaY * deltaY));
bool swipedSideways = Mathf.Abs(deltaX) > Mathf.Abs(deltaY);
if (distance > 50f)
{
if (swipedSideways && deltaX > 0) //swiped left
{
//transform.rotation = Quaternion.Slerp (transform.rotation, targetx, Time.deltaTime * 0.8f);
this.transform.Rotate(new Vector3(0, -3f, 0)*Time.deltaTime);
//transform.position = Vector3.Lerp (transform.position,new Vector3(transform.position.x+5f,transform.position.y,transform.position.z),Time.deltaTime*2f );
transform.position = Vector3.Lerp (transform.position, new Vector3 (transform.position.x - 5f, transform.position.y, transform.position.z), Time.deltaTime * 5f);
}
else if (swipedSideways && deltaX <= 0) //swiped right
{
//transform.rotation = Quaternion.Slerp (transform.rotation, targety, Time.deltaTime * 0.8f);
this.transform.Rotate(new Vector3(0, 3f, 0)*Time.deltaTime);
//transform.position = Vector3.Lerp (transform.position, new Vector3 (transform.position.x - 5f, transform.position.y, transform.position.z), Time.deltaTime * f);
transform.position = Vector3.Lerp (transform.position,new Vector3(transform.position.x+5f,transform.position.y,transform.position.z),Time.deltaTime*5f );
}
else if (!swipedSideways && deltaY > 0) //swiped down
{
//this.transform.Rotate(new Vector3(0, 2f, 0));
transform.position = Vector3.Lerp (transform.position,new Vector3(transform.position.x,transform.position.y,transform.position.z-5f),Time.deltaTime*2f );
}
else if (!swipedSideways && deltaY <= 0) //swiped up
{
this.GetComponent<Rigidbody>().velocity = new Vector3(this.GetComponent<Rigidbody>().velocity.x, 0, this.GetComponent<Rigidbody>().velocity.z);
this.GetComponent<Rigidbody>().AddForce(new Vector3(0, 400f, 0));
Debug.Log ("Swiped Up");
}
hasSwiped = true;
}
}
else if (t.phase == TouchPhase.Ended)
{
initialTouch = new Touch();
hasSwiped = false;
}
}
}
}
You could use Vector3.Slerp(Vector3 StartPosition, Vector3 DestinationPosition, float Number)
Number is between 0 and 1 and it indicates where will be the position of your object between StartPosition and DestinationPosition.
Lets say Number = 0.0f;: your object will be at StartPosition.
If Number = 0.5f;: your object will be between StartPosition and DestinationPosition.
You need to increase the Number value from 0 to 1 when swipe action is performed.
The faster you increase the "Number" value, the faster your object will move towards Destination.
You should set you StartPosition once when the swipe action begins, not give your transform.position repeatedly in your Vector3.Slerp() function.
You can find an example here in Unity Docs.
Hope this helps! Cheers!

How to fix my game's jumping?

I wanted to create a game where I can move my player tile by tile. I have no idea how to make it jump and how to make it smooth.
This is my code so far:
using UnityEngine;
using System.Collections;
public class PlayerScript : MonoBehaviour {
/*
* TILE BY TILE MOVEMENT
* */
private bool isMoving = false;
private bool isJumping = false;
private Vector3 targetPosition = new Vector3();
private Vector3 prevPosition = new Vector3();
public static bool canMove = true;
private Rigidbody2D rb2D;
void Start(){
prevPosition = transform.position;
rb2D = GetComponent<Rigidbody2D> ();
}
public void Move(string moveDirection){
if (isMoving == false && canMove == true) {
isMoving = true;
switch (moveDirection.ToLower()) {
case "left":
prevPosition = transform.position;
targetPosition = prevPosition + new Vector3(-2,0,0);
targetPosition.x = Mathf.Round(targetPosition.x);
break;
case "right":
prevPosition = transform.position;
targetPosition = prevPosition + new Vector3(2,0,0);
targetPosition.x = Mathf.Round(targetPosition.x);
break;
}
}
}
public void CancelMove(){
targetPosition = prevPosition;
Debug.Log("Canceled move");
}
void Update(){
if (isMoving == false) {
//Checks if there is ground
RaycastHit2D hit;
hit = Physics2D.Raycast (transform.position, -Vector2.up, 1.2f, 1 << LayerMask.NameToLayer("Ground"));
Debug.DrawRay (transform.position, -Vector2.up* 1.2f);
RaycastHit2D hitSideRight;
hitSideRight = Physics2D.Raycast (transform.position, Vector2.right, 1.2f, 1 << LayerMask.NameToLayer("Ground"));
Debug.DrawRay (transform.position, Vector2.right* 1.2f);
RaycastHit2D hitSideLeft;
hitSideLeft = Physics2D.Raycast (transform.position, -Vector2.right, 1.2f, 1 << LayerMask.NameToLayer("Ground"));
Debug.DrawRay (transform.position, -Vector2.right* 1.2f);
if((hitSideLeft.collider != null && hitSideLeft.collider.tag != "Box") || (hitSideRight.collider != null && hitSideRight.collider.tag != "Box")){
CancelMove();
Debug.Log("Can't move");
}
if (hit.collider != null || hit.collider == null){
if (Input.GetAxisRaw ("Horizontal") > 0 && hitSideRight.collider == null) {
Move ("right");
}
if (Input.GetAxisRaw ("Horizontal") < 0 && hitSideLeft.collider == null) {
Move ("left");
}
if(Input.GetKeyDown(KeyCode.Space)){
rb2D.AddForce(new Vector2(0,800));
}
}
} else {
if( transform.position.x != targetPosition.x )
{
// Move this object towards the target position
transform.position = Vector3.MoveTowards(transform.position, targetPosition, Time.deltaTime * 5f);
}
else
{
isMoving = false;
}
}
}
}
This script is attached to the player. The player has a rigidbody2D and a boxCollider2D: http://i.stack.imgur.com/sEV5b.jpg

How can I make my character move only forward in Unity?

I have a character in Unity which use a move script, to transform its position.x, y, or z everytime when I press the appropriate button. Now I would like to change my code to just rotate the character when the user press the "a" or "d" and don't move it, however if the user press the "w" button move it forward.
I have already looked for it on the internet, and found out that I would need to use Vector3.forward somehow, but it doesn't work.
Here is my script:
This is the script which actually moves the character:
(It is attached to a Player object which contains the moveable characters)
public class Move : MonoBehaviour {
float lerpTime;
float currentLerpTime;
float perc = 1;
Vector3 startPos;
Vector3 endPos;
bool firstInput;
public bool justJump;
// Update is called once per frame
void Update () {
if (Input.GetButtonDown("up") || Input.GetButtonDown("down") || Input.GetButtonDown("left") || Input.GetButtonDown("right")) {
if (perc == 1) {
lerpTime = 1;
currentLerpTime = 0;
firstInput = true;
justJump = true;
}
}
startPos = gameObject.transform.position;
if (Input.GetButtonDown("right") && gameObject.transform.position == endPos) {
endPos = new Vector3(transform.position.x + 0.5f, transform.position.y, transform.position.z);
}
if (Input.GetButtonDown("left") && gameObject.transform.position == endPos) {
endPos = new Vector3(transform.position.x - 0.5f, transform.position.y, transform.position.z);
}
if (Input.GetButtonDown("up") && gameObject.transform.position == endPos) {
endPos = new Vector3(transform.position.x, transform.position.y, transform.position.z + 0.5f);
}
if (Input.GetButtonDown("down") && gameObject.transform.position == endPos) {
endPos = new Vector3(transform.position.x, transform.position.y, transform.position.z - 0.5f);
}
if (firstInput == true) {
currentLerpTime += Time.deltaTime * 5;
perc = currentLerpTime / lerpTime;
gameObject.transform.position = Vector3.Lerp(startPos, endPos, perc);
if (perc > 0.8f) {
perc = 1;
}
if (Mathf.Round(perc) == 1) {
justJump = false;
}
}
}
}
And here is my "rotate script", which is attached to the moveable character(s) itself:
public class AnimationController : MonoBehaviour {
Animator anim;
public GameObject thePlayer;
// Use this for initialization
void Start () {
anim = gameObject.GetComponent<Animator>();
}
// Update is called once per frame
void Update () {
Move moveScript = thePlayer.GetComponent<Move>();
if (moveScript.justJump == true) {
anim.SetBool("Jump", true);
}
else {
anim.SetBool("Jump", false);
}
if (Input.GetButtonDown("right")) {
gameObject.transform.rotation = Quaternion.Euler(0, 90, 0);
}
if (Input.GetButtonDown("left")) {
gameObject.transform.rotation = Quaternion.Euler(0, -90, 0);
}
if (Input.GetButtonDown("up")) {
gameObject.transform.rotation = Quaternion.Euler(0, 0, 0);
}
if (Input.GetButtonDown("down")) {
gameObject.transform.rotation = Quaternion.Euler(0, 180, 0);
}
}
}
Could you give me please any help on this? (Preferably with code, if you can :) )
Assuming you want your character to move to where it is facing, and trying not to do a lot of changes to your code, this is what could be done:
First, attach both your script directly to your movable character.
Then, change your Move script to:
public class Move : MonoBehaviour {
float lerpTime;
float currentLerpTime;
float perc = 1;
Vector3 startPos;
Vector3 endPos;
bool firstInput;
public bool justJump;
// Update is called once per frame
void Update () {
if (Input.GetButtonDown("up") || Input.GetButtonDown("down") || Input.GetButtonDown("left") || Input.GetButtonDown("right")) {
if (perc == 1) {
lerpTime = 1;
currentLerpTime = 0;
firstInput = true;
justJump = true;
}
}
startPos = gameObject.transform.position;
if (Input.GetButtonDown("up") && gameObject.transform.position == endPos) {
endPos = transform.position + gameObject.transform.rotation * (new Vector3(0, 0, 0.5f));
}
if (Input.GetButtonDown("down") && gameObject.transform.position == endPos) {
endPos = transform.position + gameObject.transform.rotation * (new Vector3(0, 0, 0.5f));
}
if (firstInput == true) {
currentLerpTime += Time.deltaTime * 5;
perc = currentLerpTime / lerpTime;
gameObject.transform.position = Vector3.Lerp(startPos, endPos, perc);
if (perc > 0.8f) {
perc = 1;
}
if (Mathf.Round(perc) == 1) {
justJump = false;
}
}
}
}
And your AnimationController script to
public class AnimationController : MonoBehaviour {
Animator anim;
public GameObject thePlayer;
// Use this for initialization
void Start () {
anim = gameObject.GetComponent<Animator>();
}
// Update is called once per frame
void Update () {
Move moveScript = thePlayer.GetComponent<Move>();
if (moveScript.justJump == true) {
anim.SetBool("Jump", true);
}
else {
anim.SetBool("Jump", false);
}
if (Input.GetButtonDown("right")) {
gameObject.transform.rotation = gameObject.transform.rotation * Quaternion.Euler(0, 90, 0);
}
if (Input.GetButtonDown("left")) {
gameObject.transform.rotation = gameObject.transform.rotation * Quaternion.Euler(0, 90, 0);
}
}
}
This will make your character rotate only when you press the left and right buttons, and move only when you press the up and down button.
Althought this solves your problem, this is not the best way to write scripts for your character movement.
I recommend you read more about the state machine design patter. This book by Robert Nystrom has a chapter about it and is really easy to read. Also, its free to read online :)

Designing a specific grid movement

what I'm trying to achieve, is that while the player holds the mouse button
on a tile (any grid element, verically or horizontally aligned with the player), the player will move towards that tile with the possible directions of left,right,up,down only.
currently my code doesn't work for while pressing the mouse button, I think it has something to do with the raycasting.
second thing I want to achieve is that while the player is moving in the grid, if the player decides to change direction, he will be able, no matter if it's just opposite direction, or if he decideds to take a sudden turn left/right.
(I managed to achieve it without using the isMoving boolean condition only in the opposite direction, but I added it because when the player clicked while moving it slowed him down)
right now no change in movement while moving is available.
using UnityEngine;
using Holoville.HOTween;
using System.Collections;
public class Player : MonoBehaviour {
public float speed = 100f;
private Vector3 startPos;
private Vector3 endPos;
private float startTime;
private float journeyLength;
private tile currentTile;
private tile tileToMove;
private float angleToTurn = 0f;
private bool isMoving = false;
public static Player use;
void Awake()
{
use = this;
}
void Start () {
startPos = endPos = transform.position;
tileToMove = currentTile = fieldGenerator.use.tilesList[0];
}
// Update is called once per frame
void Update () {
MovePlayer();
float distCovered = (Time.time - startTime) * speed;
float fracJourney = distCovered / journeyLength;
if (!startPos.Equals(endPos))
transform.position = Vector3.Lerp(startPos, endPos, fracJourney);
if (transform.position == endPos)
{
isMoving = false;
}
}
void MovePlayer()
{
Ray ray;
RaycastHit hit;
if (Input.GetMouseButtonDown(0) && !isMoving)
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
for (int i = 0; i < fieldGenerator.use.tilesList.Count; i++)
{
if (fieldGenerator.use.tilesList[i].selfObject.collider.Raycast(ray, out hit, float.PositiveInfinity))
{
if (fieldGenerator.use.tilesList[i].selfObject.transform.position.x < transform.position.x && fieldGenerator.use.tilesList[i].selfObject.transform.position.y == transform.position.y)
{
angleToTurn = -180f;
tileToMove = fieldGenerator.use.tilesList[i];
isMoving = true;
}
else if (fieldGenerator.use.tilesList[i].selfObject.transform.position.x > transform.position.x && fieldGenerator.use.tilesList[i].selfObject.transform.position.y == transform.position.y)
{
angleToTurn = 0;
tileToMove = fieldGenerator.use.tilesList[i];
isMoving = true;
}
else if (fieldGenerator.use.tilesList[i].selfObject.transform.position.y < transform.position.y && fieldGenerator.use.tilesList[i].selfObject.transform.position.x == transform.position.x)
{
angleToTurn = -90f;
tileToMove = fieldGenerator.use.tilesList[i];
isMoving = true;
}
else if (fieldGenerator.use.tilesList[i].selfObject.transform.position.y > transform.position.y && fieldGenerator.use.tilesList[i].selfObject.transform.position.x == transform.position.x)
{
angleToTurn = 90f;
tileToMove = fieldGenerator.use.tilesList[i];
isMoving = true;
}
startTime = Time.time;
startPos = transform.position;
endPos = tileToMove.selfObject.transform.position;
journeyLength = Vector3.Distance(startPos, endPos);
transform.eulerAngles = new Vector3(0f, 0f, angleToTurn);
}
}
}
}
}
Unsure on what you're doing with the tiles and raycasting but here's how i'd do it. Apologies for the formatting, it's just how I work.
EDIT: Okay, given you said 'grid' movement I assumed the tiles were equidistant from each other. GetMouseButtonDown changed to GetMouseButton as well. This will mean that a ray is shot every update which you may want to look into making more efficient.
using UnityEngine;
using Holoville.HOTween;
using System.Collections;
public class Player : MonoBehaviour {
public float speed = 100.0f;
private float delta = 0.0f;
private float distance = 1.0f;
private Vector3 startPos;
private Vector3 endPos;
private tile currentTile;
private tile tileToMove;
private float angleToTurn = 0f;
private bool isMoving = false;
public static Player use;
void Awake() {
use = this;
}
void Start () {
startPos = endPos = transform.position;
tileToMove = currentTile = fieldGenerator.use.tilesList[0];
}
// Update is called once per frame
void Update () {
GetInput();
MovePlayer();
}
void MovePlayer() {
if ( isMoving ) {
if ( delta < 1 ) {
// Distance independant movement.
delta += ( speed/distance ) * Time.deltaTime;
transform.position = Vector3.Lerp(startPos, endPos, delta);
} else {
isMoving = false;
}
}
}
void GetInput() {
Ray ray;
RaycastHit hit;
if ( Input.GetMouseButton(0) ) {
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
for (int i = 0; i < fieldGenerator.use.tilesList.Count; i++) {
if ( fieldGenerator.use.tilesList[i].selfObject.collider.Raycast( ray, out hit, float.PositiveInfinity ) ) {
if (fieldGenerator.use.tilesList[i].selfObject.transform.position.x < transform.position.x && fieldGenerator.use.tilesList[i].selfObject.transform.position.y == transform.position.y) {
angleToTurn = -180f;
tileToMove = fieldGenerator.use.tilesList[i];
isMoving = true;
} else if (fieldGenerator.use.tilesList[i].selfObject.transform.position.x > transform.position.x && fieldGenerator.use.tilesList[i].selfObject.transform.position.y == transform.position.y) {
angleToTurn = 0;
tileToMove = fieldGenerator.use.tilesList[i];
isMoving = true;
} else if (fieldGenerator.use.tilesList[i].selfObject.transform.position.y < transform.position.y && fieldGenerator.use.tilesList[i].selfObject.transform.position.x == transform.position.x) {
angleToTurn = -90f;
tileToMove = fieldGenerator.use.tilesList[i];
isMoving = true;
} else if (fieldGenerator.use.tilesList[i].selfObject.transform.position.y > transform.position.y && fieldGenerator.use.tilesList[i].selfObject.transform.position.x == transform.position.x) {
angleToTurn = 90f;
tileToMove = fieldGenerator.use.tilesList[i];
isMoving = true;
}
isMoving = true;
delta = 0f;
startPos = transform.position;
endPos = tileToMove.selfObject.transform.position;
distance = Vector3.Distance( startPos, endPos );
transform.eulerAngles = new Vector3(0f, 0f, angleToTurn);
}
}
}
}
}