前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[学习笔记]DarkSouls复刻(1)-角色控制器

[学习笔记]DarkSouls复刻(1)-角色控制器

作者头像
六月丶
发布2022-12-26 17:33:26
3560
发布2022-12-26 17:33:26
举报
文章被收录于专栏:六月-游戏开发六月-游戏开发

简介

Unity3d脚本知识已经入门了,然后从今天开始做黑魂复刻,教程取自傅老师的DarkSouls复刻经典教程,av21513489。因为一遍做到底容易忘,那样做完就没有意义了,所以我打算一边学着做一边写博客记录过程,这样以后有哪个unity操作步骤忘了也方便查找笔记。因为是笔记,所以不会写的太详细,步骤一步过,脚本会说的细一点,那么就开始吧。

制作流程

1.新建一个3d项目,把素材导入
1_导入素材.png
1_导入素材.png
2.创建一个名为Materials的文件夹,在里面创建一个Material,并把在textures上下的材质图贴上对应的位置
2_添加Material.png
2_添加Material.png
3.创建一个plane,并把Material贴上去,再创建一个capsule,命名为PlayerHandle,把模型yBot拖进PlayerHandle中,重命名为model
3_添加模型.png
3_添加模型.png
4.修改PlayerHandle的组件,并添加PlayerInput、ActorController两个脚本:
4_PlayerHandle组件修改.png
4_PlayerHandle组件修改.png
5.再添加一个动画控制器:创建一个文件夹名为animator,在里面创建一个animator Controller,名为Actor,双击打开
5_Actor.png
5_Actor.png
6.创建一个前进动画的混合树,名为forward。
6_1_创建混合树.png
6_1_创建混合树.png
6_2_修改名字.png
6_2_修改名字.png
7.把yBot的idle4和walk动画添加进混合树:
7_1_添加动画.png
7_1_添加动画.png
7_2_导入动画.png
7_2_导入动画.png
7_3_混合数动画设置信息.png
7_3_混合数动画设置信息.png
8.把Actor导入model的animator中
8_导入动画控制器.png
8_导入动画控制器.png
9.创建一个文件夹Scripts,把脚本拖进去
9_放入scripts中.png
9_放入scripts中.png

这时编写好脚本(见下)后就可以行走了,但是此时走的只是模型本身,而Playerhandle并没有移动,所以我们得换一种移动方式,让Rigidbody移动。所以需要加上rigidbody组件

9_GIF.gif
9_GIF.gif
10.给Playerhandle附上Rigidbody组件,并把constraints的rotation的xyz勾上
10_添加rigidbody组件.png
10_添加rigidbody组件.png
11.取消勾选animator的apply root Motion选项
11.取消勾选.png
11.取消勾选.png

脚本编写

当前有ActorController和PlayerInput两个脚本,其中PlayerInout用于做角色的控制器输入,PlayerInput中定义了四个方向键和dUp与dRight作为上和右的移动量,取值[0,1),因为如果直接用Input.GetKey判断是否按下而将值在0和1两数中变化就太生硬了,所以可以用Mathf.SmoothDamp来让dUp和dRight有一个过渡。

代码语言:javascript
复制
//注意,变量都为全局变量而不能在update中定义
targetUp = (Input.GetKey(upKey) ? 1.0f : 0) - (Input.GetKey(bottomKey) ? 1.0f : 0);
targetRight = (Input.GetKey(rightKey) ? 1.0f : 0) - (Input.GetKey(leftKey) ? 1.0f : 0);
dUp = Mathf.SmoothDamp(dUp, targetUp, ref velocityDUp, 0.1f);
dRight = Mathf.SmoothDamp(dRight, targetRight, ref velocityDRight, 0.1f);

移动量可以用勾股定理算出dUp和dRight的组合量作为移动量,代码为

代码语言:javascript
复制
dMag = Mathf.Sqrt(dUp * dUp + dRight * dRight);

不过这会有一个bug,当角色斜向走时,移动量为根号2,显然比1快,这个问题先放着以后再来解决。 而要求实际移动向量,可以用移动量dMag乘模型的前向量model.transform.forward,为了让移动速度和动画同步防止出现太空步的问题,还需要乘一个walkSpeed,值根据动画来设,这里我设为1.5f。

代码语言:javascript
复制
//movingVec为Vector3,walkSpeed为float
movingVec = pi.dMag * model.transform.forward * walkSpeed;  

PlayerInput.cs

代码语言:javascript
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerInput : MonoBehaviour
{
    public string upKey = "w";
    public string bottomKey = "s";
    public string leftKey = "a";
    public string rightKey = "d";

    public float dUp;
    public float dRight;
    [SerializeField]
    private float targetUp;
    private float targetRight;
    private float velocityDUp;
    private float velocityDRight;
    public float dMag;          //
    public Vector3 dVec;        //移动方向

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        targetUp = (Input.GetKey(upKey) ? 1.0f : 0) - (Input.GetKey(bottomKey) ? 1.0f : 0);
        targetRight = (Input.GetKey(rightKey) ? 1.0f : 0) - (Input.GetKey(leftKey) ? 1.0f : 0);
        dUp = Mathf.SmoothDamp(dUp, targetUp, ref velocityDUp, 0.1f);
        dRight = Mathf.SmoothDamp(dRight, targetRight, ref velocityDRight, 0.1f);
        dMag = Mathf.Sqrt(dUp * dUp + dRight * dRight) ;
        dVec = transform.forward * dUp + transform.right * dRight;
    }

}

ActorController.cs

代码语言:javascript
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ActorController : MonoBehaviour
{
    [SerializeField]
    private Animator animr;
    public PlayerInput pi;
    public GameObject model;
    private Rigidbody rigbody;
    public Vector3 movingVec;           //移动向量
    public float walkSpeed = 1.4f;
    // Start is called before the first frame update
    void Awake()
    {
        animr = model.GetComponent<Animator>();
        pi = GetComponent<PlayerInput>();
        rigbody = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {
        animr.SetFloat("forward", pi.dMag);
        if (pi.dMag > 0.1f)
            model.transform.forward = pi.dVec;
        movingVec = pi.dMag * model.transform.forward * walkSpeed;
    }

    private void FixedUpdate()
    {
        rigbody.position += movingVec * Time.fixedDeltaTime;
    }
}

完成效果

控制器效果.gif
控制器效果.gif
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019 年 11 月,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • 制作流程
    • 1.新建一个3d项目,把素材导入
      • 2.创建一个名为Materials的文件夹,在里面创建一个Material,并把在textures上下的材质图贴上对应的位置
        • 3.创建一个plane,并把Material贴上去,再创建一个capsule,命名为PlayerHandle,把模型yBot拖进PlayerHandle中,重命名为model
          • 4.修改PlayerHandle的组件,并添加PlayerInput、ActorController两个脚本:
            • 5.再添加一个动画控制器:创建一个文件夹名为animator,在里面创建一个animator Controller,名为Actor,双击打开
              • 6.创建一个前进动画的混合树,名为forward。
                • 7.把yBot的idle4和walk动画添加进混合树:
                  • 8.把Actor导入model的animator中
                    • 9.创建一个文件夹Scripts,把脚本拖进去
                      • 10.给Playerhandle附上Rigidbody组件,并把constraints的rotation的xyz勾上
                        • 11.取消勾选animator的apply root Motion选项
                        • 脚本编写
                        • 完成效果
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档