【Unity】John_Lemon密室逃脱

What’s unity?

Unity3D是由Unity Technologies开发的一个能让玩家轻松创建诸如三维游戏、虚拟现实、实时电 影与动画、建筑可视化、数字教育、汽车/运输与制造等众多类型互动内容的多平台的综合型游戏开 发工具,是一款功能强大的专业游戏引擎。Unity类似于Director,Blender,Virtools或Torque Game Builder等利用交互的图形化开发环境为首要方式的软件。
————————————————
版权声明:本文为CSDN博主「想吃烤地瓜.」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_46093832/article/details/120306980

unity开发学习路线

在这里插入图片描述

Demo的制作流程:

  1. 安装并配置,熟悉编辑器工具
  2. 导入资源文件,可以去Window->Asset Store下载想要的场景,这里下载的Tutorial Resources,添加到我的资源并在unity中打开,import到unity中
  3. 拖入人物,通过GameObject->Align with view调整视角
  4. 制作预制体(下面详细展开)
  5. 创建动画,创建文件夹MyAnimators->Animator Controller->双击进入,设置对应动画关系
  6. 创建脚本,给需要实现的人物/事物编写程序
  7. 完成创作,打包游戏

关于预制体

为什么创建预制体

在Unity中,预制体的作用是重复利用资源,比如游戏世界的花草树木、房屋建筑。这些资源都是重复出现的,我们可以将它做成预制体,方便重复利用

创建范围

凡是能够拖入Hierarchy面板的,都可以制成预制体,包括但不限于模型、UI、挂载脚本的空对象等。

创建方法

把Scene中物体拖到Prefabs中,图标变蓝色块

编写脚本

PlayerMovement

通过键盘输入控制游戏人物的移动,语法比较易懂,详细功能见注释。

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

public class PlayerMovement : MonoBehaviour
{
    public float turnspeed = 20f;   //定义旋转速度
 
    Animator m_Animator;
    Rigidbody m_Rigidbody; //定义游戏人物上的组件

    Vector3 m_Movement;//游戏人物移动的矢量
    Quaternion m_Quaternion=Quaternion.identity;//定义人物旋转的角度

    // Start is called before the first frame update
    void Start()
    {
        m_Animator = GetComponent<Animator>();
        m_Rigidbody = GetComponent<Rigidbody>();
        //获取人物上的刚体、动画控制机制组件
    }

    // Update is called once per frame
    private void FixedUpdate()
    {
        float horizontal = Input.GetAxis("Horizontal");//键盘输入水平移动
        float vertical = Input.GetAxis("Vertical");//键盘输入数值移动
        m_Movement.Set(horizontal, 0f, vertical);//设置游戏人物移动方向
        m_Movement.Normalize();//速度归一化

        bool hasHorizontalInput = !Mathf.Approximately(horizontal,0f); //定义移动的bool值
        bool hasverticalInput = !Mathf.Approximately(vertical, 0f);

        //控制动画播放
        bool iswalking = hasHorizontalInput || hasverticalInput;
        m_Animator.SetBool("isWalking", iswalking);

        //旋转的过渡
        Vector3 desirForwad = Vector3.RotateTowards(transform.forward, m_Movement, turnspeed * Time.deltaTime, 0f);
        m_Quaternion = Quaternion.LookRotation(desirForwad);
    }

    //游戏人物的旋转和过渡
    private void OnAnimatorMove()
    {
        m_Rigidbody.MovePosition(m_Rigidbody.position + m_Movement * m_Animator.deltaPosition.magnitude);
        m_Rigidbody.MoveRotation(m_Quaternion);
    }
   
}

CameraFollow

照相机跟随人物移动,也可以通过设置虚拟相机的方法来实现。

思路:在Start函数中找到相机与玩家的相对位置并记录,在每一帧的更新中(由Update函数实现),键盘输入控制人物移动,但是相对位置不发生改变。

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

public class CameraFollow1 : MonoBehaviour
{
    //跟随着游戏人物
    private Transform Player;

    //相机与人物之间的距离
    Vector3 offset;
   
    // Start is called before the first frame update
    void Start()
    {
        Player = GameObject.Find("JohnLemon").transform;
        offset = transform.position - Player.position;   
    }
    // Update is called once per frame
    void Update()
    {
        transform.position = offset + Player.position;        
    }
}

GameEnding

游戏结束时效果,包括显示画布和响起音频,失败时重启和成功时退出。

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

public class GameEnding : MonoBehaviour
{

    public float fadeDuration = 1f;    //淡入淡出的时间
    public float displayDuration = 1f; //游戏胜利显示的时间  
    public GameObject Player;  //游戏人物    
    public CanvasGroup ExitBK;//游戏胜利时的画布背景
    public CanvasGroup FailBK;//游戏失败时的画布背景
    bool IsExit = false;//游戏胜利时的bool值
    bool IsFail = false;//游戏失败时的bool值

    //定义计时器用于图片的渐变
    public float timer=0f;

    //音频组件
    public AudioSource winaudio;
    public AudioSource failaudio;

