Unity3D学习笔记#4_Unity3D补充知识和简单案例学习


这篇文章切换了教程,主要参考这个 1。本篇文章结合前三篇文章,即完成了对Unity3D的基本认知。本篇以后就进入更系统的学习了,主要会更系统地学习Unity3D引擎和C#语言。

本文首先补充了一些Unity3D的知识,然后比较详细介绍了如何配置Unity3D的C#编程环境,最后给出了几个Unity3D制作小游戏的例子。这三个Example都基于同一个场景,是逐渐完善的过程。

1. 一些补充知识

①Unity脚本可以用很多编辑器来编辑,使用VS的话,由于VS很强大,开发会比较方便,断点调试等功能也可以依靠UnityVS插件实现。

②在Scene中,键盘的上下左右也可以移动视角。

③Inspector中的每个组件对应一个脚本。

④多个添加了Collider的物体,如果把它们叠在一起,只要一运行就会弹开来(下图都添加了Box Collider)。
在这里插入图片描述
⑤空对象:默认只有个Transform组件,别的得自己添加。

⑥添加自定义组件:有两种办法
第一种:直接在Project面板右键创建C# Script,然后把该Script拖到Hierachy面板中需要添加该组件的物体上去。
在这里插入图片描述
第二种:首先在Hierachy面板中选择需要添加组件的对象,然后在Inspector面板中,点击Add Component,选择New script即可添加。
在这里插入图片描述
⑦Input
C#脚本中会大量使用Input对象获取键盘和鼠标输入,Input到底提供了什么信息,可以在如下位置查看:
在这里插入图片描述
在这里插入图片描述
⑧一个物体的collider勾选成为触发器,就失去所有碰撞物理了,需要我们手动代码处理。

2. 安装和配置Unity3D的C#编程环境

对于新手来说,这东西真是愁死我了,一直有问题,经过很多尝试和搜索资料后才最终解决了。之前文章中介绍的方法大体也是没问题的,这里只有一些细节变化。

①Visual Studio安装。
首先下载安装最新版本的Visual Studio,在Installer中要勾选Unity3D游戏开发一项【我并没有下载最新版本,而是用的以前安装的vs2017】:

在这里插入图片描述
顺带着也可以勾选一些别的需要的功能【我还安装了.Net桌面开发、C++桌面开发、通用Windows平台开发、.NET Core几项】。然后就是漫长的等待,直到安装完毕。【我之所以遇到问题,就是因为我安装的vs2017版本太老了,在installer中点击更新后,就解决了在unity中无法使用vs的问题。】

②Unity3D安装。
点击这里进入下载页面。选择<回头用户>选项,会进入下载页面:
在这里插入图片描述
在下载页面勾选确认checkbox,点击Download Unity Hub即可,下好后傻瓜式安装。

在这里插入图片描述
打开Unity Hub,在如下位置点击安装,选择最新版本安装,然后等待安装完成,可以勾选中文语言包【我习惯英文就不勾选了】,如图所示我安装的是Unity 2019.3.2f1版本。注意,点击安装后,这个Hub的反应极慢,很可能还会显示<没有Unity版本>这样的页面,多等待一会儿应该就能解决。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
安装的过程也很缓慢,等待即可。

③关联vs2017到Unity3D。
首先,在Hub中随便创建一个工程。
在这里插入图片描述
在这里插入图片描述
然后在Project面板中,右键->Import Package->Custom Package:
在这里插入图片描述

会弹出资源管理器,我们在如下位置找到资源包文件:
在这里插入图片描述
点击打开即可。此时在Project面板的Assets目录下会出现UnityVS的文件夹。

然后,我们点击菜单栏的Edit->Preferences
在这里插入图片描述
在弹出的面板中,在下图中的位置选择vs2017作为编辑器即可:
在这里插入图片描述
此后,我们如果在unity中创建了C#脚本,双击即自动打开vs2017,观察是否报错,没报错基本就可以了。这时候在vs2017中编写代码,发现自动补全/智能提示功能正常。

3. Example 1 走路

这个例子在之前文章所使用的视频教程中也有类似的,在这里系统整理下。Unity的一些基本知识参考之前三篇文章,跟脚本无关的内容这里不展开。

