Unity3D-实现第一人称人物动作: 走,跑,跳,移动视角

需要物体:一个用于移动的对象,一个主摄像机,一个地面对象,且摄像机的父结点为移动对象
旋转移动坐标示意图:
在这里插入图片描述

用于视角移动的代码(给摄像机的):

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

public class CameraTurn : MonoBehaviour
{
    // 水平视角移动的敏感度
    public float sensitivityHor = 3f;
    // 垂直视角移动的敏感度
    public float sensitivityVer = 3f;
    // 视角向上移动的角度范围,该值越小范围越大
    public float upVer = -40;
    // 视角向下移动的角度范围,该值越大范围越大
    public float downVer = 45;
    // 垂直旋转角度
    private float rotVer;

    // 旋转的方向问题
    // x 表示绕 x 轴旋转,即 前上后 的角度
    // y 表示绕 y 轴旋转,即 左前后 的角度
    // y 表示绕 y 轴旋转,即 左前后 的角度

    // Start is called before the first frame update
    void Start()
    {
        // 初始化当前的垂直角度
        rotVer = transform.eulerAngles.x;
    }

    // Update is called once per frame
    void Update()
    {
        // 获取鼠标上下的移动位置
        float mouseVer = Input.GetAxis("Mouse Y");
        // 获取鼠标左右的移动位置
        float mouseHor = Input.GetAxis("Mouse X");
        // 鼠标往上移动,视角其实是往下移,所以要想达到视角也往上移的话,就要减去它
        rotVer -= mouseVer * sensitivityVer;
        // 限定上下移动的视角范围,即垂直方向不能360度旋转
        rotVer = Mathf.Clamp(rotVer, upVer, downVer);
        // 水平移动
        float rotHor = transform.localEulerAngles.y + mouseHor * sensitivityHor;
        // 设置视角的移动值
        transform.localEulerAngles = new Vector3(rotVer, rotHor, 0);
    }
}

用于物体移动的控制器(给要移动的物体的):

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

// 表示一定需要这个控件
[RequireComponent(typeof(CharacterController))]
public class Move : MonoBehaviour {
    // 获取摄像机对象的位置信息,[SerializeField] 类似于 java 的构造方法的方法参数
    [SerializeField] private Transform target;
    // 跳起来的速度
    public float jumpSpeed = 15.0f;
    // 重力
    public float gravity = -9.8f;
    // 最终垂直速度
    public float endsVelocity = -10.0f;
    // 在地面时的垂直速度
    public float minFall = -1.5f;
    // 跑起来的速度
    public float runSpeed = 10;
    // 走路的速度
    public float walkSpeed = 4;
    // 垂直速度
    private float verSpeed;

    // 移动的速度
    private float moveSpeed;
    // 用于存储当前的角色控件
    private CharacterController character;

    // 在被加载时执行
    void Start() {
        // 初始化
        character = GetComponent<CharacterController>();
        verSpeed = minFall;
        moveSpeed = walkSpeed;
    }
    // 每更新一帧时执行
    void Update() {
        // 用于存储移动信息
        Vector3 movement = Vector3.zero;
        // 获取左右方向的移动信息
        float horspeed = Input.GetAxis("Horizontal");
        // 获取前后方向的移动信息
        float verspeed = Input.GetAxis("Vertical");
        // 当发生了移动才执行
        if (horspeed != 0 || verspeed != 0) {
            // 设置左右位置
            movement.x = horspeed * moveSpeed;
            // 设置前后的位置
            movement.z = verspeed * moveSpeed;
            // 设置斜着走的最大速度更水平垂直走的速度一样
            movement = Vector3.ClampMagnitude(movement, moveSpeed);
            // 将移动的信息转化为以摄像机为全局坐标的位置,即保证你向前走一定是摄像机的视角方向
            movement = target.TransformDirection(movement);
        }
        // 当按下左 shift 是跟换速度
        if (Input.GetKey(KeyCode.LeftShift)) {
            moveSpeed = runSpeed;
        } else {
            moveSpeed = walkSpeed;
        }
        // 角色控件自带的一个方法,用于检测是否在地面
        if (character.isGrounded) {
            // 按了空格键则给垂直方向施加一个速度
            if (Input.GetButtonDown("Jump")) {
                verSpeed = jumpSpeed;
            } else {
                verSpeed = minFall;
            }
        } else {
            // 若已经跳起来了则将垂直方向的速度递减降低,来达到一个 下上下 的一个效果
            // Time.deltaTime 表示为每秒的刷新频率的倒数,用来控制每台电脑的移动速度都是一样的
            verSpeed += gravity * 3 * Time.deltaTime;
            // 限制最大坠落速度
            if (verSpeed < endsVelocity) {
                verSpeed = endsVelocity;
            }
        }
        // 给移动一个垂直速度
        movement.y = verSpeed;
        // 控制速度
        movement *= Time.deltaTime;
        // 角色控件自带的一个方法,若用 transform.Translate() 的话会无视碰撞器
        character.Move(movement);
    }
}
  • 22
    点赞
  • 159
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值