Unity 麦扣 x 勇士传说 全解析之Player运动(附各模块知识的链接,零基础也包学会的牢弟)(案例难度:★★☆☆☆)

请查看(2D)物理专栏 http://t.csdnimg.cn/rDJTo

1.人物刚体和碰撞器

Q:瓦片地图和碰撞体不贴合怎么办?

A:在该瓦片图集的精灵编辑器里面找到自定义物理形状后,将边缘容忍度设置高一些生成或者自定义点,做到尽量贴合 

Unity物理模块 之 ​2D刚体-CSDN博客

2.瓦片地图复合碰撞器

Unity物理模块 之 ​2D碰撞器-CSDN博客

3.输入配置文件

新输入系统请查看输入模块:

http://t.csdnimg.cn/gVXE5

为Player创建一个脚本和添加一个Player Input,创建默认InputActions(输入配置文件)我就叫PIC吧,生成C#代码

并且建议使用第三或者第四种监听方式,比较直观和方便

4.人物移动

可以用刚体加力,刚体速度,也可以用transform的直接移动,这块属于必会的基础部分,我没有写博客,所以干脆分别演示一下

Translate

  private PIC pic;

  public Vector2 wasdValue;

  //设置移动速度
  public float playerSpeed=50;
  
  private void OnEnable() {
      pic = new PIC();
      pic.Enable();
  }
  private void OnDisable() {
      pic.Disable();
  }

  private void Update() {

      wasdValue = pic.Player.Move.ReadValue<Vector2>();

      this.transform.Translate(playerSpeed* wasdValue*Time.deltaTime);   
  }

缺点也很明显,不符合物理特性,上下左右乱飞 

刚体加力 

 private PIC pic;

 public Vector2 wasdValue;

 //设置移动速度
 public float playerSpeed;
 //获取刚体组件
 private Rigidbody2D rb ;
 private void Awake() {
     playerSpeed = 20;
     rb = GetComponent<Rigidbody2D>();     
     pic = new PIC();
 }
 private void OnEnable() {
  
     pic.Enable();
 }
 private void OnDisable() {
     pic.Disable();
 }
 private void Update() {
     wasdValue = pic.Player.Move.ReadValue<Vector2>(); 
 }
 private void FixedUpdate() {
         rb.AddForce(wasdValue*Time.deltaTime,ForceMode2D.Impulse);
 }

额,刚体加力默认是以轴心点加力的,所以会造成旋转,因此要锁住z轴

刚体速度

    private PIC pic;

    public Vector2 wasdValue;

    //设置移动速度
    public float playerSpeed;
    //获取刚体组件
    private Rigidbody2D rb ;
    private void Awake() {
        playerSpeed = 20;
        rb = GetComponent<Rigidbody2D>();     
        pic = new PIC();
    }
    private void OnEnable() {
     
        pic.Enable();
    }
    private void OnDisable() {
        pic.Disable();
    }
    private void Update() {
        wasdValue = pic.Player.Move.ReadValue<Vector2>(); 
    }
    private void FixedUpdate() {
        rb.velocity= new Vector2(wasdValue.x*Time.deltaTime* playerSpeed,rb.velocity.y);
}

5.人物翻转

人物翻转有两种方法,用tansformscale或者sprite renderer的flip功能(我关于精灵渲染器的部分没有写这个小知识点,再次体会到了任何一处细节都有可能用得上)

tansformscale(要求pivot在人物左右的分割线上)

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

public class PlayerControl : MonoBehaviour
{
    private PIC pic;

    public Vector2 wasdValue;

    //设置移动速度
    public float playerSpeed;
    //获取刚体组件
    private Rigidbody2D rb ;

    private void Awake() {
        playerSpeed = 200;
        rb = GetComponent<Rigidbody2D>();     
        pic = new PIC();
    }
    #region 启用和禁用
    private void OnEnable() {

        pic.Enable();
    }
    private void OnDisable() {
        pic.Disable();
    }
    #endregion
    private void Update() {
        wasdValue = pic.Player.Move.ReadValue<Vector2>();
        //注意,不能直接修改transform xyz中的其中一个值
        Vector3 flip = this.transform.localScale;
        //翻转逻辑
        if (wasdValue.x > 0)
            { flip.x = wasdValue.x;
        this.transform.localScale = flip; }
        if (wasdValue.x < 0)
           { flip.x = wasdValue.x;
        this.transform.localScale = flip; }
    }
    

    private void FixedUpdate() {

        //加力逻辑
        rb.velocity= new Vector2(wasdValue.x*Time.deltaTime* playerSpeed,rb.velocity.y);

     
}
}

Sprite Renderer Flip(建议)

这样只需要两行逻辑就可以了,建议用这种方法

   //翻转逻辑
   if (wasdValue.x > 0)
       { 
       spriteRenderer.flipX = false;
   }
   if (wasdValue.x < 0)
      { 
       spriteRenderer.flipX = true;
  }

6.订阅跳跃事件

这还是不得不提到新输入系统,请查看本文第三个标题中链接专栏的内容

配置一下Action

我直接用lambda表达式 来订阅事件,因为没有太多复杂的输入的话,不必重用代码这样也会比较清晰:C# 匿名函数与Lambda表达式-CSDN博客 

注意参数,这实际上是使用的playerinput的第四种监听方式

  private void Update() {
      wasdValue = pic.Player.Move.ReadValue<Vector2>();

      pic.Player.Jump.started += (context) => {
          rb.AddForce(this.transform.up * jumpSpeed,ForceMode2D.Impulse);
      };
      

但是,这样可能存在不断订阅事件从而影响性能地问题

所以可以在disenble中添加一行,以移除所有回调函数

    pic.Player.Jump.RemoveAction();

7.连跳和分层检测

这一块和射线检测有关,重点在于物理组件中的检测方法,你可以在我链接中最后一部分找到它unity保姆级教程之 射线检测_unity 射线-CSDN博客

因为游戏中多物品的交互会比较复杂,所以要分层级去判断不同的影响方式,你也不想水和地面一样硬吧!

有些案例会通过api让你手搓一个简单的分层检测方法,这里我就直接和麦扣写一样了,这样比较方便,也有利于后续拓展

注意我设置了偏移量,因为我裁剪图集的时候中心点在center而不是botton 

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

public class PhysicsCheck : MonoBehaviour
{
    //地面检测
    public bool isGround;
    //检测半径
    public float raduis;
    //检测层级
    public LayerMask ground;
    //检测偏移量
   public Vector2 positionWithOffset;
    private void Start() {      
        raduis = 0.3f;       
    }
    private void Update() {
        Check();
    }
    private void Check()
        {
        positionWithOffset = new Vector2(this.transform.position.x-0.2f, this.transform.position.y - 1.0f);
        isGround = Physics2D.OverlapCircle(positionWithOffset, raduis, ground);
    }

    private void OnDrawGizmosSelected() {
        Gizmos.DrawWireSphere(positionWithOffset, raduis);
    }

}

 还有一个问题就是连跳,用isground判断就行了

   pic.Player.Jump.started += (context) => {
       if(physicsCheck.isGround=true)
       rb.AddForce(this.transform.up * jumpSpeed,ForceMode2D.Impulse);
   };

画辅助线我之前没在意这个细节,所以没有在博客中提到

  private void OnDrawGizmosSelected() {
      Gizmos.DrawWireSphere(positionWithOffset, raduis);
  }

 

 

  • 18
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值