本例子的目的是构建一个场景,场景中有一个立方体,使用键盘wasd可以控制立方体移动,使用shift可以加速移动,使用space跳起,使用鼠标可以调整俯仰视角,调整立方体的朝向。

3.1. 游戏对象创建和组件添加

首先,创建一个3D项目。然后删除掉Camera对象,只保留Directional Light。

然后,添加我们需要的对象。需要的游戏对象有:一个Terrain,一个Empty,然后给Empty创建两个子对象Cube和Camera。我把Empty的名字改成了MoveObject。如下图所示:

在这里插入图片描述
然后,我们分别修改这四个物体的组件。
(1)对于Terrain,我们不需要修改,使用默认的参数,为了确保和读者统一,特别说明下Transform组件参数和Terrain组件中的尺寸信息。
在这里插入图片描述
在这里插入图片描述
可以修改下地形的材质。

(2)对于MoveObject,添加一个Character Controller,一个Box Collider组件,一个自定义空白组件CubeMove。

在这里插入图片描述

调整下Transform组件:
在这里插入图片描述
调整一下BoxCollider组件:
在这里插入图片描述
调整一下Character Controller的Height、Radius、Y参数,使之恰好包围Cube:
在这里插入图片描述
(3)对于Cube,先删掉其Box Collider组件,然后需要对其位置进行一定调整,也就是调整Transform组件。
在这里插入图片描述
在这里插入图片描述
(4)对于Camera,则添加一个名为CubeViewRotate的自定义空白组件。并调整Transform到Cube顶部的中心位置。
在这里插入图片描述

3.2. 自定义脚本编写和配置

接下来我们编写脚本的内容。
①在Project面板中,双击CubeMove文件,如果配置一切正常,会自动打开VS,且VS的解决方案管理器中不是空的,有当前的Unity项目。编写如下代码(只要会编程应该就能大概看懂):

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

public class CubeMove : MonoBehaviour
{
    // Update is called once per frame
    public float speed;                         // 速度,外部赋值
    public CharacterController cubeController;  // 移动控制器,外部赋值
    public float cubeJumpSpeed = 5;             // 跳起时速度,外部可修改

    private const float g = 10;                 // 重力加速度
    private Vector3 cubeMoveVec;                // 计算移动量,注意 transform.right 和 transform.forward 是 Vector3

    // 每帧都会调用 Update 函数
    void Update()
    {
        // 获取键盘移动操作输入
        float x = 0, z = 0;

        if (cubeController.isGrounded)          // 跳起来就不允许控制了
        {
            x = Input.GetAxis("Horizontal");    // 获取水平方向两个控制量
            z = Input.GetAxis("Vertical");

            // 合成控制量,并转换到local坐标系
            cubeMoveVec = (transform.right * x + transform.forward * z) * speed;
            if (Input.GetKey(KeyCode.LeftShift))// 如果按下了左侧Shift则跑动
            {
                cubeMoveVec *= 2.5f;
            }

            if (1 == Input.GetAxis("Jump"))     // 如果按下了Space则跳起来,设置cubeJumpSpeed的跳起速度
            {
                cubeMoveVec.y = cubeJumpSpeed;
            }
        }
        else                                    // 如果不在地面,则逐渐让物体降下来
        {                                       
            cubeMoveVec.y -= g * Time.deltaTime;
        }

        // 执行移动命令
        cubeController.Move(cubeMoveVec * Time.deltaTime);
    }
}

然后保存,回到Unity页面,发现MoveObject的CubeMove出现了我们在脚本中定义的三个public类型变量,我们设置速度为10,跳起速度为5,然后把Hierarchy中的MoveObject拖到Cube Controller变量上。

在这里插入图片描述

②对于CubeViewRotate脚本,我们则填写如下代码:

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

public class CubeViewRotate : MonoBehaviour
{
    public float cubeViewRotateSpeed;
    public Transform cubeTransform;
    private float cubeUpAngle;


    // Start is called before the first frame update
    void Start()
    {
        // 锁定鼠标位置
        Cursor.lockState = CursorLockMode.Locked;
    }

