官方案例--Survival Shoot(一)

2021-11-30 19:52:18 浏览数 (1)

导入Survival Shooter.unitypackage,里面有个完整了,新版本导入的时候,需要简单的修改一下代码;

一、环境设置

1、Prefabs--->Environment,将预制体Environment拖到Hierarchy面板中,调整位置:

2、Prefabs--->Lights,将预制体Lights拖到Hierarchy面板中,不需要担心位置,因为是平行光,与位置无关,需要考虑的是角度。将原来场景中的灯光删除

3、会有相机,发射不可见的Raycast,射向地面,但是现在环境中的地面是不平整的,上面有很多其它的物品,所以我们要建立一个3DObject--->Quad,重命名为Floor,调整位置、角度、大小。我们只需要它的Collider,不需要看到它,所以将Mesh Renderer组件删除。并将它的Layer层设置成Floor(导入包后会有这个层,没有就自己创建一个)

4、create Empty,重命名为BackgroundMusic,添加一个Audio Source组件,选择音乐,取消勾选Play On Awake,勾选Loop循环播放。可以适当的调整音量Volume,不用调整位置

  5、保存场景

二、玩家角色

1、Models--->Characters---->Player,拖拽到Hierarchy面板中,调整位置到原点,设置Tag为Player,创建Animator Controller,重命名PlayerAC,拖拽到Player身上,会自动添加Animator组件(实现所有的动画效果)。

2、双击动画控制器PlayerAC,会打开Animator面板,将模型Player中包含的动画Idle、Death、Move拖拽到里面(idle是默认刚开始的状态,先拖着Idie进去,不然需要调整)

  3、创建一个布尔Bool类型的Parameters,命名为isWalking(有true和false两种状态),点击 号,创建Trigger类型的参数,命名Die(和布尔类型的区别是,设置成true后会自己变成false,如果这个状态只是触发一次就可以用,像死亡.....)

4、设置状态之间的切换transition条件。move--->idle条件isWalking为false,idle--->move条件isWalking为true,可以取消勾选Has Exit Time(满足条件立刻切换动画),Any State--->Death,设置条件Die

5、给Player添加Rigidbody组件 ,设置Drag、Angular Drag为infinity,constraints约束,位置勾选Y,旋转勾选X、Z;;添加Capsule Collider组件(检查碰撞),调整中心点,让胶囊体包住Player

6、想让玩家受到伤害时,发出声音,添加Audio Source组件,添加Player Hurt音效,取消勾选Play On Awake。

  7、创建PlayerMovement脚本,添加到玩家Player身上,书写代码。

代码语言:javascript复制
using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    //控制玩家移动速度
    public float speed = 6f;
    //存储移动信息
    private Vector3 movement;
    //anim控制动画
    private Animator anim;
    //控制移动
    private Rigidbody playerRigidbody;
    // 指定要在Physics.Raycast中使用的层。
    private LayerMask floorMask;
    // 从摄像机发出射线的长度
    private float camRayLength = 100f;

    
    private void Awake()
    {
        // 找到Floor层
        floorMask = LayerMask.GetMask("Floor");
        //获得组件
        anim = GetComponent<Animator>();
        playerRigidbody = GetComponent<Rigidbody>();
    }

    // 固定帧率调用此函数,物理相关放到这里面
    private void FixedUpdate()
    {
        // 获得水平、垂直轴的输入,三个值-1,0,1,直接全速移动
        float h = Input.GetAxisRaw("Horizontal");
        float v = Input.GetAxisRaw("Vertical");
        Move(h, v);
        Turing();
        Animating(h, v);

    }

    // 移动
    void Move(float h, float v)
    {
        movement.Set(h, 0, v);
        // 水平、垂直两个按键一起按,斜着会快值,为根号2,所以要normalized标准化
        // 还要乘上速度,默认FixedUpdate0.02秒运行一次,一秒会移动50*speed,这样太快
        // 所以还要乘上Time.deltaTime,1秒移动speed个单位
        movement = movement.normalized * speed * Time.deltaTime;
        // MovePosition移动到指定位置
        playerRigidbody.MovePosition(transform.position   movement);
    }

    // 旋转
    void Turing()
    {
        //返回一条射线(起始点:相机,终点:鼠标位置)
        Ray camRay = Camera.main.ScreenPointToRay(Input.mousePosition);
        // 为了获取射线击中hit物体的信息,所以要创建一个 RaycastHit类型变量
        RaycastHit floorHit;
        //如果击中floor层,Raycast(射线,存储击中信息,射线长度,哪一层)
        if (Physics.Raycast(camRay,out floorHit, camRayLength, floorMask))
        {
            // 玩家转向鼠标的方向,差向量纸箱被减向量
            Vector3 playerToMouse = floorHit.point - transform.position;
            // 为了不让玩家倾斜,将y设置为0;
            playerToMouse.y = 0;
            // vector3不能存储旋转信息,Quaternion四元数存储旋转信息
            // LookRotation,指定以playerToMouse为正方向,
            Quaternion newRotation = Quaternion.LookRotation(playerToMouse);
            // 设置旋转
            playerRigidbody.MoveRotation(newRotation);
        }
    }

    // 动画
    void Animating(float h, float v)
    {
        bool isWalking = h != 0f || v != 0f;
        anim.SetBool("isWalking", isWalking);
    
    }
}

三、设置相机

  1、调整位置、角度。将相机设置成正交模式,size设置为4.5,Clear Flags设置成Solid ,背景设置成黑色(防止移动到边缘看到别的东西)。

  2、创建脚本CameraFollow,挂到相机上。 

代码语言:javascript复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraFollow : MonoBehaviour
{
    // 跟随目标
    public Transform target;
    // 相机平滑移动的速度
    public float smoothing = 5f;
    // 相机-跟随目标的位置。偏移量
    private Vector3 offset;
    // Start is called before the first frame update
    void Start()
    {
        offset = transform.position - target.position;
    }

    private void FixedUpdate()
    {
        Vector3 targetCamPos = target.position   offset;
        transform.position = Vector3.Lerp(transform.position, targetCamPos, smoothing * Time.deltaTime);
    }
}

0 人点赞