步骤一:准备素材
先到Unity3d Asset store 下载survival shooter的素材
https://www.assetstore.unity3d.com/cn/#!/search/page=1/sortby=relevance/query=survival&shooter
你也可以偷懒,到我的网盘下载。默默感谢我的无私吧!
链接:https://pan.baidu.com/s/1VDhJi1JHQBOWUeQlDVDrNQ 密码:vkl6
步骤二:设计主角player的运动逻辑 和 Camera跟踪player的逻辑
导进来的survival shooter资源包,如下图:
友情提醒:
第一个红圈显示的文件夹,是我自己创建的,以后把需要用到的资源都放在这个文件夹下,这样才不会乱套。
第二个红圈显示的文件夹,是发布者已经完成的项目。
1)创建一个地板物体,目的:自动寻径和射线碰撞检测
GameObject–>3D object–>Quad
在Inspect视图中,rename成Floor,并在Layer层中设置为Floor;
2)创建一个空的GameObject,目的:放置背景音乐
GameObject–>Create Empty
在Inspect视图中,rename为BackgroundMusic,并为其添加Audio组件。
Add Component -->Audio–>Audio Source
然后,选中Audio Clip ,然后赋予Background Music.mp3
3)添加一个player对象
3-1、将Player对象拖拽到Hierarchy视图中,即场景中。
3-2、在Inspector视图中,将Tag标签设置为Player(目的,为了后面的脚本中通过Tag标签找到Player这个对象)
3-3、创建一个动画控制器,用于控制角色运动时的状态。
在2016_my_survival_Shooter目录下,右键–>create–>Animator Controller -->命名为yzx_PlayAC —>拖拽该控制器到场景中的Player对象上;
3-4、打开Animator视窗,window–>Animator
默认有3个状态 (Any State 、Entry 、Exit),右键空白处,分别创建三个状态(右击–>Create State–>Empty),并分别重命名为Move、Idle 和 Death;
接下来,点击Parameters,点击“+”号,添加两个参数。一个设置为Bool(布尔型):IsWorking,一个设置为Trigger(触发型): Dead, 并记得勾选。
最后,设置好整个控制器状态的逻辑。
Entry—>Idel;
Idel–>Move (右击–>Make Transition) 并选中过渡线,设置过渡条件,在Inspect视图中,找到Conditions,选中“+”,把刚才设置的参数添加进来(这里选择IsWorking : true)
Move–>Idel(类似上面操作,过渡条件设置为 IsWorking : false)
Any State–>Death (过渡条件设置为 Dead)
整体的效果如下:
3-5、为Player添加各种组件,目的:使得角色具有碰撞检测功能、刚体属性等
添加一个刚体组件:Add Component–>Physics–>Rigidbody
设置如下:
Drag(阻力) : Infinity(无限大)
Angular Drag(角阻力):Infinity(无限大)
Constraints(限制)
Freeze Position : Y (限制角色 Y 方向的平移)
Freeze Position :X、Z (限制角色 X 方向和 Z 方向的旋转)
添加一个胶囊碰撞组件: Add Component–>Physics–>Capsule Collider
设置如下:
Center : X :0.2 | Y:0.6 | Z:0
Radius :0.5
Height:1.2
添加一个Audio Source 组件
设置如下:
Audio Clip : Player Hurt.MP3
取消 play on Awake 选项 ,目的为了在脚本中,当敌人碰撞到Player对象时,动态打开Audio Clip的声音片段。
3-6、新建一个C#脚本,并命名为PlayerMovement 将脚本拖拽到Player对象上。其中,PlayerMovement .cs脚本代码如下:
using UnityEngine;
using System.Collections;
public class playerMovement : MonoBehaviour {
public float speed = 6f; //设置玩家的移动速度
Vector3 movement; // 存储玩家移动的方向,是个向量类型
Animator anim; //定义一个动画器类型的变量
Rigidbody playerRigidbody; //定义一个刚体类型的变量
int floorMask; //定义一个int型的变量,存储射线将要与其碰撞的地板层
float camRayLength = 100f; //定义摄像机射线的长度
// Use this for initialization
void Start () {
floorMask = LayerMask.GetMask ("Floor"); //获取到地板层,射线只与这一层的物体碰撞
anim = GetComponent <Animator> (); //获取Player对象上的Animator组件
playerRigidbody = GetComponent <Rigidbody> (); //获取Player对象上的刚体组件
}
//固定更新函数,默认设置每秒50帧,也就是每隔0.02s执行一次该函数
void FixedUpdate ()
{
float h = Input.GetAxisRaw("Horizontal"); //获取用户键盘上的按键,对应水平按键 A,D (方向键的左右)
float v = Input.GetAxisRaw("Vertical"); //获取用户键盘上的按键,对应垂直按键W,S (方向键的上下)
Move (h, v); //Player对象运动函数
Turning (); //Player对象旋转函数,使得Player对象转向鼠标光标的方向
Animating (h, v); //Player对象状态逻辑
}
void Move (float h, float v)
{
movement.Set (h, 0f, v); //获取按键的信息
movement = movement.normalized * speed * Time.deltaTime; //normalizer单位化向量 *速度*时间= 位移
playerRigidbody.MovePosition (transform.position + movement); //设置Player对象的位置
}
void Turning (){
//根据用户鼠标的点击位置,计算出一条摄像机射线
Ray camRay = Camera.main.ScreenPointToRay (Input.mousePosition);
RaycastHit floorHit;
if(Physics.Raycast (camRay, out floorHit, camRayLength, floorMask))
{
//地板上的点击位置-角色当前的位置,向量的方向:Player对象指向鼠标的点击位置
Vector3 playerToMouse = floorHit.point - transform.position;
playerToMouse.y = 0f; //y方向为0
Quaternion newRotatation = Quaternion.LookRotation (playerToMouse); //旋转四元素
playerRigidbody.MoveRotation (newRotatation); //设置Player玩家的旋转信息
}
}
void Animating (float h, float v)
{
//若用户按上了WSAD(即运动方向键),则角色状态为运动状态,否则为Idel状态
bool walking = h != 0f || v != 0f;
anim.SetBool ("IsWalking", walking);
}
}
3-7、创建一个摄像机跟随Player角色运动的C#脚本,并命名为CameraFollow,其中,CameraFollow.cs脚本代码如下:
将CameraFollow.cs脚本拖拽到MainCamera对象上
拖拽Player对象到CameraFollow.cs脚本的Target变量上
using UnityEngine;
using System.Collections;
public class CameraFollow : MonoBehaviour {
public Transform target;
public float smoothing=5f;
Vector3 offset;
void Start () {
offset = transform.position - target.position;
}
void FixedUpdate () {
Vector3 targetCampos = target.position + offset;
transform.position = Vector3.Lerp (transform.position, targetCampos, smoothing * Time.deltaTime);
}
}