    // Update is called once per frame
    void Update()
    {
        // 获取鼠标偏移量,并限制纵向角度范围
        float x, y;
        x = Input.GetAxis("Mouse X") * cubeViewRotateSpeed * Time.deltaTime;
        y = Input.GetAxis("Mouse Y") * cubeViewRotateSpeed * Time.deltaTime;
        cubeUpAngle -= y;
        cubeUpAngle = Mathf.Clamp(cubeUpAngle, -80, 80);

        // 像机偏转 - 垂直方向
        this.transform.localRotation = Quaternion.Euler(cubeUpAngle, 0, 0);

        // MoveObject旋转 - 水平方向
        cubeTransform.Rotate(Vector3.up * x);
    }
}

同样拖动MoveObject到Cube Transform上,且设置角速度为100。
在这里插入图片描述

3.3. 运行效果

在这里插入图片描述
在这里插入图片描述

4. Example 2 射击

在上个基础上,添加了可移动目标以及射击功能。

4.1. 添加和修改游戏对象

需要添加四个新的游戏对象。

(1)枪Gun
给Camera创建名为Gun的子空对象。添加Sprite Renderer和Audio Source组件,以及名为CubeGunShoot的自定义组件。
在这里插入图片描述

Sprite Renderer是枪的准星,按照下图操作选择准星。
在这里插入图片描述
Audio Source是枪声,我们去网上下载一个枪声的mp3文件,放到project中,并按下图拖到组件中,然后把Play On Awake勾掉:
在这里插入图片描述
(2)子弹Bullet
创建完成后,把它拖到Project中成为预制体,并删掉Hierarchy中的对象。

创建名为Bullet的Sphere,添加Rigidbody组件和名为CubeBulletMove的自定义组件。
在这里插入图片描述
修改Transform:
在这里插入图片描述
修改Rigidbody:
在这里插入图片描述
(3)子弹碎片 BulletFragment
创建完成后,把它拖到Project中成为预制体,并删掉Hierarchy中的对象。

创建名为BulletFragment的空对象,添加名为CubeBulletFragmentDisappear的自定义组件。

在这里插入图片描述
创建五个BulletFragment的Cube类型子对象,每个Cube进行同样的设置。
在这里插入图片描述
首先都添加Rigidbody。
在这里插入图片描述
都修改Transform:
在这里插入图片描述
都修改Rigidbody:
在这里插入图片描述
(4)敌人Enemy
创建完成后,把它拖到Project中成为预制体,并删掉Hierarchy中的对象。

创建一个名为Enemy的Cube类型对象,添加Rigidbody,Character Controller和自定义Cube Enemy。
在这里插入图片描述
添加一个名为Enemy的tag:
在这里插入图片描述
修改Transform:
在这里插入图片描述
修改Box Collider:
在这里插入图片描述
修改Rigidbody:
在这里插入图片描述
此外,可以添加子物体以区分正反面,添加材质修改外观。
在这里插入图片描述
(5)给MoveObject添加标签:
在这里插入图片描述
(6)Terrain对象添加脚本
Terrain添加一个Cube Terrain的自定义组件。
在这里插入图片描述

(7)Hierarchy面板和预制体
以上修改完成后,Hierarchy面板的样子:
在这里插入图片描述
我把Project中的预制体放到了一个文件夹中:
在这里插入图片描述

4.2. 自定义脚本编写和配置

①修改CubeMove

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

public class CubeMove : MonoBehaviour
{
    // Update is called once per frame
    public float speed;                         // 速度,外部赋值
    public CharacterController cubeController;  // 移动控制器,外部赋值
    public float cubeJumpSpeed = 5;             // 跳起时速度,外部可修改
    public int cubeHp = 100;                    // 自身血量

    private const float g = 10;                 // 重力加速度
    private Vector3 cubeMoveVec;                // 计算移动量,注意 transform.right 和 transform.forward 是 Vector3

    // 每帧都会调用 Update 函数
    void Update()
    {
        // 如果hp已经没了,那么就死掉吧
        if (cubeHp <= 0)
        {
            Destroy(gameObject);
        }
        // 获取键盘移动操作输入
        float x = 0, z = 0;

        if (cubeController.isGrounded)          // 跳起来就不允许控制了
        {
            x = Input.GetAxis("Horizontal");    // 获取水平方向两个控制量
            z = Input.GetAxis("Vertical");

            // 合成控制量,并转换到local坐标系
            cubeMoveVec = (transform.right * x + transform.forward * z) * speed;
            if (Input.GetKey(KeyCode.LeftShift))// 如果按下了左侧Shift则跑动
            {
                cubeMoveVec *= 2.5f;
            }

            if (1 == Input.GetAxis("Jump"))     // 如果按下了Space则跳起来,设置cubeJumpSpeed的跳起速度
            {
                cubeMoveVec.y = cubeJumpSpeed;
            }
        }
        else                                    // 如果不在地面,则逐渐让物体降下来
        {                                       
            cubeMoveVec.y -= g * Time.deltaTime;
        }

        // 执行移动命令
        cubeController.Move(cubeMoveVec * Time.deltaTime);
    }