    //bool控制音效只播放一次
    bool IsPlay=false;
    // Update is called once per frame
    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject == Player)
        {
            //检测到玩家
            IsExit = true;
        }
    }

    //游戏失败时的控制函数
    public void Caught()
    {
        IsFail = true;
    }

    void Update()
    {
        if (IsExit)
        {
             EndLevel(ExitBK,false,winaudio);
        }
        else if (IsFail)
        {
            EndLevel(FailBK, true,failaudio);
        }
    }
    //游戏胜利/失败时的方法
    void EndLevel(CanvasGroup igCanvasGroup,bool doRestart,AudioSource playaudio)
    {
        //音效播放
        if (!IsPlay)
        {
            playaudio.Play();
            IsPlay = true;
        }

        //玩家碰到计时器时开始计时计时器开始计时
        timer += Time.deltaTime;//控制CanvasGroup不透明度的显示
        igCanvasGroup.alpha = timer / fadeDuration;
        //游戏胜利/失败图片渐变1s,显示1s
        if (timer > fadeDuration+displayDuration)
        {
        //    Debug.Log("Fail");
            
            if (doRestart)//游戏失败,重启游戏
            {
                SceneManager.LoadScene("Main");
            }
            else
            {
                Application.Quit();
            }
        }
    }
}

Observer

射线检测,判断玩家有没有进入死亡区域。

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

public class Observer : MonoBehaviour
{
    //游戏角色
    public Transform Player;
    public GameEnding gameEnding;

    //游戏玩家是否进入到扫描棒的视线范围
    bool IsInRange = false;

    private void OnTriggerEnter(Collider other)
    {
        //扫描棒扫描到玩家
        if (other.gameObject == Player.gameObject)
        {
            IsInRange = true;
        }
    }

    // Update is called once per frame
    void Update()
    {
        if (IsInRange == true)
        {
            //射线检测
            Vector3 dir = Player.position - transform.position + Vector3.up;//考虑重心的偏移
            Ray ray = new Ray(transform.position, dir);
            RaycastHit raycastHit;
            if(Physics.Raycast(ray,out raycastHit))
            {
                if (raycastHit.collider.transform == Player)
                {
                    //游戏失败,调用gameending的caught方法
                    gameEnding.Caught();
                }
            }
        }
    }
}

WayPointsPatrol

生成移动的点位,利用数组储存目标点。可以在数组waypoints[ ]中设置具体位置

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

public class WayPointsPatrol : MonoBehaviour
{
    //导航组件
    public NavMeshAgent navMeshAgent;
    //导航点的数组
    public Transform[] waypoints;
    //当前巡逻的目标点
    int m_currentpointIndex;


    // Start is called before the first frame update
    void Start()
    {
        navMeshAgent = GetComponent<NavMeshAgent>();
        //从起点到达第一个巡逻点
        navMeshAgent.SetDestination(waypoints[0].position);
    }

    // Update is called once per frame
    void Update()
    {
        //到达目标点,前往下一个目标点
        if (navMeshAgent.remainingDistance<navMeshAgent.stoppingDistance)
        {
            m_currentpointIndex=(m_currentpointIndex + 1) % waypoints.Length;
            navMeshAgent.SetDestination(waypoints[m_currentpointIndex].position);
        }
    }
}

几个值得记录的语句:

void Start()
//初始状态函数,在游戏一开始时运行
void Update()
//每一帧都会运行的函数,动态获取
public void FixedUpdate()
//固定帧更新,一般用作物理更新
public void OnAnimatorMove() 
//可以让物体根据动画自身的空间位移来改变物体的空间坐标
public void OnTriggerEnter()
//检测物体碰撞
Time.deltaTime
//后一帧时间减去前一帧时间
//其存在的意义:可以让运动的物体在相同的时间保持同样平均的速度进行运动。
navMeshAgent.SetDestination()
//下一个目标点的位置
GameObject.GetComponent<Type>()
//GameObject时当前游戏对象的变量名称
//Type是组件名称,类型是string 
//获取当前游戏对象组件的方法,可以通过直接调用它来访问游戏对象的组件和进行参数调整。
Animator //定义动画
Rigidbody  //定义刚体组件
Vector3 //定义移动的矢量
Quaternion //定义旋转角度
AudioSource //定义音频

最后效果

整体界面
运行开始后界面

ENABLE_UNITY_COLLECTIONS_CHECKS是Unity中的一个编译器宏定义,用于启用Unity Collections库中的线程和处置安全检查。这个宏定义可以确保在使用Unity Collections库时,对于线程安全和资源释放的问题进行检查,以避免潜在的错误。\[1\] Unity Collections库提供了一些关键的类数组类型,如NativeArray和NativeSlice,以及一些数据结构,如NativeList和NativeQueue,这些都受到ENABLE_UNITY_COLLECTIONS_CHECKS宏定义的影响。\[2\] 但是需要注意的是,ENABLE_UNITY_COLLECTIONS_CHECKS主要用于单元测试框架中的断言,而不是用于生产代码的测试。因此,在生产代码中使用这个宏定义可能会导致性能下降,因为它会增加额外的检查和开销。\[3\] #### 引用[.reference_title] - *1* *3* [unity断言_Unity断言库](https://blog.csdn.net/culiao6493/article/details/108642656)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [[Unity ECS] Unity Collections Package](https://blog.csdn.net/u013716859/article/details/122278432)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

404Gloria

你的鼓励是我创作的最大动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值