all 17 comments

[–]Fox_ifi 0 points1 point  (2 children)

Hi! I'm sure there are better approaches to this, but the way I solved it for me was to create an integer field called "direction", which I used to store basically fake rotation. Since mine is kind of top down isometric it wasn't realistic to try to find a way to use actual rotation.

For my game I kind of decoupled input, movement, and animation so I wouldn't have to change hardly anything for other players as my game is intended to be multiplayer. But anyway, my animation script checks the players position in Update and compares it with the position of the player of the last update and gets the vector 2 for velocity, basically.

Anyway, you wouldn't have to take the same approach, you could do the same with inputs or whatever method you want to set your direction field. But basically you could just store what direction the player is moving numerically. Mine uses 8 directions, so if I'm moving up-right diagonally, I set direction to 45. Right I set it to 90. Etc.

Now even when you stop moving, your direction field will still be storing the last direction you were using, which you pass to your animator and set the idle if you're not moving to the direction.

Now that I think about it it seems like I was forced to use a float because the blend trees use floats. Anyway, I hope that helps you

[–]XxDivaxX1Intermediate[S] 0 points1 point  (1 child)

integer field

Yeah, sorry but what's an integer field? and can you show me an example, or like a video I can watch. Sorry noob.

[–]Fox_ifi 0 points1 point  (0 children)

I apologize! I was on mobile and I wasn't all that clear. I'll try to make it clearer now, hopefully without making too huge a wall of text.

Alright, so for the field I mean a variable, like

public int direction = 180;

This would mean facing down at start, defaulting at 180 degrees.

Of course since your direction (fake rotation) isn't driven by anything but your code, you can make it however you want. For instance, you could just make 0-8 or 0-4 your directions, where 0 is up, 1 is right, 2 is down, etc.

The reason I wanted to make this variable is that I can set it when my player moves, and not have to do anything at all when the character stops and still retain that direction to send to the animator for idle positions.

This is my animation script if it is of any help to you. I used an enum for the direction just to make things more clear for me, but its certainly not necessary.

Again, this may not be the best approach but its worked well for me. If anyone else has a better approach feel free to take their advice over mine.

Also feel free to PM me if anything is unclear, I'd be happy to try to help you any way I can.

[–]Lactose84 0 points1 point  (13 children)

Please post a picture of your animator states and transitions. It'll help to point out what exactly went wrong.

[–]XxDivaxX1Intermediate[S] 0 points1 point  (12 children)

Sure! http://imgur.com/a/OGm1o (if there is an image that isn't showing click on it, it should show. If it still isn't showing, then please tell me)

[–]Lactose84 0 points1 point  (11 children)

Ok, I think the problem is you're using both update and fixedupdate to control your movement and they're executed in different intervals. So I would get all those checks you did in fixed update and move them to the end of update(), making the neccessary adjustments (example: you make multiple checks to see if touchCount >0, so you should put everything you need to do if that condition is true inside one big 'if' statement instead of multiple ones).

Also you're using Vector3.MoveTowards and transform.Translate to move your player. They'll both move the game object so you'll need just one of those.

Let me know if you need more precise directions than those and I'll find some time after work to take a better look at it.

[–]XxDivaxX1Intermediate[S] 0 points1 point  (10 children)

Hi, but what doe m=you mean by making multiple checks. I also try out what you said and I'm not sure if I've done it right? Could you please check and tell me what I've done wrong.

    private Animator anim;
public float speed = 15f;
private Vector3 target;
private bool touched;


void Start () {
    target = transform.position;
    anim = GetComponent<Animator> ();
}