    public void beAttacked(int hpHurt)          // 被攻击到掉血
    {
        cubeHp -= hpHurt;
    }
}

此后会多出Cube Hp的可设置属性,这是我们自己的血量:
在这里插入图片描述
②CubeBulletFragmentDisappear脚本

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

public class CubeBulletFragmentDisappear : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Destroy(gameObject, 0.3f);      // 0.3秒后自动消失
    }
}

③CubeBulletMove脚本

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

public class CubeBulletMove : MonoBehaviour
{
    // Start is called before the first frame update

    private const float bulletSpeed = 200;      // 子弹速度
    private const float bulletLiveTime = 3;     // 子弹存活时间
    public Rigidbody bulletRigid;               // 给子弹初始一个力,子弹是刚体,此后会自动掉落
    public GameObject bulletFragment;           // 子弹碎片

    void Start()
    {
        Destroy(gameObject, bulletLiveTime);                            // bulletLiveTime后销毁
        bulletRigid.velocity = (this.transform.forward) * bulletSpeed;  // 子弹初始受力
    }

    private void OnCollisionEnter(Collision collision)                  // 击中敌人,对其造成伤害
    {
        if ("Enemy" == collision.gameObject.tag)
        {
            collision.gameObject.GetComponent<CubeEnemy>().beAttacked(20);
        }
        if ("MoveObject" != collision.gameObject.tag)                   // 不允许子弹击中自己
        {
            GameObject bulletFragmentObj = GameObject.Instantiate(bulletFragment, transform.position, transform.rotation);
            Destroy(gameObject);
        }
    }
}

Inspector显示(点击Project中Bullet预设体)如下,按箭头拖拽给变量赋值:
在这里插入图片描述
④CubeEnemy脚本:

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

public class CubeEnemy : MonoBehaviour
{
    public int enemyHp = 100;                       // 敌人血量
    public float enemyTurnInterval = 10;            // 未发现自己时,敌人转弯周期
    public CharacterController enemyController;     // 敌人移动控制器
    private float enemyLastTurnTime = 0;            // 上次转弯时刻
    private float enemyMoveAngle = 0;               // 运动角度
    private const float enemySpeed = 5;             // 敌人移动速度
    Vector3 dirVec;                                 // 自己与敌人相对位置
    Vector3 enemyMoveVec;                           // 敌人移动方向
    public Rigidbody enemyRigid;                    // 敌人刚体

    private void Start()                            // 初始化
    {
        enemyLastTurnTime = -100;
        enemyMoveVec = transform.forward * Mathf.Sin(enemyMoveAngle) + transform.right * Mathf.Cos(enemyMoveAngle);
    }

    // Update is called once per frame
    void Update()
    {
        if (enemyHp <= 0) Destroy(gameObject);      // 没血就销毁

        // 以下一段控制如果敌人发现与自己距离达到一定范围,就去攻击自己,否则就随机乱走
        float dis = 100000000;
        GameObject cubeObject = GameObject.FindGameObjectWithTag("MoveObject");                                 // 获取自己的引用
        if (cubeObject != null)                     // 计算相对方位
        {
            dirVec = cubeObject.transform.position - transform.position;
            dirVec.y = 0;
            dis = Vector3.Distance(cubeObject.transform.position, transform.position);
        }
        if (dis < 50)
        {
            transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(dirVec), 0.3f);
            transform.position += dirVec.normalized * enemySpeed * Time.deltaTime * 2;

            //enemyRigid.velocity = dirVec.normalized * enemySpeed;
        }
        else if (dis < 200)
        {
            transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(dirVec), 0.3f);
            transform.position += dirVec.normalized * enemySpeed * Time.deltaTime * 0.5f;

