前言:
這是我第一次發(fā)布文章,此文章僅供參考,我也是剛學(xué)習(xí)接觸untiy,在制作項目的過程中將有用的寫下來記一記,以便自己之后能回頭看看,各位大佬輕點噴,若有錯誤請麻煩積極提謝謝各位。該文章參考自B站UP主蔡先森_rm-rf發(fā)布的【第一人稱射擊游戲教程2.0【已完結(jié)】】 https://www.bilibili.com/video/BV1J8411d75s/?p=54&share_source=copy_web&vd_source=a2427fab8ac35b158501cad28e7effe7
首先制作人物移動需要先制作一個場景和創(chuàng)建一個角色,這里就不再詳細(xì)贅述如何創(chuàng)建了。
注意:最好創(chuàng)建一個空對象把角色(膠囊體)放進去,父對象坐標(biāo)保持(0.0.0),僅對子對象進行微調(diào)即可,之后創(chuàng)建的父對象也要保持在原點,只動子對象。
創(chuàng)建好角色和場景之后新建文件夾Script創(chuàng)建新的腳本這里取名為PlayerController,將腳本負(fù)載到角色Character中,在Character對象里添加Character Controller(角色控制器)組件,修改一下他的半徑和高度。
雙擊新建的腳本先給人物添加移動邏輯
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private CharacterController characterController;
private Vector3 moveDirction; //設(shè)置人物移動方向
[Header("玩家數(shù)值")]
public float Speed;
[Tooltip("行走速度")] public float walkSpeed;
[Tooltip("奔跑速度")] public float runSpeed;
[Header("鍵位設(shè)置")]
[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;
}
//設(shè)置人物移動方向,(normalized將速度進行規(guī)范化,防止斜向走速度變大)
moveDirction = (transform.right * h + transform.forward * v).normalized;
characterController.Move(moveDirction * Speed * Time.deltaTime);//人物移動
}
}
?這里移動邏輯跟UP沒差別,使用的是GetAxisRaw方法,這種方法實現(xiàn)的是即松即停,意思就是松開方向鍵就馬上停下,不會再往前滑,但我想做的是松開方向鍵之后,人物還會往前滑一小段距離,按下反方向鍵做急停,方法如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private CharacterController characterController;
private Vector3 dir; //設(shè)置人物移動方向
[Header("玩家數(shù)值")]
public float Speed;
[Tooltip("行走速度")] public float walkSpeed;
[Tooltip("奔跑速度")] public float runSpeed;
[Header("鍵位設(shè)置")]
[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);
}
}
這樣就能實現(xiàn)平滑移動的效果,就類似馬里奧里地板抹油一樣,更加舒服,后面我也會用該移動進行編寫。
接下來是跳躍,跳躍的話在視頻合集P9中寫完之后發(fā)現(xiàn)人物走到高處掉不下去,UP也在后面補充了,我覺得都是屬于跳躍邏輯就一并寫完吧。代碼如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class PlayerController : MonoBehaviour
{
private CharacterController characterController;
private Vector3 dir; //設(shè)置人物移動方向
[Header("玩家數(shù)值")]
public float Speed;
[Tooltip("行走速度")] public float walkSpeed;
[Tooltip("奔跑速度")] public float runSpeed;
[Tooltip("跳躍的力")] public float jumpForce;
[Tooltip("下落的力")] public float fallForce;
[Header("鍵位設(shè)置")]
[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; //設(shè)置跳躍力
}
//當(dāng)前沒有按下空格并且檢測在地面上,那么isGround判斷為false(修復(fù)在空中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); //將跳躍力轉(zhuǎn)化成v3坐標(biāo)
collisionFlags = characterController.Move(jump); //調(diào)用角色控制器移動方法,向上方法模擬跳躍
/*判斷玩家在地上
CollisionFlages:CharacterController 內(nèi)置的碰撞位置標(biāo)識號
CollisionFlags.Below -->在地上*/
if (collisionFlags == CollisionFlags.Below)
{
isGound = true;
jumpForce = -2f;
}
}
}
}
這樣人物移動跳躍就已經(jīng)做好了,剩下視角移動,我們先將Main Camera拖進我們創(chuàng)建的角色里做我們角色的子對象,將坐標(biāo)軸重置,調(diào)整至合適位置,將剪裁調(diào)至0.01,在Script文件夾下創(chuàng)建MouseLook腳本,并將其拖入Main Camera內(nèi)。
雙擊MouseLook腳本,輸入以下代碼:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 攝像機的旋轉(zhuǎn)
/// 玩家左右旋轉(zhuǎn)控制實現(xiàn)左右移動
/// 攝像機上下旋轉(zhuǎn)控制視線上下移動
/// </summary>
public class MouseLook : MonoBehaviour
{
[Tooltip("鼠標(biāo)靈敏度")] public float mouseSenstivity = 400f;
private Transform playerBody; //玩家位置
private float yRotation = 0f; //攝像機上下旋轉(zhuǎn)
[Tooltip("當(dāng)前攝像機的初始高度")] public float height = 1.8f;
void Start()
{
Cursor.lockState = CursorLockMode.Locked; //將鼠標(biāo)隱藏并鎖定在屏幕中心
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; //將上下旋轉(zhuǎn)的軸值進行累計
yRotation = Mathf.Clamp(yRotation, -80f, 80f); //限制攝像機上下旋轉(zhuǎn)角度
transform.localRotation = Quaternion.Euler(yRotation, 0f, 0f); //攝像機上下旋轉(zhuǎn)
playerBody.Rotate(Vector3.up * mouseX); //玩家左右移動
}
}
這樣一來基本的角色移動控制就已經(jīng)寫完了,整體來講這方面還是比較簡單的,除了人物在高處懸空以外也沒啥易踩的坑,如果你不是用Character Controller來控制角色而是用Rigidbody(剛體)來處理角色的話就不會出現(xiàn)高處懸空問題,Rigidbody是Unity自帶的組件,里面添加了物理引擎的運算,但是如果是用來控制人物角色的話還是Character Controller會比較好。文章來源:http://www.zghlxwxcb.cn/news/detail-860099.html
這次的分享就到這里,感謝閱讀,如有問題可及時提出,讀者可以和視頻一起觀看,更好理解。文章來源地址http://www.zghlxwxcb.cn/news/detail-860099.html
到了這里,關(guān)于用Unity3D制作FPS游戲的學(xué)習(xí)筆記————人物移動、利用鼠標(biāo)實現(xiàn)視角轉(zhuǎn)動和人物跳躍(含人物懸空不掉落修復(fù))的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!