Unity beginner 1 - character movement control (2d)

This article comes from the notes of teacher chutianbo. Link to station b
. Moving characters in unity generally uses the coordinate axis based on the position in the control character’s transition attribute, which is generally the xy axis of the binary linear equation.

the easiest move

public class RubyController : MonoBehaviour
{
    // 每帧调用一次 Update
    // 让游戏对象每帧右移 0.1
    void Update()
    {
        // 创建一个 Vector2 对象 position,用来获取当前对象的位置
        Vector2 position = transform.position;
        // 更改 position 的 x 坐标值,让其 加上 0.05
        position.x = position.x + 0.05f;
        // 更新当前对象的位置到新位置
        transform.position = position;
    }
}

Then every frame our character will move 0.05 distance to the positive axis of x (the higher the number of frames, the faster the movement).

move with control

public class RubyController : MonoBehaviour
{
   // 每帧调用一次 Update
    // 让游戏对象每帧右移 0.1
    void Update()
    {
        // 获取水平输入,按向左,会获得 -1.0 f ; 按向右,会获得 1.0 f
        float horizontal = Input.GetAxis("Horizontal");
        // 获取垂直输入,按向下,会获得 -1.0 f ; 按向上,会获得 1.0 f
        float vertical = Input.GetAxis("Vertical");

        // 获取对象当前位置
        Vector2 position = transform.position;
        // 更改位置
        position.x = position.x + 0.1f * horizontal;
        position.y = position.y + 0.1f * vertical;
        // 新位置给游戏对象
        transform.position = position;
    }
}

This seems to use the components that come with unity to move, by getting the default vertical keys and horizontal cases, which directly correspond to wasd and arrow keys.

The second way to control movement

public class RubyController : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
    
        Vector2 position = transform.position;

        if (Input.GetKey("w"))
        {
            position.y = position.y + 0.05f;
        }else if (Input.GetKey("a"))
        {
            position.x = position.x - 0.05f;
        }else if (Input.GetKey("s"))
        {
            position.y = position.y - 0.05f;
        }
        else if(Input.GetKey("d")){
            position.x = position.x +0.05f;
        }

        
       
        transform.position = position;
    }
}

Use getkey to customize the control method

But the difference between the GetKey and GetAxis methods used in the first and second is that. GetKey only has the difference between 0 and 1, there will be no 0.5 or 0.05. But getAxis is a smooth curve (recommended for mobile controls).

Disadvantages of directly using update to move

Since the update call is directly linked to the number of game frames, that is, one update is called per frame, so the higher your frame number, the faster the character moves. Assuming the
game is 30 frames, then 0.1f moves in one second, which is 0.1*30 is 3 units. If it is 60 frames, one second is 6 units.

Method 1 to solve the problem that the number of frames affects the movement rate: lock the frame

  void Start()
    {
    //开垂直同步//
        QualitySettings.vSyncCount = 0;
        //帧率设置为50//
        Application.targetFrameRate = 50;
    }

But locking the frame will reduce the quality of the game picture, so we use the unit of second to control Ruby's actions

Temporary final solution

public class RubyController : MonoBehaviour
{
 public float speed = 0.1f;
 // Start is called before the first frame update
 void Start()
 {

 }

 // Update is called once per frame
 void Update()
 {
     float horizontal = Input.GetAxis("Horizontal");
     float vertical = Input.GetAxis("Vertical");
     Vector2 position = transform.position;
     position.x = position.x + speed * horizontal * Time.deltaTime;
     position.y = position.y + speed * vertical * Time.deltaTime;
     transform.position = position;
 }
}

In this way, we will find that when speed=5, we can get the original speed of 0.1 when using frame control;

Solve the bug when colliding

If we control the movement according to the last code above, then we will find that when the two rigid bodies collide, our character will appear ghostly, that is, our position first enters the position occupied by the collision body, and then is ejected, so Here we need to introduce the rigid body component of the object to solve

void Start()
 {
     //获得当前游戏对象的刚体组件
     rigidbody2d = GetComponent<Rigidbody2D>();


 }
   void Update()
 {
    horizontal = Input.GetAxis("Horizontal");
    vertical = Input.GetAxis("Vertical");

 }
 //固定时间间隔刷新方法
 private void FixedUpdate()
 {
    
     Vector2 position = transform.position;
     position.x = position.x + speed * horizontal * Time.deltaTime;
     position.y = position.y + speed * vertical * Time.deltaTime;
     rigidbody2d.position = position;
 }

Here we need to put the acquisition movement in update, because it is called one frame at a time, which will be smoother, and it is about 20ms to call in FixedUpdate.

Well, the regular bug time
is after the above set of movement using the physics system. After we add the enemy movement later, after colliding with other powerful objects, our protagonist will also get a force in the direction of movement of another object. (About the robot walking down, the protagonist is collided under the robot, the protagonist will go down until it hits other colliders)
According to the answer, the rigid body movement cannot directly use the position assignment
, so rigidbody2d.position = position; this sentence we have to change into rigidbody2d.MovePosition(position);

This article is only for personal initial learning of unity
Link: Ruby's Adventure: 2D Beginner
Link: What is Vertical Synchronization
Link: Official documentation of Time.deltaTime

Guess you like

Origin blog.csdn.net/jijikok/article/details/125732414