关于如何边学习边制作自己的第一个Unity 3D小游戏的日常

前言

起初,是为了完成大四毕业设计而起的念头,也是为了完成自己的一个小小的私心。关于使用 Unity 引擎来完成这个小游戏(第三人称RPG)的制作,也是看中 Unity 入门较其他游戏引擎(如虚幻引擎UE)来看简单些许,而且可用资源丰富,上手难度较低。毕业设计给的时间相对较少,本人也有较严重的拖延症…。综上,这是一个持续更新系列,记录博主对 Unity 引擎的学习,实践过程。



一、关于角色视角控制

在我的项目里,从新手的角度上看,我采用脚本控制摄像机(Camera)的方式来观察主角玩家(Player),贴上摄像机(Camera)代码:

public class CameraController : MonoBehaviour
{
    public float sensitivityMouse = 2f;
    // 绑定观察角色
    public Transform target;

    // 观察距离
    public float Distance = 6f;

    // 旋转角度
    private float mX = 0f;
    private float mY = 0f;

    // 纵向Y轴 角度限制
    private float MinLimitY = 5;
    private float MaxLinitY = 30;

    // 是否启用插值??:3D化,更加难受
    public bool isNeedDamping = false;
    // 观察插值
    public float Damping = 2f;

    void Update()
    {
    }

    void LateUpdate()
    {
        // 获取鼠标位置输入
        mX += Input.GetAxis("Mouse X") * sensitivityMouse * 0.8f;
        mY -= Input.GetAxis("Mouse Y") * sensitivityMouse * 0.5f;

        // 范围限制
        mY = ClampAngle(mY, MinLimitY, MaxLinitY);

        // 重新计算位置和角度
        Quaternion mRotation = Quaternion.Euler(mY, mX, 0);
        Vector3 mPosition = mRotation * new Vector3(0.0f, 2.0f, -Distance) + target.position;

        // 设置相机的角度和位置
        if (isNeedDamping)
        {
            // 球形插值
            transform.rotation = Quaternion.Slerp(transform.rotation, mRotation, Time.deltaTime * Damping);
            // 线性插值
            transform.position = Vector3.Lerp(transform.position, mPosition, Time.deltaTime * Damping);
        }
        else
        {
            transform.rotation = mRotation;
            transform.position = mPosition;
        }
    }

    private float ClampAngle(float angle, float min, float max)
    {
        if (angle < -360)
            angle += 360;
        if (angle > 360)
            angle -= 360;
        return Mathf.Clamp(angle, min, max);
    }
}


二、关于角色移动控制

既然是实现一个第三人称RPG(如黑神话-悟空)类型的小游戏,那么角色的流畅控制就很重要了,这里需要学习的地方主要有:脚本 + 动画。脚本的话,新手主要还是网上(百度 + 官网)借鉴别人的代码学习(避免闭门造车)。这里简单地贴上玩家角色(Player)的脚本代码:

public class PlayerController : MonoBehaviour
{
    Animator anim;
    [Header("角色")]
    public CharacterController controller;

    [Header("跟随摄像机")]
    public Transform FollowedCamera;
    [Header("移动速度")]
    public float moveSpeed = 8f;
    
    // 要到达目标位置的近似时间,实际到达目标时要快一些。
    [Header("转身缓冲速度")]
    public float trunSnoothTime = 0.1f;
    
    // 当前速度,这个值在你访问这个函数的时候会被随时修改
    [Header("当前速度")]
    float trunSmoothVelocity;

    // 动画状态组件
    private AnimatorStateInfo animatorInfo;

    void Start()
    {
        anim = GetComponent<Animator>();
        controller = GetComponent<CharacterController>();
    }


    void Update()
    {
        // 角色移动
        PlayerMovement();
    }

    void PlayerMovement()
    {
        // Player 的移动方向:初始化
        Vector3 moveDir = Vector3.zero;

        // 未添加:Player 的移动判断:方向转正再移动
        float horizontal = Input.GetAxisRaw("Horizontal");
        float vertical = Input.GetAxisRaw("Vertical");

        // Player:随摄像头正前方,WASD移动
        if (horizontal != 0 || vertical != 0)
        {
            anim.SetBool("Walk", true);

            Vector3 P_direction = new Vector3(horizontal, 0, vertical).normalized;
            if (P_direction.magnitude >= 0.1f)
            {
                // 根据按键【当前角度 ——(转向)——> 目标角度】
                float N_targetAngle = Mathf.Atan2(P_direction.x, P_direction.z) * Mathf.Rad2Deg + FollowedCamera.eulerAngles.y;
                // 平滑阻尼: Mathf.SmoothDamp(...)
                float N_angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, N_targetAngle, ref trunSmoothVelocity, trunSnoothTime);
                transform.rotation = Quaternion.Euler(0f, N_angle, 0f);

                // 获取当前朝向角度并移动
                Vector3 N_moveDir = Quaternion.Euler(0f, N_targetAngle, 0f) * Vector3.forward;
                controller.Move(N_moveDir.normalized * moveSpeed * Time.deltaTime);
            }
        }
        // 无任何操作,保持站立动画
        else if (horizontal == 0 && vertical == 0)
        {
            anim.SetBool("Walk", false);
        }
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值