Unity3D 游戏开发:角色移动(5)

一、物理系统

1、添加Box collider 2D组件

注意位置的调节

image.png

2、添加Rigidbody 2D组件

注意横板2D游戏重力(Gravity Scale)为0

image.png

碰撞后抖动问题的解决:

因为人物添加了Box Collider 2D 和刚体,因此当碰撞后会模拟实际的运动情况,和其它碰撞体碰撞后会发生抖动;

解决方法:

通过刚体控制物体的运动和位置,而不是通过 transfrom.position 来获得物体的位置并更新;

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


public class PlayerController : MonoBehaviour
{
public float speed = 5f;

    Rigidbody2D rbody;//刚体组件

    // Start is called before the first frame update
    void Start()
    {
        rbody = GetComponent<Rigidbody2D>();
    }

    // Update is called once per frame
    void Update()
    {
        float moveX = Input.GetAxisRaw("Horizontal");
        float moveY = Input.GetAxisRaw("Vertical");

        Vector2 position = rbody.position;
        position.x += moveX * speed * Time.deltaTime;
        position.y += moveY * speed * Time.deltaTime;

        rbody.MovePosition(position);
    }

}

解决碰撞后角色会旋转的问题

通过为Rigidbody 2D 添加约束实现,冻结z轴即可:

image.png

image.png

二、脚本编程

  1. 在Awake方法中获取Rigidbody2D组件,用于后续控制该物体的运动。
  2. 在Update方法中调用PlayerInput()方法,获取玩家的输入信息(水平和垂直方向上的输入)。
  3. 在FixedUpdate方法中调用Movement()方法,根据玩家的输入信息来控制物体的运动,使用Rigidbody2D.MovePosition方法使物体移动到目标位置。

具体实现细节如下:

  1. PlayerInput()方法:获取玩家的水平和垂直方向上的输入信息,如果两个方向都有输入,则将它们分别缩小0.6倍,以避免物体沿对角线运动过快的问题。
  2. Movement()方法:根据玩家输入信息计算出角色目标位置,然后使用Rigidbody2D.MovePosition方法重新设置物体的位置。movmentInput变量是一个Vector2类型的变量,表示玩家的运动输入信息(包括水平和垂直方向上的输入)。
    private void Awake()
    {
        rb = GetComponent<Rigidbody2D>(); 


    }

    private void Update()
    {
        PlayerInput();
    }
    private void FixedUpdate()
    {
        Movement(); 
    }
    private void PlayerInput()
    {
        inputX = Input.GetAxisRaw("Horizontal");
        inputY = Input.GetAxisRaw("Vertical");
        if (inputX != 0 && inputY != 0)
        {
            inputX = inputX * 0.6f;
            inputY = inputY * 0.6f;
        }
        movementInput=new Vector2(inputX, inputY);
    }
    private void Movement()
    {
        rb.MovePosition(rb.position + movementInput * Time.deltaTime);
    }
}

三、初步了解脚本编程

1、在Unity中,还有一些可以与Awake()类似使用的函数,例如:

  1. Start(): 在脚本启用时调用,与Awake()类似,但是它会等待所有Awake()函数都执行完毕后再执行。如果您需要在脚本启动时进行初始化操作,可以使用Start()。
  2. OnEnable(): 当脚本从非活动状态变为活动状态时调用,可以用来进行状态转换、数据恢复或者其他处理。在脚本没被禁用时,同样会在实例化对象后第一次调用。
  3. OnDisable(): 当脚本从活动状态变为非活动状态时调用,可以用于暂停处理,以及释放资源等操作。

这些函数与Awake()类似,都是在脚本启动时立即调用的函数,不过它们的执行顺序和作用略有不同,根据实际需求选择合适的函数来使用。

2、在Unity中,除了Update()函数之外,还有一些可以与Update()类似使用的函数,例如:

  1. FixedUpdate(): 与Update()类似,但是它在固定时间间隔内运行(通常为0.02秒),适用于需要进行物理模拟的场景。如果需要移动物体、修改刚体参数等,应该使用FixedUpdate()。
  2. LateUpdate(): 在所有Update()函数执行完后调用,适合处理摄像头跟随或其他需要在Update之后处理的逻辑。LateUpdate()会确保所有Update()函数都已经执行完毕。
  3. OnGUI(): 在每帧渲染完成后调用,用于绘制GUI界面。如果需要在屏幕上显示一些信息或按钮等,可以使用OnGUI()。

总的来说,这些函数的作用与Update()类似,但它们各有所长,在不同场景下使用会更加优化和高效。

