- Home /
Move Forward or Turn based on action recieved.
Hello All, I have been fighting this issue for three days now and decided to ask for some much needed help. My issue I'm having is i have a player(cube gameobject with player script) and platforms(cube gameobject with block script). Thplayer script casts a raycast down to recieve an action from the block it is on. Those actions are Turn Left, Turn Right, or Move Forward. I can get the actions from the blocks no problem but what isnt working is my movement. The Move function seems to be called constantly, I want to only move the player 1 unit forward and only when the player makes it to the next platform. If i can clear anything up please let me know. Thank You in advanced!
void Update () {
if(GM.PlatCounter > 0) {
RaycastHit hitBlock;
Vector3 trans = transform.TransformDirection(Vector3.down);
if (Physics.Raycast(new Vector3(transform.position.x, transform.position.y, transform.position.z), trans, out hitBlock)) {
Debug.DrawLine (new Vector3(transform.position.x, transform.position.y, transform.position.z), hitBlock.point, Color.green);
//Debug.Log("Hit: " + hitBlock.transform.gameObject.GetComponent<BlockType>().act);
GetBlockAction(hitBlock.transform);
}
void GetBlockAction(Transform action) {
string act = action.GetComponent<BlockType>().act.ToString();
//Debug.Log (act);
if(act == "MoveForward" && moving != true) {
Debug.Log ("In forward fuction");
MovePlayer();
return;
}
}
void MovePlayer() {
moving = true;
transform.position = transform.position + transform.forward * (Time.deltaTime);
moving = false;
}
Answer by korbul · Jun 11, 2014 at 12:50 PM
Ok, let's think this through.
Update function is called each frame. about 60 times a second.
So, on each frame you cast a ray downwards and hit a platform. The platform's action is "MoveForward". This will cause MovePlayer() to be called each frame, so your player will move each frame -> constantly.
Now, depending on your logic, you have to change this flow. Let's say you want the player to move once on mouse click.
So, on mouse click, you cast the ray down, find the platform's action, and call MovePlayer(). In move player i recommand you use translate function
transorm.translate(new Vector3(1,0,0));
This flow will only move your player once and for one unit.
Thank you for the reply. Now that makes sense that it's getting called 60 times a second. I want the player to automatically move forward 1 unit if the block action is move forward and G$$anonymous$$.PlatCounter is greater than 0, then 90 degrees left or right depending on if the action is Turn left or Turn Right. I'm just having trouble figuring out how to call the move function just once for one unit worth of movement.
Answer by Spikeh · Jun 12, 2014 at 08:21 AM
Currently, your moving variable has no effect on anything in your script. You're setting moving = true and moving = false in the same frame - you need to set moving = false once the player reaches its destination. I'd probably change the MovePlayer method as follows:
void MovePlayer() {
if(!moving)
return;
transform.position = transform.position + transform.forward * (Time.deltaTime);
}
Call it every frame regardless (the method will return and do nothing if moving = false):
void Update() {
// TODO: determine if the player should move (set moving = true)
// Move the player if necessary
MovePlayer();
// TODO: determine if the player has reached its destination (set moving = false)
}
I tend to do this kind of thing with a tweening engine like HOTween / iTween, as it makes things a little easier to work with (to me at least). It also adds more complexity, too though!
I also noticed that you mentioned that you want to move the player forward by 1 unit. Might be worth working out what "1 unit" is before hand, unless its a constant. Your script above moves the player gradually.
Answer by Sobe459 · Jun 12, 2014 at 04:27 PM
Now my issue is figuring out how to see when the player has moved one unit to set moving to false and call a new function TurnPlayer if turning is true. Here is my whole script. If i can clear anything up let me know.
[code]using UnityEngine; using System.Collections;
public class Player2 : MonoBehaviour {
public GameManager GM;
public PlayerDirection dirc = PlayerDirection.Up;
public int action = 0;
public int rotation = 0;
public bool moving = false;
public int turnDir = 0;
public float damping = 0.5f;
public int blocksPassed = 0;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
action = 0; //resets the block action to null
if(GM.PlatCounter > 0) { //Number of platforms placed from game manager script
RaycastHit hitDir; //Raycast to determine facing of player
if (Physics.Raycast(new Vector3(transform.position.x, transform.position.y + 1, transform.position.z), transform.forward, out hitDir)) {
Debug.DrawLine (new Vector3(transform.position.x, transform.position.y + 1, transform.position.z), hitDir.point, Color.cyan);
SetDirection(hitDir.transform.name);
}
RaycastHit hitBlock; //Raycast down to determine the block its on and send the action to GetBlcokAction function
Vector3 trans = transform.TransformDirection(Vector3.down);
if (Physics.Raycast(new Vector3(transform.position.x, transform.position.y, transform.position.z + 0.5f), trans, out hitBlock)) {
Debug.DrawLine (new Vector3(transform.position.x, transform.position.y, transform.position.z + 0.5f), hitBlock.point, Color.green);
GetBlockAction(hitBlock.transform);
}
// Based on action(MoveForward = 1, TurnLeft = 2, TurnRight = 3), moves the player then turns if has to
if(action == 1) {
moving = true;
// Move the player if necessary
MovePlayer(false, 0);
}
if(action == 2) {
moving = true;
MovePlayer(true, 1);
}
if(action == 3) {
moving = true;
MovePlayer(true, 2);
}
// TODO: determine if the player has reached its destination (set moving = false)
//Figure out where this(moving) should acctully be set to false
if(action == 0) {
moving = false;
}
if(!moving) {
Debug.Log((int)Mathf.Abs(transform.position.x) + " , " + (int)Mathf.Abs(transform.position.z));
}
}
}
void TurnPlayer(int lr) {
if(lr == 1) {
Debug.Log("Left");
if(!moving) { //only turn once moved on unit
float yRotation = 90.0f;
transform.eulerAngles = new Vector3(transform.eulerAngles.x, yRotation, transform.eulerAngles.z);
}
}
else if(lr == 2) {
Debug.Log("Right");
if(!moving) { //only turn once moved on unit
float yRotation = -90.0f;
transform.eulerAngles = new Vector3(transform.eulerAngles.x, yRotation, transform.eulerAngles.z);
}
}
else {
return;
}
}
void GetBlockAction(Transform a) {
//Recieves the block action from the block the player is on.
string act = a.GetComponent<BlockType>().act.ToString();
switch(act)
{
case "MoveForward":
action = 1;
break;
case "TurnLeft":
action = 2;
break;
case "TurnRight":
action = 3;
break;
default:
action = 0;
break;
}
}
void SetDirection(string dir) {
//Sets players facing depending on boundries.
switch(dir)
{
case "Up":
dirc = PlayerDirection.Up;
break;
case "Down":
dirc = PlayerDirection.Down;
break;
case "Right":
dirc = PlayerDirection.Right;
break;
case "Left":
dirc = PlayerDirection.Left;
break;
}
//Debug.Log("Direction: " + dirc);
}
void MovePlayer(bool turning, int lr) {
if(!moving) {
return;
}
if(turning) { //moves the player over time 1 unit forward
transform.Translate(new Vector3(0,0,1 * Time.deltaTime * damping));
}
else { //moves the player over time 1 unit forward
transform.Translate(new Vector3(0,0,1 * Time.deltaTime * damping));
//needs to finishing moving before calling TurnPlayer
TurnPlayer(lr);
}
}
}
public enum PlayerDirection { Up, Left, Right, Down }[/code]
Your answer
Follow this Question
Related Questions
Camera rotation around player while following. 6 Answers
iTween MoveTo shoots off into distance 0 Answers
Add Force To One Object in Relation to the Rotation of Another Object (C#) 1 Answer
How to stop a unit from rotation once it gets to designated position? 2 Answers
Move a ship around a planet and rotate ship on Y axis 1 Answer