            //enemyRigid.velocity = dirVec.normalized * enemySpeed * 2;
        }
        else // 随机移动
        {
            if (enemyTurnInterval <= (Time.time - enemyLastTurnTime))
            {
                enemyLastTurnTime = Time.time;
                enemyMoveAngle = Random.value * Mathf.PI;

                enemyMoveVec = transform.forward * Mathf.Sin(enemyMoveAngle) + transform.right * Mathf.Cos(enemyMoveAngle);
            }
            // print(transform.position);
            if (transform.position.x > 950 || transform.position.x < 50 || transform.position.z > 950 || transform.position.z < 50)
            { // 防止出界
                enemyMoveVec = transform.position;
                enemyMoveVec.x = 500 - enemyMoveVec.x;
                enemyMoveVec.z = 500 - enemyMoveVec.z;
                enemyMoveVec.y = 0;
            }
            transform.position += enemyMoveVec.normalized * enemySpeed * Time.deltaTime;

            // enemyRigid.velocity = enemyMoveVec.normalized * enemySpeed;
        }
    }

    private void OnTriggerEnter(Collider other)  // 击中自己时,扣除自己血量
    {
        // print(collision.gameObject.tag);
        if ("MoveObject" == other.gameObject.tag)
        {
            // print(collision.gameObject.tag);
            other.gameObject.GetComponent<CubeMove>().beAttacked(10);
        }
    }

    public void beAttacked(int hpHurt)                  // 被击中时的反应
    {
        enemyHp -= hpHurt;
    }
}

面板设置:
在这里插入图片描述

⑤CubeGunShoot脚本:

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

public class CubeGunShoot : MonoBehaviour
{
    public GameObject bullet;               // 子弹对象
    public int cubeGunShootInterval = 10;   // 射击间隔
    private int cubeGunShootCnt = 0;        // 射击间隔辅助
    public AudioSource cubeGunShootAs;      // 射击音效

    // Update is called once per frame
    void Update()
    {
        if (1 == Input.GetAxis("Fire1") && 0 >= cubeGunShootCnt)
        {   // 射击
                GameObject bulletObj = GameObject.Instantiate(bullet, transform.position + Vector3.forward * 0.1f, transform.rotation);
                cubeGunShootCnt = cubeGunShootInterval;
                cubeGunShootAs.Play();
        }
        cubeGunShootCnt--;
    }
}

Inspector面板:
在这里插入图片描述
⑥CubeTerrain脚本

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

public class CubeTerrain : MonoBehaviour
{
    // Start is called before the first frame update
    public GameObject cubeEnemy;        // 敌人对象
    public int cubeEnemyNum = 1000;     // 敌人数量

    void Start()
    { // 随机创建敌人对象
        for (int i = cubeEnemyNum; i > 0; i--)
        {
            Vector3 cubeEnemyObjPos;
            cubeEnemyObjPos.x = Random.Range(200f, 800f);
            cubeEnemyObjPos.y = Random.Range(1.6f, 1.7f);
            cubeEnemyObjPos.z = Random.Range(200f, 800f);
            Vector3 cubeEnemyObjAng;
            cubeEnemyObjAng.x = 0f;
            cubeEnemyObjAng.y = Random.Range(0f, Mathf.PI);
            cubeEnemyObjAng.z = 0f;
            GameObject cubeEnemyObj = GameObject.Instantiate(cubeEnemy, cubeEnemyObjPos, Quaternion.Euler(cubeEnemyObjAng));
        }
    }

    // Update is called once per frame
    void Update()
    {
    }
}

Inspector面板:
在这里插入图片描述

4.3. 运行效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5. Example 3 面板和动画

这个部分的内容是非常非常认识性质的,聊胜于无吧。

5.1. 面板系统

面板是随着Camera一起动的,会随着窗口的变化而变化。这里我们用面板上的准星替换掉Camera上的准星。

首先,在Hierarchy中找到Gun, 然后把其Sprite Renderer禁掉:
在这里插入图片描述
然后,我们在Hierarchy中创建一个UI/Canvas,然后在Scene中按F键,发现多出了一个面板组件。
在这里插入图片描述
最后,我们给Canvas创建一个UI/Image子对象,并在其Image组件中的Source Image选项中选择准星:
在这里插入图片描述

5.2. 动画系统