3.在Unity中,还有两个跟FixedUpdate()函数类似的函数,分别是:

  1. FixedUpdate2D(): 与FixedUpdate()类似,但是它用于2D物理引擎模拟中。如果您需要对2D物理引擎进行操作,可以使用FixedUpdate2D()函数。
  2. OnTriggerStay(): 在物体与触发器保持接触时调用。如果您需要检测物体与触发器的接触状态并进行处理,可以使用OnTriggerStay()函数。

这些函数和FixedUpdate()函数都是固定时间间隔内执行的函数,使用起来比Update()函数更加精确和准确。不过,这些函数也各有适用的场景,需要根据具体需求选择合适的函数来使用。

4、在Unity中,与MovePosition类似的函数包括:

  1. transform.position: 直接设置游戏对象的位置。例如,可以使用以下代码将游戏对象移动到(1, 0, 0)处:
transform.position = new Vector3(1.0f, 0.0f, 0.0f);

由于它直接设置游戏对象的位置,因此不应该在FixedUpdate函数中使用,而应该在Update函数中使用。

  1. Rigidbody.velocity: 设置刚体的速度,使其在下一帧朝着指定方向移动。例如,可以使用以下代码让刚体向右移动:
rigidbody.velocity = new Vector2(1.0f, 0.0f);

需要注意的是,这种方式受到物理引擎的影响,例如重力、摩擦等。

  1. CharacterController.Move(): 将角色控制器移动到目标位置,忽略物理引擎的影响。例如,可以使用以下代码将角色控制器向前移动:
characterController.Move(transform.forward * moveSpeed * Time.deltaTime);

需要注意的是,这种方式只适用于角色控制器,并且也不应该在FixedUpdate函数中使用。

总之,这些方法都可以用来移动游戏对象,但是每种方法受到的约束和限制不同,需要根据具体需求选择合适的方法来使用。

5、在Unity中,与PlayerInput()类似的函数包括:

  1. Input.GetAxis(): 获取按键输入的浮点数,根据按键输入的不同而产生变化。例如,可以使用以下代码获取水平方向上键盘、摇杆等的输入:
float horizontal = Input.GetAxis("Horizontal");

这里的”Horizontal”是一个虚拟的输入轴,可以通过Project Settings -> Input面板进行设置。该函数返回一个浮点数,表示按键输入的强度。

  1. Input.GetKeyDown(): 判断是否按下了某个按键,例如键盘上的某个按键。例如,可以使用以下代码判断玩家是否按下了空格键:
if (Input.GetKeyDown(KeyCode.Space)) 
{
    // do something...
}

需要注意的是,该函数只对按下瞬间有效,如果需要持续检测按键是否按下,可以使用Input.GetKey()。

  1. Input.GetMouseButtonDown(): 判断是否按下了鼠标按钮。例如,可以使用以下代码判断玩家是否按下了鼠标左键:
if (Input.GetMouseButtonDown(0)) {
    // do something...
}

需要注意的是,该函数只对按下瞬间有效,如果需要持续检测鼠标按钮是否按下,可以使用Input.GetMouseButton()。

总之,这些函数都可以用来检测用户输入,但是每个函数有其各自的特点和限制,需要根据具体需求选择合适的函数来使用。

6、在Unity中,与Movement()类似的函数包括:

  1. Rigidbody.AddForce(): 物体受到力的作用,产生加速度并移动。例如,可以使用以下代码为刚体施加一个向右的力:
rigidbody2D.AddForce(Vector2.right * moveSpeed);

需要注意的是,该方法会受到刚体的质量、摩擦等物理属性的影响。

  1. Rigidbody.velocity: 直接设置物体的速度,使其在下一帧朝着指定方向移动。例如,可以使用以下代码让刚体向右移动:
rigidbody2D.velocity = new Vector2(moveSpeed, 0);

这种方式同样受到刚体的质量、摩擦等物理属性的影响。

  1. Transform.Translate(): 直接修改物体的Transform组件的位置,可传入相对或绝对位移。例如,可以使用以下代码将物体向右移动:
transform.Translate(Vector3.right * moveSpeed * Time.deltaTime);

需要注意的是,该方法不受物理引擎的影响,可能会导致物体卡在墙壁或其他物体里面。

总之,这些方法都可以用来移动游戏对象,但每个方法受到的限制和约束不同,需要根据具体需求选择合适的方法来使用。

阅读更多作者文章:

# Unity3D 游戏开发:创建人物(4)

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYfFPgb3' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片