前言:
这是我第一次发布文章,此文章仅供参考,我也是刚学习接触untiy,在制作项目的过程中将有用的写下来记一记,以便自己之后能回头看看,各位大佬轻点喷,若有错误请麻烦积极提谢谢各位。该文章参考自B站UP主蔡先森_rm-rf发布的【第一人称射击游戏教程2.0【已完结】】 https://www.bilibili.com/video/BV1J8411d75s/?p=54&share_source=copy_web&vd_source=a2427fab8ac35b158501cad28e7effe7
首先制作人物移动需要先制作一个场景和创建一个角色,这里就不再详细赘述如何创建了。
注意:最好创建一个空对象把角色(胶囊体)放进去,父对象坐标保持(0.0.0),仅对子对象进行微调即可,之后创建的父对象也要保持在原点,只动子对象。
创建好角色和场景之后新建文件夹Script创建新的脚本这里取名为PlayerController,将脚本负载到角色Character中,在Character对象里添加Character Controller(角色控制器)组件,修改一下他的半径和高度。
双击新建的脚本先给人物添加移动逻辑
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private CharacterController characterController;
private Vector3 moveDirction; //设置人物移动方向
[Header("玩家数值")]
public float Speed;
[Tooltip("行走速度")] public float walkSpeed;
[Tooltip("奔跑速度")] public float runSpeed;
[Header("键位设置")]
[Tooltip("奔跑按键")] public KeyCode runInputName = KeyCode.LeftShift;
[Tooltip("跳跃按键")] public KeyCode jumpInputName = KeyCode.Space;
[Header("玩家属性判断")]
private CollisionFlags collisionFlags;
public bool isWalk; //判断是否行走
public bool isRun; //判断是否奔跑
void Start()
{
characterController = GetComponent<CharacterController>();//获取角色自身控制器
walkSpeed = 4f;
runSpeed = 6f;
}
void Update()
{
Moving();
}
public void Moving()
{
float h = Input.GetAxisRaw("Horizontal");//检测是否按下键盘AD
float v = Input.GetAxisRaw("Vertical");//检测是否按下键盘WS
isRun = Input.GetKeyDown(runInputName);//如果按下左shift返回给isRun的值为true,说明玩家按下加速键
isWalk = (Mathf.Abs(h) > 0 || Mathf.Abs(v) > 0) ? true : false;
if (isRun)//奔跑行走速度
{
Speed = runSpeed;
}
else//正常行走速度
{
Speed = walkSpeed;
}
//设置人物移动方向,(normalized将速度进行规范化,防止斜向走速度变大)
moveDirction = (transform.right * h + transform.forward * v).normalized;
characterController.Move(moveDirction * Speed * Time.deltaTime);//人物移动
}
}
这里移动逻辑跟UP没差别,使用的是GetAxisRaw方法,这种方法实现的是即松即停,意思就是松开方向键就马上停下,不会再往前滑,但我想做的是松开方向键之后,人物还会往前滑一小段距离,按下反方向键做急停,方法如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private CharacterController characterController;
private Vector3 dir; //设置人物移动方向
[Header("玩家数值")]
public float Speed;
[Tooltip("行走速度")] public float walkSpeed;
[Tooltip("奔跑速度")] public float runSpeed;
[Header("键位设置")]
[Tooltip("奔跑按键")] public KeyCode runInputName = KeyCode.LeftShift;
[Tooltip("跳跃按键")] public KeyCode jumpInputName = KeyCode.Space;
[Header("玩家属性判断")]
private CollisionFlags collisionFlags;
public bool isWalk; //判断是否行走
public bool isRun; //判断是否奔跑
void Start()
{
characterController = GetComponent<CharacterController>(); //获取角色自身控制器
walkSpeed = 4f;
runSpeed = 6f;
}
void Update()
{
Moving();
}
public void Moving()
{
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
isRun = Input.GetKey(runInputName); //如果按下左shift返回给isRun的值为true,说明玩家按下加速键
isWalk = (Mathf.Abs(h) > 0 || Mathf.Abs(v) > 0) ? true : false;
if (isRun) //奔跑行走速度
{
Speed = runSpeed;
}
else //正常行走速度
{
Speed = walkSpeed;
}
Vector3 dir = new Vector3(h, 0, v);
dir = transform.TransformDirection(dir);
characterController.Move(dir * Speed * Time.deltaTime);
}
}
这样就能实现平滑移动的效果,就类似马里奥里地板抹油一样,更加舒服,后面我也会用该移动进行编写。
接下来是跳跃,跳跃的话在视频合集P9中写完之后发现人物走到高处掉不下去,UP也在后面补充了,我觉得都是属于跳跃逻辑就一并写完吧。代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class PlayerController : MonoBehaviour
{
private CharacterController characterController;
private Vector3 dir; //设置人物移动方向
[Header("玩家数值")]
public float Speed;
[Tooltip("行走速度")] public float walkSpeed;
[Tooltip("奔跑速度")] public float runSpeed;
[Tooltip("跳跃的力")] public float jumpForce;
[Tooltip("下落的力")] public float fallForce;
[Header("键位设置")]
[Tooltip("奔跑按键")] public KeyCode runInputName = KeyCode.LeftShift;
[Tooltip("跳跃按键")] public KeyCode jumpInputName = KeyCode.Space;
[Header("玩家属性判断")]
private CollisionFlags collisionFlags;
public bool isWalk; //判断是否行走
public bool isRun; //判断是否奔跑
public bool isJump; //判断是否跳跃
public bool isGound; //判断是否在地面上
void Start()
{
characterController = GetComponent<CharacterController>(); //获取角色自身控制器
walkSpeed = 4f;
runSpeed = 6f;
jumpForce = 0f;
fallForce = 10f;
}
void Update()
{
Moving();
Jump();
}
public void Moving()
{
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
isRun = Input.GetKey(runInputName); //如果按下左shift返回给isRun的值为true,说明玩家按下加速键
isWalk = (Mathf.Abs(h) > 0 || Mathf.Abs(v) > 0) ? true : false;
if (isRun) //奔跑行走速度
{
Speed = runSpeed;
}
else //正常行走速度
{
Speed = walkSpeed;
}
Vector3 dir = new Vector3(h, 0, v);
dir = transform.TransformDirection(dir);
characterController.Move(dir * Speed * Time.deltaTime);
}
public void Jump()
{
isJump = Input.GetKeyDown(jumpInputName);
//判断玩家按下跳跃键,并且此时在地上,才能进行跳跃
if (isJump && isGound)
{
isGound = false;
jumpForce = 5f; //设置跳跃力
}
//当前没有按下空格并且检测在地面上,那么isGround判断为false(修复在空中isGround还是判定为true的bug)
else if (!isJump && isGound)
{
isGound = false;
}
//此时按下跳跃键跳起来了,并且不在地上
if (!isGound)
{
jumpForce = jumpForce - fallForce * Time.deltaTime; //每秒将跳跃力进行累减,使其下落
Vector3 jump = new Vector3(0, jumpForce * Time.deltaTime, 0); //将跳跃力转化成v3坐标
collisionFlags = characterController.Move(jump); //调用角色控制器移动方法,向上方法模拟跳跃
/*判断玩家在地上
CollisionFlages:CharacterController 内置的碰撞位置标识号
CollisionFlags.Below -->在地上*/
if (collisionFlags == CollisionFlags.Below)
{
isGound = true;
jumpForce = -2f;
}
}
}
}
这样人物移动跳跃就已经做好了,剩下视角移动,我们先将Main Camera拖进我们创建的角色里做我们角色的子对象,将坐标轴重置,调整至合适位置,将剪裁调至0.01,在Script文件夹下创建MouseLook脚本,并将其拖入Main Camera内。
双击MouseLook脚本,输入以下代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 摄像机的旋转
/// 玩家左右旋转控制实现左右移动
/// 摄像机上下旋转控制视线上下移动
/// </summary>
public class MouseLook : MonoBehaviour
{
[Tooltip("鼠标灵敏度")] public float mouseSenstivity = 400f;
private Transform playerBody; //玩家位置
private float yRotation = 0f; //摄像机上下旋转
[Tooltip("当前摄像机的初始高度")] public float height = 1.8f;
void Start()
{
Cursor.lockState = CursorLockMode.Locked; //将鼠标隐藏并锁定在屏幕中心
playerBody = transform.GetComponentInParent<PlayerController>().transform;
}
void Update()
{
float mouseX = Input.GetAxis("Mouse X") * mouseSenstivity * Time.deltaTime;
float mouseY = Input.GetAxis("Mouse Y") * mouseSenstivity * Time.deltaTime;
yRotation -= mouseY; //将上下旋转的轴值进行累计
yRotation = Mathf.Clamp(yRotation, -80f, 80f); //限制摄像机上下旋转角度
transform.localRotation = Quaternion.Euler(yRotation, 0f, 0f); //摄像机上下旋转
playerBody.Rotate(Vector3.up * mouseX); //玩家左右移动
}
}
这样一来基本的角色移动控制就已经写完了,整体来讲这方面还是比较简单的,除了人物在高处悬空以外也没啥易踩的坑,如果你不是用Character Controller来控制角色而是用Rigidbody(刚体)来处理角色的话就不会出现高处悬空问题,Rigidbody是Unity自带的组件,里面添加了物理引擎的运算,但是如果是用来控制人物角色的话还是Character Controller会比较好。文章来源:https://www.toymoban.com/news/detail-860099.html
这次的分享就到这里,感谢阅读,如有问题可及时提出,读者可以和视频一起观看,更好理解。文章来源地址https://www.toymoban.com/news/detail-860099.html
到了这里,关于用Unity3D制作FPS游戏的学习笔记————人物移动、利用鼠标实现视角转动和人物跳跃(含人物悬空不掉落修复)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!