0
\$\begingroup\$

I'm making a 2D game with Unity using the new Input System. I used spriteRenderer.flipX to flip the player but since it is made of three parts (body and two eyes), the spriteRenderer didn't work. Also, I couldn't convert them to a single sprite because I need the eyes in order to animate them. So, I decided to use transform.localscale for flipping and change movementInput value from a float to a Vector2. The problem is that when I press the arrow or AD keys to move the character, an error pops up saying "Cannot read value of type Vector2 from composite". This error is from InputActionState which is a long and complicated code related to the new Input System. Also, getting input from gamepad causes the same error. I don't know what does this error mean and how can I fix it. Now, the player can jump but it can't move or flip. You can see the code, the error and my action map down below.

This is my Player Controller:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerController : MonoBehaviour
{
    [SerializeField] private float speed, jumpSpeed;
    [SerializeField] private LayerMask ground;
    private PlayerActionControls playerActionControls;
    private Rigidbody2D rb;
    private PolygonCollider2D pol;
    private Animator animator;
    private bool facingRight = true;
    private Vector2 movementInput;

private void Awake() {
       
    playerActionControls = new PlayerActionControls();  
    rb = GetComponent<Rigidbody2D>(); 
    pol = GetComponent<PolygonCollider2D>();
    animator = GetComponent<Animator>();   
      
   }

private void OnEnable() {

    playerActionControls.Enable();

   }

 private void OnDisable() {

    playerActionControls.Disable();
   }

 void Start()
   {
     playerActionControls.Land.Jump.performed += ctx => Jump(ctx.ReadValue<float>());

    }   

private void Jump(float val) {
       if (val == 1 && IsGrounded()) {
           rb.AddForce(new Vector2(0, jumpSpeed), ForceMode2D.Impulse);       
       }
   }
     

private bool IsGrounded() {
  
       Vector2 topLeftPoint = transform.position;
       topLeftPoint.x -= pol.bounds.extents.x;
       topLeftPoint.y += pol.bounds.extents.y;

       Vector2 bottomRightPoint = transform.position;
       bottomRightPoint.x += pol.bounds.extents.x;
       bottomRightPoint.y -= pol.bounds.extents.y;

       return Physics2D.OverlapArea(topLeftPoint, bottomRightPoint, ground);
   }
     void FixedUpdate()
   {    
       if(facingRight == false && movementInput.x > 0){       
           Flip();
       } else if (facingRight == true && movementInput.x < 0){        
           Flip();    
       }
   }
   void Flip(){
        facingRight = !facingRight;
        Vector3 Scaler = transform.localScale;
        Scaler.x *= -1;
        transform.localScale = Scaler;
   }
  
   void Update()
   {
      movementInput = playerActionControls.Land.Move.ReadValue<Vector2>();
       
       Vector2 currentPosition = transform.position;  // This was a Vector3 but since I got the error  "Operator '+=' is ambiguous on operands of type 'Vector3' and 'Vector2", I changed it to a Vector2.
       currentPosition += movementInput * speed * Time.deltaTime;
       transform.position = currentPosition;
     
   }
}

This is the error I get when I want to move the player. enter image description here

This is my action map.

enter image description here