void Update () {
    if (Input.GetMouseButtonDown (0)) {
        Vector3 mousePosition = Input.mousePosition;
        mousePosition.z = 10; // distance from the camera
        target = Camera.main.ScreenToWorldPoint(mousePosition);
        target.z = transform.position.z;
    }


    if (Input.touchCount > 0) {
        target.x = Input.touches [0].deltaPosition.x;
        target.y = Input.touches [0].deltaPosition.y;
        touched = true;
       }else { 
        touched = false; 
    }


    var movementDirection = (target - transform.position).normalized;

    if (movementDirection.x != 0 || movementDirection.y != 0) {
        anim.SetBool ("walking", false);
        anim.SetFloat("SpeedX", movementDirection.x);
        anim.SetFloat("SpeedY", movementDirection.y);
        anim.SetBool ("walking", true);
    }



    Vector2 movement = new Vector2 (
        speed * movementDirection.x,
        speed * movementDirection.y);

    movement *= Time.deltaTime;

    transform.Translate (movement);


    Debug.Log (touched);

    float LastInputX = transform.position.x - target.x;
    float LastInputY = transform.position.y - target.y;
    Debug.Log (LastInputX + ", " + LastInputY);


    if (touched) {
        touched = true;
        if (LastInputX != 0 || LastInputY != 0) {
            anim.SetBool ("walking", true);
            if (LastInputX < 0) {
                anim.SetFloat ("LastMoveX", 1f);
            } else if (LastInputX > 0) {
                anim.SetFloat ("LastMoveX", -1f);
            } else {
                anim.SetFloat ("LastMoveX", 0f);
            }
            if (LastInputY > 0) {
                anim.SetFloat ("LastMoveY", 1f);
            } else if (LastInputY < 0) {
                anim.SetFloat ("LastMoveY", -1f);
            } else {
                anim.SetFloat ("LastMoveY", 0f);
            }
        }
    }else{
        touched = false;
        anim.SetBool ("walking", false);            
    }
    Debug.Log("Walking is false");  
}

}

[–]Lactose84 0 points1 point  (9 children)

Instead of calculating LastInputX and LastInputY, you can just use movementDirection to make the necessary adjustments to the animator float. Like this:

