首页 > 其他分享 >Unity Character Controller移动控制(第一人称)

Unity Character Controller移动控制(第一人称)

时间:2022-10-20 01:45:17浏览次数:74  
标签:isGround float Character Unity private Controller Time velocity public

目录

Character Controller组件

官方文档:https://docs.unity.cn/cn/2019.4/Manual/class-CharacterController.html

1. 移动

直接上代码:

public class PlayerController : MonoBehaviour
{
    //获取组件
    public CharacterController characterController;

    //设置移动和跳跃速度
    public float moveSpeed;
    //定义按键输入
    public float getHorizontal, getVertical;
    //定义移动向量
    private Vector3 dir;

    private void Start()
    {
        moveSpeed = 4;  
        characterController = GetComponent<CharacterController>();
    }

    private void Update()
    {
        getHorizontal = Input.GetAxis("Horizontal") * moveSpeed;
        getVertical = Input.GetAxis("Vertical") * moveSpeed;

        dir = transform.forward * getVertical + transform.right * getHorizontal;

        characterController.Move(dir * Time.deltaTime);
    }
}

2. 重力和跳跃

2.1 重力

  • 定义重力、向下的速度(通过计算得出)
  • 判断物体是否在地面上,不在时开始计算向下的速度
  • 通过physics.CheckSphere方法判断物体是否在地面上
  • 需要定义目标点transform、检测半径float、检测图层LayerMask来进行判断
    代码:
public class PlayerController : MonoBehaviour
{
    //定义重力和下落加速度
    public float gravity = 9.8f;
    private Vector3 velocity = Vector3.zero;

    //定义bool值判断角色是否在地面上
    public bool isGround;

    //定义一个目标点,一个检测半径,一个检测图层
    public Transform checkGround;
    public float checkRedius;
    public LayerMask checkLayer;

    private void Start()
    {
        checkRedius = 0.2f;
    }

    private void Update()
    {
        isGround = Physics.CheckSphere(checkGround.position, checkRedius, checkLayer);
        if (isGround && isJumping < 0.1)
        {
            velocity.y = 0;
        }

        velocity.y -= gravity * Time.deltaTime;
        characterController.Move(velocity * Time.deltaTime);
    }
}

2.2 跳跃

在这里遇到一个困难,如果直接用以下代码的话:

if (Input.GetButtonDown("Jump") && isGround)
{
    velocity.y = jumpSpeed;
}

理论上可行,但是通过实践发现根本跳不起来,猜测和在上一步添加重力时的这一段代码有关:

if (isGround && isJumping < 0.1)
{
    velocity.y = 0;
}

在起跳的时候程序又执行到这一部分,导致角色的velocity.y=0,从而使角色不能跳跃
暂时想到的解决办法就是添加一个计时器,让在起跳0.1秒内不再执行判断isGround的代码
通过修改后,PlayerController代码如下:

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

public class PlayerController : MonoBehaviour
{
    //获取组件
    public CharacterController characterController;

    //设置移动速度
    public float moveSpeed;
    //定义按键输入
    public float getHorizontal, getVertical;
    //定义移动向量
    private Vector3 dir;

    //定义跳跃速度和跳跃状态
    public float jumpSpeed;
    public float isJumping;
    //定义重力和下落加速度
    public float gravity = 9.8f;
    private Vector3 velocity = Vector3.zero;

    //定义bool值判断角色是否在地面上
    public bool isGround;

    //定义一个目标点,一个检测半径,一个检测图层
    public Transform checkGround;
    public float checkRedius;
    public LayerMask checkLayer;

    private void Start()
    {
        moveSpeed = 4;
        jumpSpeed = 5;
        checkRedius = 0.2f;
        characterController = GetComponent<CharacterController>();
        isJumping = 0.2f;
    }