\$\endgroup\$
11
  • \$\begingroup\$ Your movement controls look like they are only left-right, not up-down. If that's the case, perhaps the Move input is using a single axis (meaning it will only have a float value) rather than a 2-axis Vector2 value? \$\endgroup\$
    – Kevin
    Dec 2 '20 at 22:34
  • \$\begingroup\$ @Kevin They are only left-right because I don't need up-down for this 2D game. Before this, I was using just a Left Stick binding but its problem was that the left stick could move the player to up and down and it made a weird bouncing. I hope this answers your question if not, please tell me to give more information about this. \$\endgroup\$
    – Ali
    Dec 2 '20 at 22:42
  • \$\begingroup\$ So it sounds like you're trying to read a two-axis input when you only need one axis. Try getting a <float> instead of a <Vector2> \$\endgroup\$
    – Kevin
    Dec 2 '20 at 22:47
  • \$\begingroup\$ @Kevin This was a float but I changed it to a Vector2 because I wanted to get flipping working. I had to use sprite renderer component if I changed it to a float which was not what I wanted. Also, I wrote a comment in the code about Vector2 currentPosition = transform.position; and this problem might be due to that. This was a Vector3 but I changed it to a Vector2 because I got an error saying that "operator is ambiguous on operands of type Vector 3 and Vector2". Can this be related to the current problem? \$\endgroup\$
    – Ali
    Dec 3 '20 at 0:34
  • \$\begingroup\$ I'm not sure if this helps since I have never used the new input system, but googling the error I see people have similar issues caused by Unitys auto generated files. Most people said this was fixed by regenerating the action map, whatever that means. It seems to be an error that happens when you change the inputs type (in your case I'm guessing float to Vector2. Mostly likely if you ask for your old input type you will still get a result of that type instead of the new Vector2 type). \$\endgroup\$ Dec 3 '20 at 2:16
1
\$\begingroup\$

There are a few errors in your code.

  1. In your Update you declare a second local movementInput Vector2. This one hides your movementInput in your class and while no errors are produced, your Flip() won't work. Delete the Vector2 in front of movementInput.
  2. Your actionMap looks wrong. Your action needs to be of the type Value with ControlType Vector2. Next you are missing the Composite 2D Vector for your input. It should look like this

enter image description here

\$\endgroup\$
1
  • \$\begingroup\$ This solved my problem. Thank you so much! \$\endgroup\$
    – Ali
    Dec 3 '20 at 20:45
0
\$\begingroup\$

The only reason why I want to change the value from float to Vector2 is for movementInput.x. If I keep movementInput as a float, then I get an error because the float doesn't contain a definition for x

Yes, a float doesn't have an x property because it's a single numeric value. The x property of Vector2 is a float. It sounds like you need to brush up on your basic data structures like floats and Vectors.

What you need is this:

private float movementInput;

void FixedUpdate() {    
    if(facingRight == false && movementInput > 0){       
        Flip();
    } else if (facingRight == true && movementInput < 0){        
        Flip();    
    }
}

void Update() {
    movementInput = playerActionControls.Land.Move.ReadValue<float>();
       
    transform.Translate(movementInput * speed * Time.deltaTime, 0);
}
\$\endgroup\$
5
  • \$\begingroup\$ Thank you for your help. I tried the other answer and it solved my problem. The player can now move, jump and flip. \$\endgroup\$
    – Ali
    Dec 3 '20 at 20:46
  • \$\begingroup\$ The only thing that should be fixed is transform.Translate because it makes a vibrating effect when the player collides with the wall and sometimes it moves slightly to the right or the left. I might ask another question about this. Thank you for everything! \$\endgroup\$
    – Ali
    Dec 3 '20 at 20:49
  • \$\begingroup\$ @Ali That's probably physics correcting your movement. Basically you are pushing your character into the wall with the movement code and the physics engine is pushing him/her out with it's own code. To get around that just raycast in the direction you want to move and stop them before going into the next collider or make the physics engine handle movement by either calling rigidBody.MovePosition(nextPosition) (only works on non-kinematic rigidbodies) or using rigidBody.velocity = movementdirection * speed; \$\endgroup\$ Dec 4 '20 at 1:51
  • \$\begingroup\$ @BenjaminDangerJohnson I want to use rb.MovePosition but I'm not sure what position (parameter) I should pass into it and what variables I need to add before this. Could you please tell me the exact code that I have to write, based on the player controller above? \$\endgroup\$
    – Ali
    Dec 5 '20 at 4:10
  • \$\begingroup\$ @Ali I don't really have time to check but I would guess it is something like rb.MovePosition(transform.position + (speed * Time.deltaTime * movementInput)); There maybe a boolean flag as well to specify if the position is global or local but I don't really know of the top of my head. Anyway I believe it will work if you replace your transform.Translate line with that but without testing I'm not really sure. \$\endgroup\$ Dec 6 '20 at 6:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.