这里仍然搞个简单的例子,为我们的Cube建个家,带有可以开闭的门。

首先创建一个空对象,命名为Home,然后给它创建四个子Cube对象,并搭成一个房子形状,再创建Home的两个Sphere子对象,作为开门的按钮:
在这里插入图片描述
两个Sphere要勾选触发器:
在这里插入图片描述
然后,我们把子对象Cube(1)作为门,给Cube(1)创建一个Animator组件。
在这里插入图片描述
在Project面板中,创建两个动画,分别命名为DoorOpen和DoorClose:
在这里插入图片描述
然后把DoorClose拖到Cube(1)的Inspector面板,会自动和刚刚为Cube(1)创建的Animator组件绑定,同时在Project中会出现一个动画控制器。然后双击打开控制器:
在这里插入图片描述
把Project中的DoorOpen也拖到面板中,然后把三个元素连成上面图中的样子,连接方法是:右键箭头出发的元素,然后选择Make Transition,然后再选择被连接的组件即可。
在这里插入图片描述
双击DoorOpen,会进入动画编辑器,进入后我们点击Cube(1)对象,然后点击控制器中红色圆圈录制动画,把时间线拖动到1s的位置,然后在Scene中把Cube(1)给拉起高度,然后再次点击红色圆圈,动画制作完毕,具体地:

①打开控制器,点击Cube(1),开始录制动画,时间拨到1s的操作顺序为:
在这里插入图片描述
②拉起门,结束录制:
在这里插入图片描述
然后,我们重新进入动画控制器,并进入Parameters面板,添加Bool变量opendoor:
在这里插入图片描述
然后分别点击DoorClose指向DoorOpen的箭头和DoorOpen指向DoorClose的箭头,设置对变量opendoor的绑定分别为true和false,这样,我们只要在人物碰到Sphere按钮时,修改这个opendoor变量的值,就可以控制动画的流程了。
在这里插入图片描述
最后,我们编写名为CubeDoorOpen的脚本:

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

public class CubeDoorOpen : MonoBehaviour
{
    public GameObject door;

    private void OnTriggerEnter(Collider other)
    {
        if ("MoveObject" == other.gameObject.tag)
        {
            bool x = door.GetComponent<Animator>().GetBool("opendoor");

            x = !x;

            door.GetComponent<Animator>().SetBool("opendoor", x);
        }
    }

}

把它添加给Home下的两个Sphere,并把Cube(1)拖给变量door:
在这里插入图片描述
效果为:
在这里插入图片描述
项目已经上传Github,链接

参考文献


  1. 这哥们的视频我是在上个教程的评论区发现的,先看看 ↩︎

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
学习Unity3D时,以下是一些重要的笔记: 1. Unity3D基础知识: - 游戏对象(Game Objects)和组件(Components):了解游戏对象的层次结构和组件的作用。 - 场景(Scenes)和摄像机(Cameras):学会如何创建场景并设置摄像机视角。 - 材质(Materials)和纹理(Textures):掌握如何创建和应用材质和纹理。 - 动画(Animations):学习如何创建和控制游戏对象的动画。 2. 脚本编程: - C#语言基础:了解C#语言的基本语法和面向对象编程概念。 - Unity脚本编写:学习如何编写脚本来控制游戏对象的行为和交互。 - 常见组件和功能:掌握常见的Unity组件和功能,如碰撞器(Colliders)、刚体(Rigidbodies)、触发器(Triggers)等。 3. 游戏开发流程: - 设计游戏关卡:了解如何设计游戏场景和关卡,包括布局、道具、敌人等。 - 游戏逻辑实现:将游戏规则和玩家交互转化为代码实现。 - UI界面设计:学习如何设计游戏中的用户界面,包括菜单、计分板等。 - 游戏优化和调试:优化游戏性能,解决常见的错误和问题。 4. 学习资源: - Unity官方文档和教程:官方提供了大量的文档和教程,逐步引导你学习Unity3D。 - 在线教程和视频教程:网上有很多免费和付费的Unity教程和视频教程,可根据自己的需求选择学习。 - 社区论坛和博客:加入Unity开发者社区,与其他开发者交流并获取帮助。 通过系统地学习这些内容,你将能够掌握Unity3D的基础知识并开始开发自己的游戏项目。记得不断实践和尝试,不断提升自己的技能!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值