    private void Update()
    {
        isGround = Physics.CheckSphere(checkGround.position, checkRedius, checkLayer);
        if (isGround && isJumping < 0.1)
        {
            velocity.y = 0;
        }

        getHorizontal = Input.GetAxis("Horizontal") * moveSpeed;
        getVertical = Input.GetAxis("Vertical") * moveSpeed;

        dir = transform.forward * getVertical + transform.right * getHorizontal;

        characterController.Move(dir * Time.deltaTime);

        if (Input.GetButtonDown("Jump") && isGround)
        {
            velocity.y = jumpSpeed;
            isJumping = 0.2f;
        }
        if(isJumping > 0)
        {
            isJumping -= Time.deltaTime;
            Debug.Log(isJumping);
        }

        velocity.y -= gravity * Time.deltaTime;
        characterController.Move(velocity * Time.deltaTime);
    }
}

** 如果有关于玩家跳跃的更好解决办法,欢迎发表在评论区 **

实现第一人称视角控制

前面完成了前后左右移动和跳跃,这一步完成一个第一视角的转动功能
将Camera拖到Player的节点下,调整位置,然后为Camera添加脚本:

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

public class CameraController : MonoBehaviour
{
    public Transform Player;

    private float mouseX, mouseY;   //获取鼠标移动的值

    public float mouseSensitivity;  //鼠标灵敏度

    private float xRotation;

    private void Start()
    {
        mouseX = 0;
        mouseY = 0;
        mouseSensitivity = 800;
    }
    private void Update()
    {
        mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
        mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;

        xRotation -= mouseY;

        if (xRotation > 90)
        {
            xRotation = 90;
        }
        else if (xRotation < -90)
        {
            xRotation = -90;
        }

        Player.Rotate(Vector3.up * mouseX);
        transform.localRotation = Quaternion.Euler(xRotation, 0, 0);
    }
}

完成!

标签:isGround,float,Character,Unity,private,Controller,Time,velocity,public
From: https://www.cnblogs.com/su-make/p/16808243.html

相关文章

  • 29. unity代码种树之删除树
    从treeinstance[]  treeInstances里删除树 然后设置terraindata.treeinstances=treeInstances 更新terraindata   再刷新地图数据  terrain.Flush();......
  • winXP immunity debugger 运行mona插件报错,解决方法
    报错内容报错内容提示如下:AttributeError:'list'objecthasnoattribute'update'找到问题所在为:File"C:\DocumentsandSettings\lrt\桌面\ImmunityDebugger-mast......
  • Unity IO 加载图片
    ///<summary>///以IO方式进行加载///</summary>privatevoidLoadByIo(stringurl,GameObjectImageOBJ){//创建文件读取流FileStream......
  • unity3D mirror网络游戏开发笔记
    最近想开发一款多人在线网络游戏,使用unity3d的mirror插件可以提高开发效率,并且该插件免费。但是由于使用插件开发效率太低,经过研究,ummorpg开发模板是居于该插件开发而来,使......
  • C#与unity学习
    C#与unity学习unity中产创建c#文件在unity中新建project,为方便管理可以在assets文件内创建scripts文件夹,将所有的c#文件集中在此文件夹中管理。在vsstudio中创建c#​ ......
  • java--Integer和Character常用方法
    //装箱:基本类型转换为包装类对象。通过包装类.valueOf();实现//Integernum2=Integer.valueOf(100);   Integernum1=100;   Integernum3=newInte......
  • useUnicode=true&characterEncoding=UTF-8 的作用
    我们在连接mysql数据库的时候一般都会在url后面添加useUnicode=true&characterEncoding=UTF-8,但是问什么要添加呢?添加的作用是:指定字符的编码、解码格式。例如:mysql数......
  • unity发布WebGL版本与前端交互
    由unity官方给该的方法亲测无法成功传参,故亲手写一篇相关教程,开发中实测下列方式可用。 unity发消息给前端:1.首先在unity的Plugins文件夹下创建一个后缀为.jslib(例:Web......
  • 【100个 Unity实用技能】| C# 检查字典中是否存在某个Key的几种方法
    Unity小科普老规矩,先介绍一下Unity的科普小知识:Unity是实时3D互动内容创作和运营平台。包括游戏开发、美术、建筑、汽车设计、影视在内的所有创作者,借助Unity将创意变......
  • Unity3D移动控制
    目录Unity中移动脚本1.通过Transform组件移动物体1.1Transform.Position1.2Transform.Translate1.3Vector3.Lerp,Vector3.Slerp,Vector3.MoveTowardsVector3(插值)......