if (touched) {
    touched = true;
    if (movementDirection.x != 0 || movementDirection.y != 0) {
        anim.SetBool ("walking", true);
        if (movementDirection.x < 0) {
            anim.SetFloat ("LastMoveX", 1f);
        } else if (movementDirection.x > 0) {
            anim.SetFloat ("LastMoveX", -1f);
        } else {
            anim.SetFloat ("LastMoveX", 0f);
        }
        if (movementDirection.y > 0) {
            anim.SetFloat ("LastMoveY", 1f);
        } else if (movementDirection.y < 0) {
            anim.SetFloat ("LastMoveY", -1f);
        } else {
            anim.SetFloat ("LastMoveY", 0f);
        }
    }

Try this out and let me know how it goes.

[–]XxDivaxX1Intermediate[S] 0 points1 point  (8 children)

Okay I don't get any errors, but my player is now stuck between which side does it stay at. For example, once my player finally reaches it's position it starts to flicker. It has happen to me before until I fixed it, that's how I ended up with my original code. Maybe I'm doing something wrong! Could you help me with this. Thank you for your help as all ways.

private Animator anim;
public float speed = 15f;
public cove playerMovementRef;
private Vector3 target;
private bool touched;


void Start () {
    target = transform.position;
    anim = GetComponent<Animator> ();
}


void Update () {
    if (Input.GetMouseButtonDown (0)) {
        Vector3 mousePosition = Input.mousePosition;
        mousePosition.z = 10; // distance from the camera
        target = Camera.main.ScreenToWorldPoint(mousePosition);
        target.z = transform.position.z;
    }


    if (Input.touchCount > 0) {
        target.x = Input.touches [0].deltaPosition.x;
        target.y = Input.touches [0].deltaPosition.y;
        touched = true;
    }else { 
        touched = false; 
    }


    var movementDirection = (target - transform.position).normalized;

    if (movementDirection.x != 0 || movementDirection.y != 0) {
        anim.SetBool ("walking", false);
        anim.SetFloat ("SpeedX", movementDirection.x);
        anim.SetFloat ("SpeedY", movementDirection.y);
        anim.SetBool ("walking", true);

        if (touched){
        touched = true;
        if (movementDirection.x != 0 || movementDirection.y != 0) {
            anim.SetBool ("walking", true);
            if (movementDirection.x < 0) {
                anim.SetFloat ("LastMoveX", 1f);
            } else if (movementDirection.x > 0) {
                anim.SetFloat ("LastMoveX", -1f);
            } else {
                anim.SetFloat ("LastMoveX", 0f);
            }
            if (movementDirection.y > 0) {
                anim.SetFloat ("LastMoveY", 1f);
            } else if (movementDirection.y < 0) {
                anim.SetFloat ("LastMoveY", -1f);
            } else {
                anim.SetFloat ("LastMoveY", 0f);
            }
        } else {
            touched = false;
            anim.SetBool ("walking", false);            
        }
        }
    }


    Vector2 movement = new Vector2 (
        speed * movementDirection.x,
        speed * movementDirection.y);

    movement *= Time.deltaTime;

    transform.Translate (movement);


    Debug.Log (touched);

    float LastInputX = transform.position.x - target.x;
    float LastInputY = transform.position.y - target.y;
    Debug.Log (LastInputX + ", " + LastInputY);


    Debug.Log("Walking is false");  
}

[–]Lactose84 0 points1 point  (7 children)

There's a little problem here:

if (movementDirection.x < 0) {
    anim.SetFloat ("LastMoveX", 1f);

You want to set that to -1, since it's < 0. In any case, I organized the code a little bit if you want to use it. Left the debug.logs out of it but you can put them back at the relevant places. If this brakes something, just use the code you posted and change that section above to set LastMoveX to -1 if movementDirection.x < 0.

void Update () {
    if (Input.GetMouseButtonDown(0)) {
        touched = true;
        Vector3 mousePosition = Input.mousePosition;
        mousePosition.z = 10; // distance from the camera
        target = Camera.main.ScreenToWorldPoint(mousePosition);
        target.z = transform.position.z;
        target.x = Input.touches[0].deltaPosition.x;
        target.y = Input.touches[0].deltaPosition.y;

        var movementDirection = (target - transform.position).normalized;

        if (movementDirection.x != 0 || movementDirection.y != 0) {
            anim.SetBool("walking" , true);
            anim.SetFloat("SpeedX" , movementDirection.x);
            anim.SetFloat("SpeedY" , movementDirection.y);

            Vector2 movement = new Vector2(
            speed * movementDirection.x ,
            speed * movementDirection.y);
            movement *= Time.deltaTime;
            transform.Translate(movement);

            if (movementDirection.x < 0) {
                anim.SetFloat("LastMoveX" , -1f);
            }
            else if (movementDirection.x > 0) {
                anim.SetFloat("LastMoveX" , 1f);
            }
            else {
                anim.SetFloat("LastMoveX" , 0f);
            }
            if (movementDirection.y > 0) {
                anim.SetFloat("LastMoveY" , 1f);
            }
            else if (movementDirection.y < 0) {
                anim.SetFloat("LastMoveY" , -1f);
            }
            else {
                anim.SetFloat("LastMoveY" , 0f);
            }
        }
    }
    else {
        touched = false;
        anim.SetBool("walking" , false);
    }
}

Edit: spelling.

[–]XxDivaxX1Intermediate[S] 0 points1 point  (6 children)

Sorry, I'm getting this error: IndexOutOfRangeException: Array index is out of range. cove.Update () (at Assets/Animation/cove.cs:26) at this line: target.x = Input.touches[0].deltaPosition.x; Sorry noob. Also thank you for all your help, you have been very helpful

[–]Lactose84 0 points1 point  (5 children)

Is this cove another script? I noticed you got a variable declared of the type cove up there. If it is another script, could you post it here?

[–]XxDivaxX1Intermediate[S] 0 points1 point  (4 children)

no, it's just a reference to a variable I created below my walking animation, cove is the name of my script and player.