首页 > 其他分享 >入门笔记

入门笔记

时间:2023-03-11 11:56:23浏览次数:32  
标签:UnityEngine 入门 void transform 笔记 物体 using public

Unity

 

 

1.基本介绍

1.1Unity的安装与汉化_引擎安装与基础操作

安装时先安装Unity Hub,再安装Unity.

汉化在Unity Hub的Installs中找到对应版本的Unity,左上角的设置按钮,在跳出的窗口选择中文包,下载安装好后进入Unity,在Edit>Preferences>Languages>Editor Languages中选择中文版本。

1.2Unity窗口界面介绍与布局

2.2.1Scene界面

1.鼠标右键旋转视角

2.按住鼠标滚轮移动视角

3.旋转鼠标滚轮调整远近视角

4.按住右键并按WASD可以在场景中进行漫游

5.Pivot和Center

Pivot表示轴心,在该状态下,点击父物体时坐标会落在父物体上,旋转时也是子物体围绕父物体旋转。

Center表示中心,在该状态下,点击父物体时坐标会落在父物体与其所有的子类物体(包括孙物体和后面的物体)的中心点,旋转时也会围绕该中心点旋转。

6.Global和Local

Global表示全局,在该状态下,旋转后物体的坐标方向会与原始的坐标方向一致。

Local表示局部,在该状态下,旋转后物体的坐标会保持旋转后的方向。

2.2.2Project界面

选择文件并右键点击Show in explorer可以打开所在文件夹

1.3Unity菜单

Fils,Edit,Assets,...等菜单的功能。

 

2.游戏流程控制与脚本基础

2.1脚本生命周期

2.1.1方法名

示例

using UnityEngine;

public class Test : MonoBehaviour

{

/*游戏开始时调用,在脚本组件未勾选的情况下也可运行。*/

    void Awake()

    {

        Debug.Log("Awake");

    }

/*当物体被启用时调用*/

    void OnEnable()

    {

        Debug.Log("Enable");

    }

/*没有Reset方法的情况下,会在执行OnEnable方法后执行*/

    void Start()

    {

        Debug.Log("Start");

    }

/*每帧调用一次,一般用于非物理运动,例如游戏的逻辑。*/

    int updateCount = 0;

    void Update()

    {

        Debug.Log("Update第" + UpdateCount++ + "次打印");

    }

/*以相同的时间间隔调用,用在力学更新效果中。*/

    int fixedUpdateCount = 0;

    void FixedUpdate()

    {

        Debug.Log("FixedUpdate第" + FixedUpdateCount++ + "次打印");

    }

/*在Update和FixedUpdate调用后调用。*/

    int lateUpdateCount = 0;

    void LateUpdate()

    {

        Debug.Log("LateUpdate第" + LateUpdateCount++ + "次打印");

    }

/*当物体被禁用时调用*/

    void OnDisable()

    {

        Debug.Log("OnDisable");

    }

/*当物体销毁后执行*/

    void OnDestroy()

    {

        Debug.Log("Ondestroy");

    }

}

该段代码的功能是,通过控制台打印观察方法的执行顺序

2.1.2检测调用间隔时间

使用的API:Time.deltaTime;

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    void Update()

    {

        Debug.Log("Update"+Time.deltaTime);

    }

}

该脚本实现的功能是每帧输出一次文字Update和每帧的间隔时间。

2.2变量的创建与使用

2.2.1变量的创建

变量在类下面直接创建,默认为私有,如为私有可省略Private.

2.2.1变量的操作

1.隐藏Publicb变量

在变量上方用 [HideInInspector]

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    [HideInInspector]   //序列化  隐藏

    public int num;

}

2.显示private变量

在变量上方用[SerializeField]

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    [SerializeField]    //序列化  显示

    private int num;

}

3.设置变量范围

在变量上方用[Range(a,b)]

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    [Range(1, 100)]

    public int num;

}

 

3.游戏素材与脚本

3.1游戏素材

游戏素材包括字体,图片,音频,视频,模型,场景,粒子特效等。

素材的添加可以通过在Project中点击右键选择Import New Assets或Import Package实现,也可以通过文件夹拖入的方式实现。

3.2游戏脚本

游戏脚本可以通过在Project中点击右键Create>C# Script创建。

游戏脚本需要挂载到物体上方能实现其功能。

游戏脚本命名不能加空格,否则无法挂载。

 

4.游戏物体

4.2物体的标签和层级

标签可以方便查找物体。

层级可以运用在一些操作上,比如Camera中Inspector中的Culling Mask上,可以通过勾选掉一些层级来屏蔽显示一些物体

4.3摄像机

组件Camera>Projection下的persepective表示透视,透视模式下可以通过Field in view调镜头的角度;另一个Orthography表示正交即在播放时场景没有透视效果。

组件Camera>Clipping Planes为视距设置选项,在视距范围之外(高于最远视距,低于最近视距)的物体无法被摄像机看到。

4.4预制件

4.4.1克隆预制件

使用的API:GameObject.Instantiate(变量名);

示例:

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        GameObject go = Resources.Load<GameObject>("Cubes/Cube");

        GameObject.Instantiate(go);

    }

}

在Project中新建Resources文件夹,在Resources文件夹下新建Cubes文件夹,将Hierachy中做好的物体Cube拖入Cubes文件夹中,制成预制件。该段代码实现的功能是:在运行时将Resources/Cubes文件夹中的Cube预制件克隆一份并显示。

4.4.2修改预制件

预制件的修改的两种方式;

第一种:在Project中双击预制件,或者在Hietachy中点击其中一个预制件的最后的“>”标志,进入预制件修改视图,在修改视图中进行预制件的修改。

第二种:在Hierachy中选择一个预制件,直接进行修改,修改后再单击Hierachy中的预制件,在Inspector中找到Override按钮,点击按钮并选择Apply All即可完成对预制体的修改。预制件的Inspector中的组件参数修改后会留下标记,在标记行点击鼠标右键会出现Apply to prefab”/*预制件名称*/”的提示框,点击即将修改应用至预制件。

4.5通过脚本操作物体

4.5.1查找物体

1.按照路径查找物体

使用的API:GameObject.Find(物体的Hietachy路径);

示例:

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        GameObject go = GameObject.Find("Cube/Sphere");

        go.SetActive(false);

    }

}

在Hierachy中新建一个物体Cube,在Cube下新建一个子物体Sphere,将含上面代码的脚本挂载到某一物体上,可以实现在运行时隐藏物体Sphere,若一个文件夹下有同名的多个物体,则查找到的物体为创建时间最短的物体。

2.按照标签查找

使用的API:GameObject.FindGameObjectWithTag("标签名");

示例:

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        GameObject go = GameObject.FindGameObjectWithTag("Player");

        go.SetActive(false);

    }

}

该段代码的功能是找到最后将标签设置成Player的物体,并在运行时隐藏该物体。

4.5.2修改物体名称

使用的API:物体名.name=”修改后物体名称”;

示例:

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        GameObject go = GameObject.Find("Cube/Sphere");

        go.name = "CuteSphere";

    }

}

该段代码功能是找到物体Sphere,并在运行时将该物体名称改为CuteSphere。

4.5.3修改物体位置

使用的API:变量名.transform.position=/*更改后的位置*/

示例:

using UnityEngine;

 

public class Temp : MonoBehaviour

{

    public GameObject cube;

    void Start()

    {

        cube.transform.position = new Vector3(2, 1, 3);

    }

}

该段代码功能是,将物体的位置移动到世界坐标(2,1,3)的位置。

如果是想让物体移动到相对坐标(2, 1, 3)的位置,可将代码cube.transform.position = new Vector3(2, 1, 3);写成cube.transform.localposition = new Vector3(2, 1, 3);

如果想让找到的物体在运行时旋转一定角度,可以将上面示例中的代码cube.transform.position = new Vector3(2, 1, 3);写成go.transform.Rotation= Quaternion.Euler(new Vector3(a, b, c))或cube.transform.eulerAngles = new Vector(a,b,c))/*a,b,c表示旋转角度*/;

如果想让找到的物体在运行时放大或缩小,可以将上面示例中的代码cube.transform.position = new Vector3(2, 1, 3);写成cube.transform.localScale = new Vector3(a,b,c))/*a,b,c表示放大倍数*/;

4.5.4删除物体

使用的API:Destroy( );

示例:

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        GameObject go = GameObject.Find("Cube/Sphere");

        Destroy(go);

    }

}

该段代码功能是找到物体Sphere,并在运行时删除该物体。

如果想实现在运行后5秒消除,可以将代码Destroy(go);修改为Destroy(go,5);。

如果想让物体在切换场景的时候不销毁,可以将Destroy(go);修改为DontDestroyOnLoad(go);。

4.5.5克隆物体

示例:

using UnityEngine;

public class Test : MonoBehaviour

{

    public GameObject Cube;

    void Start()

    {

        GameObject.Instantiate(Cube);

    }

}

将含上面代码的脚本挂载到某一物体上,并将需要克隆的物体Cube拖入脚本组件中,运行后便可在场景中得到一个克隆的预制体Cube。

5.物体组件

5.1组件的基本操作

代码类名后面跟的MonoBehaviour使脚本能够挂到物体的组件中。

组件在Inspector视图中,可以通过最下面的Add Component添加组件,通过组件点击组件名左边的勾选符号打开或关闭组件,通过组件名右边的三个点下面的Remove Component移除组件。

5.2通过脚本操作组件

5.2.1添加组件

使用的API:AddComponent</*组件名称*/>();

示例:

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        GameObject go = GameObject.Find("Cube/Sphere");

        go.AddComponent<Rigidbody>();

    }

}

该段代码先找出物体Sphere,运行时在该物体上添加Rigidbody组件。

5.2.2查找组件

1.查找单个组件

使用的API:GetComponent</*组件名称*/>()

示例:

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        GameObject go = GameObject.Find("Cube/Sphere");

        go.GetComponent<SphereCollider>().radius = 1;

    }

}

该段代码的功能是,先查找Sphere物体,然后查找Sphere物体的SphereCollider组件,并将该组件中radios值改为1。

如果想查找该物体及其子物体的某个组件,可以将示例代码中的go.GetComponent<SphereCollider>().radius = 1;改为go.GetComponentInChildren<SphereCollider>().radius = 1;,改完之后会查找该物体及其子物体的该组件类型,找到一个后便停止,不再继续查找。

如果想查找该物体及其父物体的某个组件,可以将示例代码中的go.GetComponent<SphereCollider>().radius = 1;改为go.GetComponentInParent<SphereCollider>().radius = 1;改完之后会查找该物体及其父物体的该组件类型,找到一个后便停止,不再继续查找。

2.查找多个同类型的组件

使用的API:GetComponents<AudioSource>();

示例:

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        GameObject go = GameObject.Find("Cube/Sphere");

        SphereCollider[] sphereColliders= go.GetComponents<SphereCollider>();

        Debug.Log("查找到多少个:"+sphereColliders.Length);

    }

}

这段代码的功能是,先找到Sphere物体,找出物体里所有SphereCollider组件,将找到的组件放入数组SphereCollider中,并通过控制台打印数组的长度。

如果想查找该物体及其子物体的某个组件,可以将示例代码中的SphereCollider[] sphereColliders= go.GetComponents<SphereCollider>();改为SphereCollider[] sphereColliders= go.GetComponentsInChildren<SphereCollider>();改完之后会查找该物体及其子物体的所有该组件类型。

如果想查找该物体及其父物体的某个组件,可以将示例代码中的SphereCollider[] sphereColliders= go.GetComponents<SphereCollider>();改为SphereCollider[] sphereColliders = go.GetComponentsInParent<SphereCollider>();改完之后会查找该物体及其父物体的所有该组件类型。

5.2.3删除组件

使用的API:Destroy(/*要删除的组件类型*/);

示例:

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        GameObject go = GameObject.Find("Cube/Sphere");

        SphereCollider sphereCollider = go.GetComponent<SphereCollider>();

        Destroy(sphereCollider);

    }

}

该段代码的功能是,找到物体Sphere,并在运行时删除该物体的SphereCollider组件。SphereCollider sphereCollider = go.GetComponent<SphereCollider>();改为Component sphereCollider = go.GetComponent<SphereCollider>();也可实现该效果。

5.2.4关闭和激活组件

使用的API:enabled=false;

示例:

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        GameObject go = GameObject.Find("Cube/Sphere");

        go.GetComponent<SphereCollider>().enabled=false;

    }

}

该代码的功能是,找到物体Sphere,并在运行时关闭该物体的SphereCollider组件。

如果想要激活组件,可以将上面示例中的go.GetComponent<SphereCollider>().enabled=false;改为go.GetComponent<SphereCollider>().enabled=true;

 

 

6.场景管理

6.1场景的基础操作

6.1.1场景的创建

场景创建的快捷键Ctrl+N可以快捷创建场景,此时创建的场景为临时场景,需要保存起来后续才能使用。

6.1.2场景的删除

直接在文件夹中进行删除即可,因为场景中可能会有一些依赖项,因此非必要不要删除场景。

6.2同步加载场景

6.2.1切换场景

使用的API:SceneManager.LoadScene( );

示例:

using UnityEngine;

using UnityEngine.SceneManagement;

public class Test : MonoBehaviour

{

    void Start()

    {

        SceneManager.LoadScene("Scenes/SampleScene1");

    }

}

先将两个场景导入File>Build Settings...中,将含上面代码的脚本挂到待切换场景的一个物体上,该脚本可以实现将场景切换至Scenes文件夹下的SampleScene1场景播放;

地址"Scenes/SampleScene1"也可换成该场景在Build Settings...中所对应的序号。

6.2.2同时加载场景

使用的API:SceneManager.LoadScene( ,LoadSceneMode.Additive);

示例:

using UnityEngine;

using UnityEngine.SceneManagement;

public class Test : MonoBehaviour

{

    void Start()

{     

SceneManager.LoadScene("Scenes/SampleScene1",LoadSceneMode.Additive);

    }

}

先将两个场景导入File>Build Settings...中,将含上面代码的脚本挂到原场景的一个物体上,该脚本可以实现将原将原场景与Scenes文件夹下的SampleScene1场景同时加载;

地址"Scenes/SampleScene1"也可换成该场景在Build Settings...中所对应的序号。

6.3异步加载场景

示例

using System.Collections;

using UnityEngine;

using UnityEngine.SceneManagement;

public class Test : MonoBehaviour

{

    void Start()

    {

        StartCoroutine(Load());

    }

    private IEnumerator Load()

    {

        AsyncOperation asyncOperation=SceneManager.LoadSceneAsync("Scene/Cut");

        asyncOperation.allowSceneActivation = false;

        while (asyncOperation.progress < 0.9f)

        {

            Debug.Log("Current progress is " + asyncOperation.progress);

            yield return null;

        }

        asyncOperation.allowSceneActivation = true;

        if (asyncOperation.isDone)

        {

            Debug.Log("Finished load and skip.");

        }

        else

        {

            Debug.Log("Not finished");

        }

    }

}

不理解该段代码

6.4加载场景时保留物体

使用的API:DontDestroyOnLoad( );

示例:

using UnityEngine;

using UnityEngine.SceneManagement;

public class Test : MonoBehaviour

{

    void Start()

    {

        GameObject capsule = GameObject.Find("Capsule");

        DontDestroyOnLoad(capsule);

        SceneManager.LoadScene("Scenes/SampleScene1");

    }

}

先将两个场景导入File>Build Settings...中,将含上面代码的脚本挂到原场景的一个物体上,该脚本实现的功能是将原场景切换至Scenes文件夹下的SampleScene1场景后保留原场景的Cube物体及该物体下面的子物体,该代码保留的物体只能是根物体,即没有父物体的物体。

地址"Scenes/SampleScene1"也可换成该场景在Build Settings...中所对应的序号。

 

7.UGUI图形系统

7.1画布与事件系统

7.1.1画布

画布用于承载所有的UI元素。

Canvas物体的Canvas组件Render Mode分为三种:

第一种:Screem Space Overlay模式,该模式下画布中的元素始终在前面。

第二种:Screem Space Camera模式,该模式下画布中的元素是否在前取决于它与物体的位置。

第三种:World Space模式,该模式下画布可以自由移动缩放。可用来做人物的血条等。

7.1.2事件系统

事件系统是使画布内元素产生效果系统,创建画布后会自动创建,如果不小心删除也可点击添加单独创建。

7.2图像、文本框、按钮、输入框的脚本交互

7.2.1登录按钮的脚本实现

示例

using UnityEngine;

using UnityEngine.UI;

public class Login : MonoBehaviour

{

    InputField accountInput;

    InputField passwordInput;

    Button loginButton;

    void Start()

    {

        accountInput = transform.Find("Account").GetComponent<InputField>();

        passwordInput = transform.Find("Password").GetComponent<InputField>();

        loginButton = transform.Find("Login").GetComponent<Button>();

        loginButton.onClick.AddListener(LoginButtonOnClick);

    }

    void LoginButtonOnClick()

    {

        string account = accountInput.text;

        string password = passwordInput.text;

        Debug.Log("Account is " + account);

        Debug.Log("Password is " + password);

    }

 

}

该段代码实现的功能是,在输入账号和密码并点击登录键后,将账号和密码在控制台输出。

7.2.2更换背景图的脚本实现

示例

using UnityEngine;

using UnityEngine.UI;

public class Change : MonoBehaviour

{

    public Sprite bg;

    void Start()

    {

        transform.Find("Background").GetComponent<Image>().sprite = bg;

    }

}

该段代码实现的功能是,在将新的图像添加到新建的脚本后,点击播放可以在运行时将背景图换成新的图像

7.2.3修改文本框

示例

using UnityEngine;

using UnityEngine.UI;

public class Test : MonoBehaviour

{

    string text = "抵制不良游戏,拒绝盗版游戏。注意自我保护,谨防受骗上当。\n适度游戏益脑,沉迷游戏伤身。合理安排时间,享受健康生活。";

    void Start()

    {

        transform.Find("Text").GetComponent<Text>().text = text;

    }

}

该段代码实现的功能是,在运行时将文本框文字改为:抵制不良游戏,拒绝盗版游戏。注意自我保护,谨防受骗上当。适度游戏益脑,沉迷游戏伤身。合理安排时间,享受健康生活。

7.2.4点击按钮导入链接

示例

using UnityEngine;

using UnityEngine.UI;

public class Test : MonoBehaviour

{

    void Start()

    {

transform.Find("Button").GetComponent<Button>().onClick.AddListener(ButtonOnClick);

    }

    void ButtonOnClick()

    {

        Application.OpenURL("https://v.qq.com/channel/choice?channel_2022=1");

    }

}

该段代码实现的功能是,在点击了Button按钮后,跳转到网站https://v.qq.com/channel/choice?channel_2022=1。

7.3切换开关与开关组

7.3.1切换开关

示例

using UnityEngine;

using UnityEngine.UI;

public class Test : MonoBehaviour

{

    InputField user;

    InputField password;

    Toggle toggle;

    Button logon;

    void Start()

    {

        user= transform.Find("User").GetComponent<InputField>();

        password = transform.Find("Passward").GetComponent<InputField>();

        toggle=transform.Find("Toggle").GetComponent<Toggle>();

        logon=transform.Find("Logon").GetComponent<Button>();

        logon.onClick.AddListener(logonOnClick);

    }

    void logonOnClick()

    {

        if (toggle.isOn == true)

        {

            string username= user.text;

            string passwordnum=password.text;

            Debug.Log("用户名是:"+username);

            Debug.Log("密码是:"+passwordnum);

        }

        else

        {

            Debug.Log("请先同意用户协议");

        }

    }

}

该段代码实现的功能是,在点击了按钮后,可以正常登录,未点击时控制台显示:请先同意用户隐私协议!

7.3.2开关组

若有多个Toogle,而只能选择一个,可在Hierachy中新建一个空对象,在空对象的Inspector中添加一个Toggle Group,将空对象移入每个Toogle的Inspector>Toogle>Group中,运行即可实现单选,Toggle Group的Allow Switch Off指允许取消勾选,即选择后可以实现一个都不选。

7.4滑动条Slider的使用

示例

using UnityEngine;

using UnityEngine.UI;

public class Test : MonoBehaviour

{

    Slider slider;

    void Start()

    {

        slider = transform.Find("Slider").GetComponent<Slider>();

        slider.onValueChanged.AddListener(OnValueChanged);

    }

    void OnValueChanged(float value)

    {

        Debug.Log("进度条的值为:"+slider.value);

    }

}

该段代码的功能是,在控制台显示slider滑动的值。

 

7.5滚动视图与遮罩的使用

7.5.1滚动视图Scroll View

滚动视图是容纳多个图标的容器,可以通过拖动滚动条来查看所有的图标,因为在Scroll View中的Viewport含有Mask组件,所以,图标只会在滚动视图内显示。

7.5.2Mask和Rect Mask 2D

Mask作为父物体的组件时,子物体超出父物体的部分不会显示,这里会识别父物体的透明度,透明度高的部分也不会被显示。

Rect Mask 2D作为父物体的组件时功能与Mask相同,但不会识别父物体的透明度,父物体以矩形方式呈现。

 

7.6水平、垂直、网格布局组件与布局元素

7.6.1水平、垂直和网格布局

水平布局组件:Horizontal Layout Group,在Scroll View>View Port>Content中加入该组件,可以将滚动视图中的图像设置成一行,并进行相关设置。

垂直布局组件:Vertical Layout Group,在Scroll View>View Port>Content中加入该组件,可以将滚动视图中的图像设置成一列,并进行相关设置。

网格布局组件:Grid Layout Group,在Scroll View>View Port>Content中加入该组件,可以将滚动视图中的图像设置成方固定方格排列,并进行相关设置。

7.6.2布局元素

布局元素组件:Layout Element,网格布局元素中的单个图像若添加该组件,并选择组件中的Ignore Layout,可以使该图像自由移动,不受网格限制。

 

7.7内容尺寸适配器Context Size Fitter

7.7.1内容尺寸适配器

该组件英文名Context Size Fitter,当在内容输入文本框或者在Scroll View>View Port>Content的网格状态下使用该组件,把Horizontal Fit项设置成Preferred Size时,可以根据内容自适应左右宽度的大小,Vertical Fit同理。

7.7.2克隆元素图标

示例

using UnityEngine;

public class Clone : MonoBehaviour

{

    public GameObject hero;

    public Transform content;

    void Update()

    {

        if (Input.GetKeyDown(KeyCode.A))

        {

            GameObject clonehero=GameObject.Instantiate(hero);

            clonehero.transform.parent = content;

        }

    }

}

将元素图标的预制件与HeroPanel>Scroll View>View Port>Content拖入该脚本并将该脚本挂到penel中后,可以在播放时通过按A键来克隆物体。

7.8UI特效与图片填充功能

7.8.1UI特效

Outline组件,该组件可以通过设置大小、颜色等给UI元素(如图片)描边。

Shadow组件,该组件可以通过设置大小、颜色等给UI元素(如图片)设置阴影。

7.8.2图片型进度条制作

示例

using System.Collections;

using UnityEngine;

using UnityEngine.UI;

public class FullFill : MonoBehaviour

{

    public Image image;

    void Start()

    {

        StartCoroutine(Fill());

    }

    IEnumerator Fill()  //协程就是要等时间

    {

        float value = 0;

        while(value<=1)

        {

            yield return new WaitForSeconds(0.5f);

            value+=0.1f;

            image.fillAmount = value;

        }

    }

}

新建两个层级不同的Image,父Image设置成背景色,子Image设置成填充色,并在子Image的Sourse Image中导入一张图片,将Image Type设置成Filled,将Fill Method设置成Horizontal,将Fill Origin设置成Left,将含上面代码的脚本挂到某一物体上,将子Image挂到脚本中,可以实现实现播放时的进度条加载效果。

 

8.用户输入管理

8.1虚拟轴

使用的API:.GetAxis("/*Edit>Project Settings>Input Manager>Axes中对应的名字*/");

8.1.1控制位置  

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    void Update()

    {

        float horizontal = Input.GetAxis("Horizontal");

        float vertical = Input.GetAxis("Vertical");

        if (horizontal != 0)

        {

            transform.position=new Vector3(transform.position.x+horizontal*0.1f, transform.position.y,transform.position.z);

        }

        if(vertical != 0)

        {

            transform.position=new Vector3(transform.position.x,transform.position.y+vertical*0.1f,transform.position.z);

        }

    }

}

该段代码实现的目标是在运行时可以通过WASD来控制前后左右,Horizontal和Vertical是Edit>Project Settings>Input Manager>Axes中Horizontal和Vertical的名字。

8.1.2控制旋转

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    void Update()

    {

        float horizontal = Input.GetAxis("Horizontal");

        if (horizontal != 0)

        {

            transform.eulerAngles=new Vector3(transform.eulerAngles.x, transform.eulerAngles.y+horizontal, transform.eulerAngles.z);

        }

    }

}

该段代码实现的功能是通过AD来控制左右旋转。

8.1.3控制其他

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    void Update()

    {

        Debug.Log(Input.GetAxis("Mouse X"));

    }

}

该段代码实现的功能是在控制台输出鼠标在X轴方向移动的值,Mouse X也可以换成Edit>Project Settings>Input Manager>Axes中的其他值来实现相应的控制。

8.2获取键盘事件

使用的API:GetKey("相应的键"/*也可以用KeyCode.A*/)

using UnityEngine;

public class Test : MonoBehaviour

{

    void Update()

    {

        if (Input.GetKey("a"/*也可以用KeyCode.A*/))

        {

            Debug.Log("A键被按下了");

        }

    }

}

该段代码实现的功能是,在按住A键时控制台不停输出:A键被按下了。

若上面代码将GetKey换成GetKeyDown,则控制台会在按键按下时打印一次输出。

若上面代码将GetKey换成GetKeyUp,则控制台会在按键抬起时打印一次输出。

8.3获取鼠标事件

8.3.1获取鼠标按键

使用的API:GetMouseButtonDown(数字)、GetMouseButtonUp(数字)、GetMouseButton(数字)/*数字0代表鼠标左键,数字1代表鼠标右键,数字2代表鼠标滚轮*/

示例1

using UnityEngine;

public class Test : MonoBehaviour

{

    void Update()

    {

        if (Input.GetMouseButtonDown(0))

        {

            GameObject cube = GameObject.Find("Cube");

            cube.transform.localScale=new Vector3(2,2,2);

        }

    }

}

画面中创建一个立方体,当上述代码执行时,按下鼠标左键,画面中的立方体会放大一倍。

若将上面代码中的GetMouseButtonDown换成GetMouseButtonUp则会在按键抬起时执行效果。

示例2

using UnityEngine;

public class Test : MonoBehaviour

{

    void Update()

    {

        if (Input.GetMouseButtonDown(0))

        {

            GameObject cube = GameObject.Find("Cube");

            cube.transform.localScale+=new Vector3(1,1,1);

        }

    }

}

上述代码的功能是,在播放时不停按下鼠标左键,立方体会被不断放大。

8.3.2获取鼠标位置

使用的API:Input.mousePosition;

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    bool isDown=false;

    void Update()

    {

        if (Input.GetMouseButtonDown(0))

        {

            isDown=true;

        }

        if (Input.GetMouseButtonUp(0))

        {

            isDown = false;

        }

        if (isDown)

        {

            GameObject go = GameObject.Find("Image");

            go.transform.position=Input.mousePosition;

        }

    }

}

创建一个图片,该段代码实现的功能是,点击鼠标左键后,图片会回到鼠标指针所在的位置,当鼠标持续点击并移动时,图片会跟随鼠标指针。

8.4移动设备输入

使用的API:Input.touchCount

          Input.touches[0].fingerId

Input.touches[0].position

Input.touches[0].deltaPosition;

示例

using UnityEngine;

using UnityEngine.UI;

public class MyText : MonoBehaviour

{

    Text juse;

    void Start()

    {

        juse = GameObject.Find("Text").GetComponent<Text>();

    }

    void Update()

    {

        if (Input.touchCount >= 1)

        {

            juse.text= "当前有:" + Input.touchCount + "根手指触碰。" + "当前手指的ID是:" + Input.touches[0].fingerId + "当前手指所在位置是:" + Input.touches[0].position + "从上一帧到现在移动了:" + Input.touches[0].deltaPosition;

        }

    }

}

在场景中新建一个Text,将上面的代码写好并打包成apk文件,运行apk文件,在点击屏幕的时候,屏幕上会显示当前有几根手指触碰,当前手指的ID,当前手指所在位置,和从上一帧到现在移动了多少。

 

9.自然环境设计

9.1天空盒的创建

9.1.1六张图片创建

在Project中新建材质,将Inspector>Shader中将材质设置成Skybox>6 Side,导入6张照片,将6张照片添加进Inspector中,再将新建材质拖入Scene中。

9.1.2全景图片创建

在Project中新建材质,将Inspector>Shador中将材质设置成Skybox>Cubemap,导入一张全景图片,将图片的Texture Shape设置成Cube,再将图片拖进新建材质的Inspector中,将新建材质拖入Scene中。

9.2山脉和地表贴图的创建

在Hierachy视图中新建Terrain物体,在Terrain的Inspector>Terrain中对地形进行修改,如果要Paint Texture需要先创建图层。

9.3树和草的创建

通过在Terrain的Inspector>Terrain中对地形添加树和草,树和草均需要先添加图层。

在Hierachy中添加Windzone来使树木在播放时有风吹效果。

9.4水和雾

通过将一个水的预制件(也可自己制作,即一个有动态纹理的平面)加入场景实现水的效果。

通过点击Lighting>Other Seeting>Fog来实现雾的效果,还可在下面设置雾的颜色,密度等。

 

10.光照系统

10.1灯光组件

10.1.1区域灯光的使用

先将Lighting>Mixed Lighting>Baked Global Illumin选项打开,并将Lighting>Lightmap Setting>Lightmapper设置为progressive GPU(preview),,创建一个区域光和一个其他类型(直线光、点光、和聚光都可)的光源,设置区域光的光照范围和颜色,在Lighting中点击Generate Lighting就可以看到静态的物体被渲染成了区域光的颜色,而其非静态物体则不受影响,烘焙后的物体的颜色将一直保存,不随区域光的删除而消失,除非在Lighting中点击Generate Lighting重新生成照明。

10.1.2灯光组件介绍

灯光组件的添加及灯光组建的功能。

10.2照明设置

照明设置打开方式:Windows>Rendering>Lighting Setting.

介绍了Lighting的一些按钮功能。

10.3自发光

自发光物体创建方式:在Project中新建材质,在新建材质的组件中将Emission勾选上,将挂上贴图和设置颜色,在将新建材质挂到物体的Mesh Render>Material中,即可以实现物体的自发光。

10.4光照探测器

自发光可以在Generate Lighting后让静态物体有烘焙效果,但对非静态物体无效。

通过在Hierachy里添加光照探测器,并编辑光照探测器的范围,让非静态物体在光照探测器的范围之内,点击Lighting>Generate Lighting,可以使非静态物体也能有烘焙效果。

10.5反射探测器

若一个房间里的地板上反射的灯光模糊,可以在Hierachy里添加反射探测器,将反射探测器调整至合适的大小,将房间的地板在组件中取消勾选Matellic,并将Smooth的值拉到最大,将反射探测器组件中的Type改为Realtime,此时地面就可以呈现镜子般反射灯光的效果。

 

12.3D物理系统

12.1刚体组件介绍

介绍了刚体组件Rigidbody的中一些选项的功能。

Rigidbody组件中的Is Kinematic勾选上后,该物体将不会受到碰撞等效果的影响。

12.2刚体常用的方法

12.2.1Constant Forse组件

可以在该组件中设置不同方向的恒定力,Relative表示按照相对坐标的的方向确定力。

12.2.2添加刚体速度

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    Rigidbody rb;

    void Start()

    {

        rb = GetComponent<Rigidbody>();

        rb.velocity = new Vector3(0, 0, 5);

    }

}

该段代码的功能是,使脚本所挂的物体在世界坐标的Z轴方向以5的速度运动。

12.2.3添加力

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    Rigidbody rb;

    void Start()

    {

        rb = GetComponent<Rigidbody>();

        rb.AddForce (new Vector3(0, 0, 10f));

    }

}

该段代码的功能是在代码所挂的物体上添加一个世界坐标Z轴方向的大小为50的力。

若想添加相对坐标的Z轴的方向的力,可以将上述代码中的rb.AddForce(new Vector3(0, 0, 10f));改为rb.AddRelativeForce (new Vector3(0, 0, 10f));

若想添加世界坐标Z轴方向的扭矩力,可以将上述代码中的rb.AddForce(new Vector3(0, 0, 10f));改为rb.AddTorque (new Vector3(0, 0, 10f));

若想添加相对坐标Z轴方向的扭矩力,可以将上述代码中的rb.AddForce(new Vector3(0, 0, 10f));改为rb.AddRelativeTorque (new Vector3(0, 0, 10f));

ForceMode 力的模式

在unity中,Rigidbody.AddForce()实现对刚体物体施加力的效果,实现物体例如碰撞,爆炸等等效果

调用函数如下:

public void AddForce(Vector3 force, ForceMode mode = ForceMode.Force);

public void AddForce(float x, float y, float z, ForceMode mode = ForceMode.Force);

AddForce()函数有一个参数 ForceMode , 为枚举类型

Force:添加一个可持续力到刚体,使用它的质量

Acceleration:添加一个可持续加速度到刚体,忽略它的质量。

Impulse:添加一个瞬间冲击力到刚体 ,使用它的质量。( 爆炸或碰撞力量 )

VelocityChange:添加一个瞬间速度变化给刚体,忽略它的质量。

具体介绍如下:

在以下举例中均设刚体质量为m=2.0f,力向量为f=(10.0f,0.0f,0.0f)。

1 . ForceMode.Force:默认方式,使用刚体的质量计算,时间间隔以系统帧频间隔计算(默认值为0.02s)。

则由动量定理 f • t = m • v

可得:10 * 0.02 = 2.0 * v1,从而可得 v1=0.1 m/s,即每秒刚体在X轴上值增加0.1米

2 . ForceMode.Acceleration:忽略刚体的实际质量而采用默认值m = 1.0f,时间间隔以系统帧频间隔计算(默认值为0.02s)

则 f • t = 1.0 • v

可得:10 * 0.02 = 1.0 * v2,从而可得 v2=0.2 m/s,即每秒刚体在X轴上值增加0.2米

3 . ForceMode.Impulse:采用瞬间力作用方式,即默认 t = 1.0f,不再采用系统的帧频间隔

则 f • 1.0 = m • v

可得:10 * 1.0 = 2.0 * v3,从而可得 v3=5.0 m/s,即每秒刚体在X轴上值增加5.0米

4 . ForceMode.VelocityChange:忽略刚体的实际质量,采用默认值m = 1.0f,同时也忽略系统的实际帧频间隔,采用默认间隔 t = 1.0f

则 f • 1.0 = 1.0 • v

可得:10 * 1.0 = 1.0 * v4,从而可得 v4=10.0 m/s,即每秒刚体在X轴上值增加10.0米

12.2.4爆炸力

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    Rigidbody rb;

    void Start()

    {

        rb = GetComponent<Rigidbody>();

    }

    void Update()

    {

        if (Input.GetKeyDown("a"))

        {

            rb.AddExplosionForce(500f, transform.position, 10f);/*三个参数分别是:爆炸力度、爆炸位置、爆炸范围*/

        }

    }

}

该段代码的功能是在运行时按下A键后,组件所挂的物体在原位置受到一个大小为500f的力。

12.2.5刚体的唤醒和休眠

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    Rigidbody rb;

    void Start()

    {

        rb = GetComponent<Rigidbody>();

    }

    void Update()

    {

        if (Input.GetKeyDown("a"))

        {

            rb.Sleep();

        }

        else if (Input.GetKeyDown("b"))

        {

            rb.WakeUp();

        }

    }

}

该段代码实现的功能是,在运行状态下按A键,刚体组件将失效,再按B键刚体组件将恢复效果。

12.3碰撞器和触发器

12.3.1碰撞器组件介绍

1.点了碰撞器组件中的Is Trigger按钮后,碰撞器变为触发器。

2.触发和碰撞检测的条件

碰撞器条件:1.碰撞与被碰撞物体都需要有碰撞器组件且都不能勾选为触发器。2.挂脚本的物体上有刚体组件。

触发器条件:1.碰撞与被碰撞物体,至少有一个勾选为触发器。2挂脚本的物体上有刚体组件。

12.3.2碰撞器

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    private void OnCollisionEnter(Collision collision)

    {

        Debug.Log("I had collision");

    }

}

该段代码的功能是,脚本所挂物体发生碰撞时控制台打印:我发生了碰撞。

若想在结束碰撞时调用控制台打印,可以将上述代码中的private void OnCollisionEnter(Collision collision)换成private void OnCollisionExit(Collision collision)。

若想在碰撞停留时调用控制台打印,可以将上述代码中的private void OnCollisionEnter(Collision collision)换成private void OnCollisionStay(Collision collision)。

12.3.3触发器

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    private void OnTriggerEnter(Collider collider)

    {

        Debug.Log("I had Trigger.");

    }

}

该段代码的功能是,脚本所挂物体发生碰撞时控制台打印:我发生了触发。

若想在结束触发时调用控制台打印,可以将上述代码中的private void OnTriggerEnter(Collider collider)改为private void OnTriggerExit(Collider collider)。

若想在触发停留时调用控制台打印,可以将上述代码中的private void OnTriggerEnter(Collider collider)改为private void OnTriggerStay(Collider collider)。

12.3.4所碰撞物体

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    public void OnCollisionEnter(Collision collision)

    {

        Debug.Log("Collision object is:" + collision.gameObject.name);

    }

}

该段代码可以在运行时打印脚本所挂物体所碰撞的物体名称。

12.4力的常用函数

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    Rigidbody rb;

    void Start()

    {

        rb = transform.GetComponent<Rigidbody>();

        Vector3 direction = transform.position + new Vector3(0, 1, 0) - transform.position;

        rb.AddForceAtPosition(direction * 10f, transform.position);

    }

}

该函数的功能是,使脚本所挂物体受到一个指定方向和作用点的力。

12.5物理材质

物理材质在Project>Creat>Physics Material中创建,创建后可以设置摩檫力、弹力等值,设置后拖入物体的Collider组件中,便可使组件具有该物理性质。

注意,当两个碰撞的物体设置了不同的结合方式时,采用的顺序如下: Average < Minimum < Multiply < Maximum,例如一个设置Minimum,一个设置Maximum,那么结合方式为Maximum。

12.6关节组件

12.6.1组件效果

固定关节组件(Fixed Joint):想两个物体用棍子连载一起。

弹簧关节组件(Spring Joint):像两个物体用弹簧连在一起。

铰链关节组件(Hinge Joint):像两个物体用铰链连在一起。

角色关节组件(Character Joint):可以模拟角色的骨骼关节。

可配置关节组件(Configurable Joint):可模拟任意关节效果。

12.6.2关节力度检测

检测断开的代码,脚本API:OnJointBreak

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    private void OnJointBreak(float force)

    {

        Debug.Log("Joint is break,force is:" + force);

    }

}

该段代码的功能是在设置了关节断开的力度后,运行时断开会在控制台打印关节断开了,并显示断开时的力度。

12.7射线

12.7.1射线的绘制

第一种方式:

脚本API:Debug.DrawLine(起点位置,终点位置,颜色,持续时长,是否被遮挡);

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        Debug.DrawLine(transform.position, new Vector3(5, 5, 5), Color.blue, 10,true);

    }

}

上述脚本的功能是,在脚本所挂物体处发射一条终点坐标为(5,5,5)的,蓝色的,延迟10秒的,可被遮挡的射线。

第二种方式:

脚本API:Debug.DrawRay(起点位置,方向和长度,颜色,持续时长,是否被遮挡);

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        Debug.DrawRay(transform.position,new Vector3(0,1,0),Color.blue,10,true);

    }

}

上述脚本的功能是,在脚本所挂物体处发射一条朝(0,1,0)方向的,两点之间长度的,蓝色的,延迟10秒的,可被遮挡的射线。

12.7.2射线检测

1.检测单个物体

第一种方式

using UnityEngine;

public class Test : MonoBehaviour

{

    Ray ray;

    RaycastHit hit;

    void Update()

    {

        ray = Camera.main.ScreenPointToRay(Input.mousePosition);

        if (Physics.Raycast(ray, out hit))

        {

            Debug.Log("Mouse point attached to " + hit.transform.name);

        }

    }

}

将含上面代码的脚本挂到摄像机上,在运行时可以显示鼠标指向的物体的名称。

第二种方式

使用的API:Physics.Raycast(射线,光线碰到的物体out hit(类型RaycastHit),射线长度float,遮罩过滤层LayerMask)

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    Camera camera;

    void Start()

    {

        camera = GameObject.Find("Main Camera").GetComponent<Camera>();

    }

    void Update()

    {

        if (Input.GetMouseButtonDown(0))

        {

            Ray ray = camera.ScreenPointToRay(Input.mousePosition);

            RaycastHit hit;

            if (Physics.Raycast(ray, out hit, 100f))

            {

                Debug.Log("Hitted,Position is:" + hit.point + ",Object name is:" + hit.collider.gameObject.name);

            }

            else

            {

                Debug.Log("No hitted");

            }

        }

    }

}

该段代码的功能是,在运行并用鼠标左键点击某处后如果发生了碰撞,控制台打印发生了碰撞,并打印碰撞的位置和碰撞的物体名称。

第三种方式

使用的API:Physics.Raycast(射线起点Vector3,射线方向Vector3,光线碰到的物体out hit(类型RaycastHit),射线长度float,遮罩过滤层LayerMask)

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    public LayerMask layerMask;

    void Start()

    {

        layerMask = LayerMask.GetMask("Boss");

    }

    void Update()

    {

 

        if (Input.GetMouseButtonDown(0))

        {

            RaycastHit hit;

            if (Physics.Raycast(transform.position, transform.forward, out hit, 100f, layerMask))

            {

                Destroy(hit.collider.gameObject);

            }

            else

            {

                Debug.Log("miss hitted target");

            }

        }

    }

}

创建两个物体,该两个物体的X,Y轴数值相同,将含上面代码的脚本挂到两个物体中Z轴数值小的物体上,在Inspector中将两个物体的Layer设置成“Boss”,在两个物体的中间加一个物体将两个物体隔开,将该物体的Layer设置成另一种,运行后点击鼠标左键,Z轴数值大的物体将被销毁。

2.检测多个物体

碰到的物体形成数组

用到的API:Physics.RaycastAll(射线,射线最大长度fioat,遮罩过滤层LayerMask)

也可以用:Physics.RaycastAll(射线起点Vector3,射线方向Vector3,射线长度float,遮罩过滤层LayerMask)

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    void Update()

    {

        if (Input.GetMouseButtonDown(0))

        {

            RaycastHit[] hit=Physics.RaycastAll(transform.position,transform.forward,100f);

            for(int i = 0; i < hit.Length; i++)

            {

                Debug.Log("Hitted "+hit.Length+" object");

                Debug.Log("No." + i + " name is " + hit[i].collider.gameObject.name);

            }

        }

    }

}

该段代码的功能是将探测的物体组成一个数组,并通过控制台访问数组的信息。

3.球形射线

使用的API:Physics.OverlapSphere(transform.position,3f);

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        Collider[] colliders = Physics.OverlapSphere(transform.position, 3f);

        for(int i = 0; i < colliders.Length; i++)

        {

            Debug.Log("Hitted " + colliders.Length + " objects");

            Debug.Log("No. " + i + " name is " + colliders[i].gameObject.name);

        }

    }

}

该段代码的功能是,检测一个球形内的碰撞体信息,并用控制台输出。

 

13.2D物理系统

13.1 2D的物理碰撞和触发器

13.1.1碰撞和触发的条件

碰撞的条件:两个物体都要带有碰撞器,其中一个需要有刚体。

触发的条件:碰撞的两个物体至少有一个勾选了Is Trigger选项。

13.1.2碰撞的生命周期

使用的脚本API:OnCollisionEnter2D

示例

using UnityEngine;

public class Player : MonoBehaviour

{

    private void OnCollisionEnter2D(Collision2D collision)

    {

        Debug.Log("I collided "+collision.gameObject.name);

    }

}

该段代码的功能是,在两个2D物体发生碰撞时,控制台打印进入碰撞和脚本所挂物体碰到的物体名称。

若想在碰撞结束时打印,可以将上述代码中的OnCollisionEnter2D改为OnCollisionExit2D。

若想在碰撞发生时打印,可以将上述代码中的OnCollisionEnter2D改为OnCollisionStay2D。

13.1.3触发的生命周期

使用的脚本API:OnTriggerEnter2D

示例

using UnityEngine;

public class Player : MonoBehaviour

{

    private void OnTriggerEnter2D(Collider2D collision)

    {

        Debug.Log("I trigged " + collision.gameObject.name);

    }

}

该段代码的功能是,在两个2D物体发生接触时,控制台打印进入接触和脚本所挂物体接触到的物体名称。

若想在接触结束时打印,可以将上述代码中的OnTriggerEnter2D改为OnTriggerExit2D。

若想在接触持续时打印,可以将上述代码中的OnTriggerEnter2D改为OnTriggerStay2D。

13.2 2D物理材质

讲了Project中新建的Physice Material 2D的使用。

13.3 2D效果器

讲了2D效果器组件,包括:

1.Area Effector 2D

2.Surface Effector 2D

3.Buoyancy Effector 2D

4.Point Effector 2D

13.4 2D物体中的其他碰撞器与恒力组件

讲了Capsule Collider 2D,Circle Collider 2D,Edge Collider 2D组件。

讲了Constant Force 2D组件。

13.5 脚本与2D刚体的交互

示例

using UnityEngine;

public class Player : MonoBehaviour

{

    Rigidbody2D r2;

    void Start()

    {

        r2 = transform.GetComponent<Rigidbody2D>();

    }

    void Update()

    {

        float x = Input.GetAxis("Horizontal");

        float y = Input.GetAxis("Vertical");

        if (x != 0 || y != 0)

        {

            r2.velocity = new Vector2(100 * x, 100 * y);

        }

    }

}

该段代码实现的功能是,通过WSAD来控制对象的上下左右移动。

 

14.动画系统

14.1动画的播放控制

14.1.1通过组件控制

导入模型后,在Project中新建一个Animator Controller,双击Animator Controller,将模型内部的动画文件拖入到Animator Controller的场景中,再将Animator Controller拖入到模型的Animator组件(如果没有该组件可以新创建一个)的Controller中,再点击运行模型即可动起来。

14.1.2通过脚本控制

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    Animator am;

    void Start()

    {

        am = transform.GetComponent<Animator>();

    }

    void Update()

    {

        if (Input.GetKeyDown(KeyCode.Alpha0))

        {

            am.SetInteger("id", 0);

        }

        else if (Input.GetKeyDown(KeyCode.Alpha1))

        {

            am.SetInteger("id", 1);

        }

        else if (Input.GetKeyDown(KeyCode.Alpha2))

        {

            am.SetInteger("id", 2);

        }

        else if (Input.GetKeyDown(KeyCode.Alpha3))

        {

            am.SetInteger("id", 3);

        }

        else if (Input.GetKeyDown(KeyCode.Alpha4))

        {

            am.SetInteger("id", 4);

        }

    }

}

在Prooject中创建一个Animator Controller,将动画拖进Animator Controller中,在Animator中设置通过Any State设置动画的播放,在Parameter中设置一个名叫id的变量,点击Animater中的箭头,在Inspector中设置动漫所对应的值,并将Inspector>Setting>Can Transition To Self取消勾选,通过该代码可以实现在运行时,通过按设置的值实现相应的动画效果。

14.2人形动画

人形动画的特点是可以使用其他的人形动画。

14.3动画遮罩

动画遮罩的功能是屏蔽游戏对象某一部位的运动。

14.4动画的分层和退出控制

动画的分层控制是在Animator中添加多个Layer,并对各个Layer进行编辑,来对物体的动作进行分类控制。

14.5动画事件

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    public void TestDebug()

    {

        Debug.Log("Test event");

    }

}

可以在Project的动画文件的Inspector>Animatian>Events中添加动画事件,通过将脚本中的函数名(本例为TestDebug)粘贴至中Inspector>Animatian>Events>Founction中,运行后在动画播放到设置的位置时会激活函数。

 

15.寻路系统

15.1实现简单导航寻路功能

示例

using UnityEngine;

using UnityEngine.AI;

public class Test : MonoBehaviour

{

    private NavMeshAgent agent;

    void Start()

    {

        agent = GetComponent<NavMeshAgent>();

    }

    void Update()

    {

        if (Input.GetMouseButtonDown(0))

        {

            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

            RaycastHit hit;

            bool iscollider = Physics.Raycast(ray, out hit);

            if (iscollider)

            {

                agent.SetDestination(hit.point);

            }

        }

    }

}

将地面物体的Inspector设置成Navigation Static.然后点击菜单Windows>AI>Navigation,将地面物体进行Bake.在待引导的物体上添加Nav Mesh Agent组件。将上述代码挂到待引导物体上,在运行时可以实现通过鼠标左键控制物体运动。

15.2导航面板参数介绍以及导航网格区域介绍

可以在Navigation>Areas中为不同区域添加不同的行走成本,再在Navigation>Object中设置道路成本类型,通过设置成本可以是物体智能的选择走哪条路。

15.3动态障碍物

将Nav Mesh Obstacle组件挂到一个阻碍物体上,并选中该组件中的Carve后,可以使待引导物体检测到阻碍物体而重新规划路线。

15.4分离导航连接线

在地面添加Off Mash Link组件,可以在该组件中设置两个点,设置好后待引导物体可以在这两个点之间移动。

15.5运动时动态烘培导航网格

需要用到Unity官方扩展的Navigation工具。

添加扩展工具后,可以添加NavMeshSurface组件,该组件生成导航网格不需要将地面物体设置成Navigation Static,并可以通过脚本动态生成物体并烘焙。

15.6其他组件功能介绍

Unity官方扩展的Navigation工具中的NavMashLink,该组件为OffMash Link的加强版,可以连接两个导航面。

 

16.音效系统

16.1音频源和音频监听器组件

音频播放可以选择在Hierachy中单独创建Audio Source物体,也可以选择在物体的Inspector中添加Audio Source组件来播放音频。

需要有Audio Listener组件方可听到播放的音频。

16.2音频源组件常用的函数

16.2.1常用功能

使用的API:

播放音频:AudioSours.Play();

暂停播放:AudioSours.Pause();

停止播放:AudioSours.Stop();

检测是否在播放:AudioSourse.isPlaying

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    AudioSource audio;

    void Start()

    {

        audio = transform.GetComponent<AudioSource>();

    }

    void Update()

    {

        if (Input.GetKeyDown("a"))

        {

            if (audio.isPlaying == false)

            {

                audio.Play();

            }

            else

            {

                Debug.Log("Audio is playing,no need to play again.");

            }

        }

        if (Input.GetKeyDown("b"))

        {

            audio.Pause();

        }

        if (Input.GetKeyDown("c"))

        {

            audio.Stop();

        }

    }

}

将该脚本挂入Audio Sourse物体后,可以实现按A键播放(如果已经在播放,则打印在播放),按B键暂停播放,按C键停止播放。

16.2.2指定音频剪辑

使用的API:AudioSource.clip

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    AudioSource audio;

    void Start()

    {

        audio = transform.GetComponent<AudioSource>();

        audio.clip = Resources.Load<AudioClip>("kuaidi1");

    }

    void Update()

    {

        if (Input.GetKeyDown("a"))

        {

            audio.Play();

        }

    }

}

该段代码的功能是,将Resources中的kuaidi1音频文件添加进组件,在游戏播放时按A键可以播放音频。

16.3音频过滤器和音频混响区

16.3.1音频过滤器

音频过滤器组件需要在有Audio Sources组件或Audio Listener组件的物体中才能添加。

16.3.2音频混响区

音频混响区组件Audio Reverb Zone,该组件可以设置在一定区域内的混响效果。

16.3.3音频管理器

打开方式:Edit>Project Setting>Audio.

 

11.3D模型管理

11.1蒙皮网格与普通网格对比

11.1.1对比

共同点:二者都可以通过关闭网格组件来隐藏物体

不同点:蒙皮网格适用于野怪等动画人物,普通网格适用于树等静态物,且普通网格有网格过滤器(Mesh filter),蒙皮网格没有。

11.1.2通过脚本控制网格组件的开关

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    public void Start()

    {

        transform.GetComponent<MeshRenderer>().enabled = false;

    }

}

在将脚本挂到对应的物体后,上述脚本实现的功能是在运行时将网格组件关闭使该物体不再显示,如果为动态物体,可以将上面的代码transform.GetComponent<MeshRenderer>().enabled= false;换成transform.GetComponent<SkinnedMeshRenderer>().enabled= false;

11.2材质的使用

新建或导入物体模型后,在Project中新建一个Material,将新建的Material导入到物体模型的Inspector>Mash Rander>Materials>Elements中,然后通过在新建的Marerial的Inspector中对材质进行Main Map>Albedo中导入图片,变换颜色等设置来改变物体材质。

11.2换肤功能的实现

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    public MeshRenderer cube;

    public Material material1;

    public Material material2;

    void Update()

    {

        if (Input.GetKeyDown("a"))

        {

            cube.material = material1;

        }

        if (Input.GetKeyDown("b"))

        {

            cube.material = material2;

        }

    }

}

将含上面代码的脚本挂到目标物体身上,并将目标物体拖入到脚本的MeshRenderer选项中,再将2套需要变换的材质分别拖入到脚本的material1和material2选项中,点击运行,按A键和按B键后可以实现皮肤的变换。

 

17.特效系统

17.1粒子系统

演示了一些粒子系统的效果。

创建粒子系统,Hierachy中点击右键Effect>Particle System.

17.2使用脚本和粒子系统交互

17.2.1基本交互

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    GameObject particleGO;

    ParticleSystem particle;

    void Start()

    {

        particleGO = GameObject.Instantiate(Resources.Load<GameObject>("22_RFX_Fire_Campfire1"));

        particleGO.transform.position = transform.position;

        particle = particleGO.GetComponent<ParticleSystem>();

        ParticleSystem.MainModule mainModule = particle.main;

        mainModule.loop = true;

    }

    void Update()

    {

        if (Input.GetKeyDown(KeyCode.A))

        {

            particle.Play();

        }

        if (Input.GetKeyDown(KeyCode.B))

        {

            particle.Stop();

        }

        if (Input.GetKeyDown(KeyCode.C))

        {

            particle.Pause();

        }

        if (Input.GetKeyDown(KeyCode.D))

        {

            Destroy(particleGO);

        }

    }

}

新建一个空物体,将含上面代码的脚本挂在空物体上,将名为22_RFX_Fire_Campfire的粒子特效预制体放入Projece/Resources文件夹中,可以实现在运行时将粒子特效预制体22_RFX_Fire_Campfire克隆并在点击A键时播放,B键时停止,C键时暂停,D键时销毁。

17.2.2碰撞回调

使用的API:OnParticleCollision(GameObject go)

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    private void OnParticleCollision(GameObject go)

    {

        Debug.Log("Particle had collision,collide to:" + go.name);

    }

}

将该段代码挂到粒子系统物体的主子物体上,并将该主物体Inspector>Particle System>Collision勾选上,把Collision>Type设置成World,Collision>Mode设置成3D,Collision>Send Collision Messages勾选上,在粒子上方放一物体,运行时控制台会打印粒子发生了碰撞和碰撞到的物体名称。

17.3粒子触发回调

示例

using System.Collections.Generic;

using UnityEngine;

public class Test : MonoBehaviour

{

    ParticleSystem particle;

    void Start()

    {

        particle = transform.GetComponent<ParticleSystem>();

    }

    private void OnParticleTrigger()

    {

        List<ParticleSystem.Particle> particles = new List<ParticleSystem.Particle>();

        int numEnter = particle.GetTriggerParticles(ParticleSystemTriggerEventType.Enter, particles);

        for (int i = 0; i < numEnter; i++)

        {

            ParticleSystem.Particle pt = particles[i];

            pt.startColor = Color.red;

            particles[i] = pt;

        }

        particle.SetTriggerParticles(ParticleSystemTriggerEventType.Enter, particles);

    }

}

在粒子系统上方放一个物体,将该物体拖入粒子系统的Inspector>Particle System>Triggers>Colliders中,将Inspector>Particle System>Triggers>Enter设置成Callback,将含上面代码的脚本挂载到粒子系统物体上,运行时可以使粒子进入物体后变成红色。

17.4特效系统之拖尾

使用的API:TrailRenderer

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    GameObject go;

    void Start()

    {

        go = GameObject.Instantiate(Resources.Load<GameObject>("Accelerate"));

        go.transform.SetParent(transform);

        go.transform.localPosition = new Vector3(0, 0.5f, 0);

    }

    void Update()

    {

        if (Input.GetKeyDown("a"))

        {

            go.GetComponent<TrailRenderer>().emitting = true;

        }

        if (Input.GetKeyDown("b"))

        {

            Destroy(go);

        }

    }

}

新建一个物体,将含上面代码的脚本挂载到该物体上,准备一个拖尾的预制体Accelerate放入Resources文件夹中,在运行时按下A键可以激活克隆的Accelerate,使拖动时表现出效果,按下B键时销毁克隆的Accelerate。

17.5特效系统之粒子力场

讲了Hierachy中点击右键Effect>Particle System Force Field的相关知识点。

 

18.视频播放管理

18.1视频播放方法

在场景中新建RawImage,在RawImage中添加Video Player组件,在Assets中新建Render Texture,将Render Texture和视频资源分别放入Raw Image和Video Player组件中,点击即可播放。

18.2视频组件常用的函数

18.2.1视频播放常用操作

示例

using UnityEngine;

using UnityEngine.Video;

public class Test : MonoBehaviour

{

    VideoPlayer video;

    void Start()

    {

        video = transform.GetComponent<VideoPlayer>();

    }

    void Update()

    {

        if (Input.GetKeyDown("a"))

        {

            if (video.isPlaying == false)

            {

                video.Play();

            }

            else

            {

                Debug.Log("Video is playing,no need to play again");

            }

        }

        if (Input.GetKeyDown("b"))

        {

            video.Pause();

        }

        if (Input.GetKeyDown("c"))

        {

            video.Stop();

        }

    }

}

将该段代码挂到有Video Player组件的物体中,在运行时可以通过按键实现播放,暂停,停止等

18.2.2视频播放组件设置

示例

using UnityEngine;

using UnityEngine.Video;

public class Test : MonoBehaviour

{

    VideoPlayer video;

    void Start()

    {

        video = transform.GetComponent<VideoPlayer>();

        video.source = VideoSource.VideoClip;

        video.clip = Resources.Load<VideoClip>("GameExplain");

    }

}

将视频剪辑文件GameExplain放入Resources文件夹,将组件Video Player>Source设置成URL,通过该段代码可以实现在运行时Video Player>Source切换至Video Clip模式,并播放素材名为GameExplain的视频。

 

19.DoTween补间动画插件

19.1空间物体位置旋转大小等动画

19.1.1位置

使用的API:DOMove(位置,时间)

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        transform.DOMove(new Vector3(10, 10, 10), 2f);

    }

}

当前代码的功能是将脚本所挂物体用2秒移动到世界坐标系(10,10,10)位置。

如果想以本地坐标系作为参考,可以将上面代码中的transform.DOMove(new Vector3(10,10,10), 2f);换成transform.DOLocalMove(new Vector3(10,10,10), 2f);

如果想将物体沿X轴移动,可以将上面代码中的transform.DOMove(new Vector3(10,10,10), 2f);换成transform.DOLocalMoveX(10, 2f);

如果想让物体匀速运动,需要将transform.DOMove(new Vector3(10, 10, 10), 2f);改为transform.DOMove(new Vector3(10, 10, 10), 2f).SetEase(Ease.Linear);

19.1.2旋转

使用的API:DORotate(角度,时间)

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        transform.DORotate(new Vector3(0, 20, 0), 2f);

    }

}

当前代码的功能是将脚本所挂物体用2秒沿世界坐标系的Y轴顺时针转20度。

如果想以本地坐标系为参考旋转,可以将上面代码中的transform.DORotate(new Vector3(0, 20, 0), 2f);改为transform.DOLocalRotate(new Vector3(0, 20, 0), 2f);

19.1.3缩放

使用的API:DOScale(缩放倍数,时间)

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        transform.DOScale(new Vector3(6, 6, 6), 2f);

    }

}

该段代码的功能是,将脚本所挂物体的X,Y,Z轴三个方向都缩放至6倍.

如果只想让X轴方向缩放至6,可以将上面代码中的transform.DOScale(new Vector3(6, 6, 6), 2f);换成transform.DOScaleX (6, 2f);

19.1.4跳跃

使用的API:DOJump(跳跃目的地位置,跳跃高度,步数,时间)

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        transform.DOJump(new Vector3(60, 0, 0), 1,5,6);

    }

}

该段代码的功能是,使脚本所挂物体在6秒内以Y轴方向1高度分5步跳到指定位置。

如果想以当地坐标系为参考,可以将上面代码中的transform.DOJump(new Vector3(60,0,0),1,5,6);换成transform.DOLocalJump(new Vector3(60,0,0),1,5,6);

19.1.5弹簧冲击

使用的API:DOPunchPosition(位置, 时间, 频率, 对侧弹性);

DOPunchRotation(new Vector3(角度,时间, 频率, 对侧弹性);

transform.DOPunchScale(缩放倍数, 时间, 频率, 对侧弹性);

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        transform.DOPunchPosition(new Vector3(10, 0, 0), 3,10,1);

    }

}

该段代码实现的功能是,使脚本所挂物体用3秒,每秒10次,以最大的弹性的来回弹跳。

如果想实现物体的角度弹簧冲击,可以将上面代码中的transform.DOPunchPosition(new Vector3(10, 0, 0), 3, 10, 1);换成transform.DOPunchRotation(new Vector3(10, 0, 0), 3, 10, 1);

如果想实现物体缩放的弹簧冲击,可以将上面代码中的transform.DOPunchPosition(new Vector3(10, 0, 0), 3, 10, 1);换成transform.DOPunchScale(new Vector3(10, 0, 0), 3, 10, 1);

19.1.6旋转

使用的API:.DOLookAt(旋转的方向,时间);

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        transform.DOLookAt(new Vector3(1,1,1), 2f);

    }

}

该段代码实现的功能是用2秒沿着指定方向自旋转。

19.1.7增量

使用的API:DOBlendableMoveBy(位置增量, 时间);

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        transform.DOBlendableMoveBy(new Vector3(20,0,0), 2f);

    }

}

该段代码的功能是,是脚本所挂物体用2秒在X轴方向的坐标增加20。

如果想实现旋转角度的增量,可以将上面代码transform.DOBlendableMoveBy(new Vector3(20, 0, 0), 2f);换成transform.DOBlendableRotateBy(new Vector3(20, 0, 0), 2f);

如果想实现缩放的增量,可以将上面代码transform.DOBlendableMoveBy(new Vector3(20, 0, 0), 2f);换成transform.DOBlendableScaleBy(new Vector3(20, 0, 0), 2f);

19.2颜色、透明度的控制

19.2.1颜色

使用的API:DOColor(颜色,时间);

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        Material material = GetComponent<MeshRenderer>().material;

        material.DOColor(Color.red, 2f);

    }

}

该段代码的功能是用两2秒将脚本所挂物体变成红色。

该方法也可用于文本和图片颜色的更改。

19.2.2透明度

使用的API:DOFade(透明度,,时间);

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        Material material = GetComponent<MeshRenderer>().material;

        material.DOFade(0, 2f);

    }

}

将脚本所挂物体的Inspector>Shader修改成Lagacy Shader>TransParent>Diffuse,通过上面的代码可以用2秒将脚本所挂物体隐形。

19.2.3颜色渐变

使用的API:

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    public Gradient gradient;

    void Start()

    {

        Material material = GetComponent<MeshRenderer>().material;

        material.DOGradientColor(gradient, 2f);

    }

}

定义了公开变量gradient后,在Unity中Inspector中找到gradient并设置该渐变色,设置完成后运行,该段代码功能是使脚本所挂物体的颜色用2秒渐变。

19.3震动效果表现

19.3.1物体震动

使用的API:DOShakePosition(时间, 振幅,频率,混乱程度);

transform.DOShakeRotation(时间, 角幅度,频率,混乱程度);

transform.DOShakeScale(时间, 大小幅度,频率,混乱程度);

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        transform.DOShakePosition(2f, 1, 10, 90);

    }

}

该段代码实现的功能是,使脚本所挂物体用2秒以1振幅,10振幅,90混乱度的状态震动。

如果想换成方向震动,可以将上述代码中的transform.DOShakePosition(2f, 1, 10, 90);换成transform.DOShakeRotation(2f, 90, 10, 90);

如果想换成大小震动,可以将上述代码中的transform.DOShakePosition(2f, 1, 10, 90);换成transform.DOShakeScale(2f,2, 10, 90);

19.3.2摄像机震动

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        transform.DOShakePosition(2f, 1, 10, 90);

    }

}

定义了摄像机后,将指定摄像机拖入该变量中,通过该段代码可以实现摄像机的震动。

参考上一小节,同理可实现摄像机的角震动。

19.4物体路径动画

使用的API:DOPath(路径,时间,路径类型,路径模式,分辨率,颜色);

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        Vector3[] path = new Vector3[] { new Vector3(1, 2, 1), new Vector3(2, 1, 3), new Vector3(10, 2, 5), new Vector3(4, 9, 6) };

        transform.DOPath(path, 5,PathType.Linear,PathMode.Full3D,10,Color.red);

    }

}

该段代码的功能是,使脚本所挂物体以设置的模式沿路径运动

除了用脚本控制物体运动外,还可以通过Dotween Path组件来控制物体的运动。

19.5动画序列Sequence

19.5.1动画序列

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        Sequence sequence = DOTween.Sequence();

        sequence.Append(transform.DOMoveX(10,1));

        sequence.Insert(0,transform.DOScale(2,1));

        sequence.AppendInterval(2);

        sequence.Append(transform.DOMoveX(0,1));

        sequence.Insert(3,transform.DOScale(1,1));

    }

}

该段代码实现的功能是,用1秒钟使被挂脚本的物体在X轴移动到10的位置,同时大小变为原来的2倍,停顿两秒后,物体X轴的位置变为0,同时大小变回原来的大小。

上面代码中Insert方法也可以用Join方法来实现同样的功能,只需将代码sequence.Insert(0, transform.DOScale(2, 1));换成sequence.Join(transform.DOScale(2, 1));并将sequence.Insert(3,transform.DOScale(1, 1));换成sequence.Join(transform.DOScale(1, 1));即可。

19.5.2方法回调

Append回调:

示例

using DG.Tweening;

using UnityEngine;

 

public class Test : MonoBehaviour

{

    void Start()

    {

        Sequence sequence = DOTween.Sequence();

        sequence.Append(transform.DOMoveX(10,1));

        sequence.Join(transform.DOScale(2,1));

        sequence.AppendCallback(() =>

        {

            Debug.Log("AppendCallback1");

        });

        sequence.Append(transform.DOMoveX(0,1));

        sequence.Join(transform.DOScale(1,1));

        sequence.AppendCallback(() =>

        {

            Debug.Log("AppendCallback2");

        });

    }

}

AppendCallback会在上面的代码执行完后调用。

Insert回调:

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        Sequence sequence = DOTween.Sequence();

        sequence.Append(transform.DOMoveX(10,1));

        sequence.Insert(0,transform.DOScale(2,1));

        sequence.AppendInterval(2);

        sequence.Append(transform.DOMoveX(0,1));

        sequence.Insert(3,transform.DOScale(1,1));

        sequence.InsertCallback(6,() =>

        {

            Debug.Log("InsertCallback2");

        });

    }

}

该段代码会在运行6秒后打印InsertCallback,即InsertCallback的执行时间点只与填写的时间点有关。

19.6动画常用设置以及动画控制

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    Tweener tweener;

    void Start()

    {

        tweener=transform.DOMoveX(10,1).SetEase(Ease.Linear).SetLoops(-1,LoopType.Restart).SetDelay(0).SetAutoKill(true);

    }

    private void onGUI()

    {

        if (GUILayout.Button("暂停"))

        {

            tweener.Pause();

        }

        if (GUILayout.Button("Kill"))

        {

            tweener.Kill();

        }

        if (GUILayout.Button("播放"))

        {

            tweener.Play();

        }

        if (GUILayout.Button("倒回播放"))

        {

            tweener.PlayBackwards();

        }

        if (GUILayout.Button("向前播放"))

        {

            tweener.PlayForward();

        }

        if (GUILayout.Button("重新播放"))

        {

            tweener.Restart();

        }

        if (GUILayout.Button("回到初始位置"))

        {

            tweener.Rewind();

        }

        if (GUILayout.Button("跳转到"))

        {

            tweener.Goto(2);

        }

        if (GUILayout.Button("点击暂停"))

        {

            tweener.TogglePause();

        }

    }

}

该段代码的功能是,设置一段动画,并通过不同的按键来控制动画。(运行问题:游戏页面无法形成控制按钮)

21.各平台打包操作

21.1Windows平台

讲解了Windows平台的打包操作

21.2安卓平台

安卓平台的打包需要先在Hub中安装Android SDK & NDK Tools和Open JDK两个组件。

21.3IOS平台

讲解了IOS平台的打包操作

 

19.7动画的回调

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    Tweener tweener;

    void Start()

    {

        tweener=transform.DOMoveX(10,1).SetEase(Ease.Linear).SetLoops(-1,LoopType.Restart).SetDelay(0).SetAutoKill(true);

        tweener.OnComplete(() =>

        {

            Debug.Log("OnComplete");

        });

        tweener.OnKill(() =>

        {

            Debug.Log("OnKill");

        });

        tweener.OnPlay(() =>

        {

            Debug.Log("OnPlay");

        });

        tweener.OnStart(() =>

        {

            Debug.Log("OnStart");

        });

        tweener.OnRewind(() =>

        {

            Debug.Log("OnRewind");

        });

        tweener.OnUpdate(() =>

        {

            Debug.Log("OnUpdate");

        });

        tweener.OnPause(() =>

        {

            Debug.Log("OnPause");

        });

    }

}

该段代码的功能是根据动画运行时的不同状态打印相应的提示。

 

20.EasyTouch手势插件

20.1手势监测之初级使用

示例

using HedgehogTeam.EasyTouch;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Update()

    {

        Gesture gesture = EasyTouch.current;

        if (gesture != null)

        {

            if (EasyTouch.EvtType.On_TouchStart == gesture.type)

            {

                OnTouchStart(gesture);

            }

            else if (EasyTouch.EvtType.On_Drag == gesture.type)

            {

                OnDragStart(gesture);

            }

        }

    }

    private void OnTouchStart(Gesture gesture)

    {

        Debug.Log(gesture.type);

    }

    private void OnDragStart(Gesture gesture)

    {

        Debug.Log(gesture.type);

    }

}

上述代码的功能是,当运行时鼠标点击或者拖拽被挂脚本物体,控制台打印相关信息。

20.2手势监测之使用QuickGesture以及Trigger

20.2.1QuickGesture类组件

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    public void Log(string str)

    {

        Debug.Log(str);

    }

}

新建一个空物体,讲脚本挂入空物体中,然后将空物体挂入待操作物体的Quick Drag,Quick Tap,Quick Touch,Quick Pinch等组件中,设置相关输出内容,在运行时进行对物体进行操作后,会输出相关内容。

20.2.2Trigger组件

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    public void Log(int str)

    {

        Debug.Log(str);

    }

}

将含该代码的脚本挂入待操作物体上,并在待操作物体上加入Trigger组件,选择Add new event>On_Touch Start,将Mothed name改成Log,将Parameter to send改为Touch_Count,在运行时将对物体的操作信息通过控制台打印。

20.3组件核心参数

讲解了Easy Touch组件

 

20.4JoyStick虚拟摇杆

讲解了ETCJoystick组件

 

22.各平台调试技术

22.1常见的异常

22.1.1空指针导致的异常

空指针异常可以分为未指定引用对象(包括未指定和未分配对象),和指定的路径错误(包括查找物体和查找资源)两类。

22.1.2数据结构错误

包括重复添加相同的Key和索引出现异常。

22.2编辑器模式下的日志功能

日志的三种类型:

普通日志:Debug.Log("普通日志");

警告日志:Debug.LogWarning("警告日志");

错误日志:Debug.LogError("错误日志");

22.3安卓平台下的日志跟踪

分为Unity本身的调试和AndroidStudio调试。

22.4IOS调试日志查看

讲解了IOS平台下的日志查看。

22.5断点调试和调用堆栈

22.5.1断点调试

在一些代码前面加入断点,点击附加到Unity,在Unity中点击播放,返回Visual Studio中查看相关代码的值。

22.5.2调用堆栈

在Visual Studio中操作

 

23.其他知识

23.1生成随机数

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        for(int i = 0; i < 10; i++)

        {

            Debug.Log(Random.Range(0,8));

        }

    }

}

该段代码的功能是在运行时控制台随机打印10个0~7之间的随机数。

 

23.2协程方法

示例1

using System.Collections;

using UnityEngine;

 

public class Test : MonoBehaviour

{

    private void Start()

    {

        StartCoroutine(MyCoroutine(2, "success"));

    }

    IEnumerator MyCoroutine(int i, string str)

    {

        Debug.Log(i);

        yield return new WaitForSeconds(5f);

        Debug.Log(str);      // 打印i的5s后执行

        yield return new WaitForSeconds(5f);

        Debug.Log("123");    // 打印str的5s后执行

    }

}

该段代码的功能是间隔一定时间打印内容。

示例2

using System.Collections;

using UnityEngine;

 

public class Test : MonoBehaviour

{

    private void Start()

    {

        StartCoroutine(MyCoroutine(2));

    }

    IEnumerator MyCoroutine(int i)

    {

        while (true)

        {

            yield return new WaitForSeconds(1);

            Debug.Log(i);

        }

    }

}

该段代码的作用是每过1秒打印一次数字2.

 

23.3调用方法

示例1

using UnityEngine;

 

public class Test : MonoBehaviour

{

    private void Start()

    {

        Invoke("Bigger",2);

    }

    void Bigger()

    {

        transform.localScale = new Vector3(2, 2, 2);

    }

}

该代码的作用是使脚本所挂物体在2秒后变为原来的2倍。

示例2

using UnityEngine;

 

public class Test : MonoBehaviour

{

    private void Start()

    {

        InvokeRepeating("Bigger",2,1);

    }

    void Bigger()

    {

        transform.localScale += new Vector3(1, 1, 1);

    }

}

该代码的作用是使脚本所挂物体2秒后增大1倍,然后每1秒增大1倍。

示例3

using UnityEngine;

 

public class Test : MonoBehaviour

{

    private void Start()

    {

        InvokeRepeating("Fuse", 0.01f,0.01f);

    }

    private void Fuse()

    {

        transform.Translate(new Vector3(0.02f, 0.02f, 0.02f));

    }

    private void Update()

    {

        if (Input.GetMouseButtonDown(0))

        {

            CancelInvoke();

        }

    }

}

该段代码的功能是,使物体持续朝一个方向运动,在按下鼠标左键后停止运动。

 

23.3触发器

示例

using UnityEngine;

public class zidan : MonoBehaviour

{

    void OntriggerEnter(Collider coll)

    {

        if (coll.name == "Cube")

        {

            //transform.position  生成一个特效到这个位置上

            Destroy(transform.gameObject);

        }

        else if (coll.name == "xiaonuhai")

        {

            //transform.position  生成一个别的特效到这个位置上

            Destroy(transform.gameObject);//打中小女孩后,销毁子弹

            Destroy(coll.gameObject);//打中小女孩后,销毁小女孩

        }

    }

}

23.5按键控制程序退出

示例

using UnityEngine;

using UnityEngine.UI;

 

public class Exit : MonoBehaviour

{

    void Start()

    {

        transform.GetComponent<Button>().onClick.AddListener(() => { DoExit(); });

    }

    void DoExit()

    {

        UnityEditor.EditorApplication.isPlaying= false;

        Application.Quit();

    }

}

上述代码的功能是,当按键被按下时,退出游戏。

23.6Text中显示时间

示例

using System;

using UnityEngine;

using UnityEngine.UI;

 

public class ShowTime : MonoBehaviour

{

    public Text time1;

    void Update()

    {

        DateTime nowTime=DateTime.Now.ToLocalTime();

        time1.text = nowTime.ToString("yyyy-MM-dd HH:mm:ss");

    }

}

上述代码可以实现在Text中显示实时时间。

23.7Text字体隐形显现转换

示例

using DG.Tweening;

using UnityEngine;

using UnityEngine.UI;

 

public class FlashWord : MonoBehaviour

{

    private void Start()

    {

        Pingpong(1, 0, 0.6f);

    }

    void Pingpong(float fromValue, float toValue, float duration)

    {

        Color temColor = gameObject.GetComponent<Text>().color;

        temColor.a = fromValue;

        Tweener tweener = DOTween.ToAlpha(() => temColor, x => temColor = x, toValue, duration);

        tweener.onUpdate = () => { gameObject.GetComponent<Text>().color = temColor; };

        tweener.onComplete = () =>

        {

            Pingpong(toValue, fromValue, duration);

        };

    }

}

上述代码可以实现将字体的显隐变换效果,将<Text>改为<Image>可以实现图片的显隐效果。

23.8关闭程序

示例

using UnityEngine;

using UnityEngine.UI;

 

public class Exit : MonoBehaviour

{

    void Start()

    {

        transform.GetComponent<Button>().onClick.AddListener(() => { DoExit(); });

    }

    void DoExit()

    {

       // UnityEditor.EditorApplication.isPlaying= false;

        Application.Quit();

    }

}

上述代码可以实现点击按键关闭程序。“//”后的代码加上后可以实现在编辑器模式下的关闭效果,但加上后无法打包成安卓应用。

23.9实现UI圆点跟随运动

示例

using System.Collections;

using DG.Tweening;

using UnityEngine;

 

public class AfterScanDotsMove : MonoBehaviour

{

    public Transform[] Dots;

    Vector3[] tempvec3;

    void Start()

    {

        tempvec3 = new Vector3[Dots.Length];

        StartCoroutine(DotsMove());

    }

    IEnumerator DotsMove()

    {

        while (true)

        {

            for (int i = 0; i < Dots.Length; i++)

            {

                tempvec3[i] = Dots[i].position;

            }

 

            for (int i = 0; i < Dots.Length; i++)

            {

                if (i < Dots.Length - 1)

                {

                    Dots[i].transform.DOMove(tempvec3[i + 1], 0.5f).SetEase(Ease.Linear);

                }

                else

                {

                    Dots[i].transform.DOMove(tempvec3[0], 0.5f).SetEase(Ease.Linear);

                }

            }

            yield return new WaitForSeconds(0.5f);

        }

    }

}

该代码可以实现小圆点的跟随运动。

23.10全局变量

//该脚本不用挂载,内数据不会随场景变化而变化

public class storeData

{

    public static int countData = 0;

}

//其他脚本可以使用这个数据

if (storeData.countData ==0)  

23.11单例(一个脚本调另一个脚本里的变量或方法)

示例

//待调用的代码

using UnityEngine;

 

public class Juse : MonoBehaviour

{

public static Juse m_Instance;

    void Start()

    {

        m_Instance = this;

}

public void OpenPage()

{

//待调用的方法

}

}

//调用的代码

using UnityEngine;

 

public class TimeShow : MonoBehaviour

{

    void Start()

    {

        Juse.m_Instance.OpenPage();

    }

}

23.12SendMessenger方法调用

示例

//待调用的脚本代码

using UnityEngine;

 

public class TakeMess : MonoBehaviour

{

    public void DebugWord(string str)

    {

        Debug.Log(str);

    }

}

//调用的脚本代码

using UnityEngine;

 

public class SendMess : MonoBehaviour

{

    void Start()

    {

        GameObject.Find("Cube").SendMessage("DebugWord", "juse");

    }

}

该代码可以调用Cube物体上的DebugWord方法,并传递相关参数。

若想调用自身及子物体上的方法,可以用BroadcastMessage( );

若想调用自身及父物体上的方法,可以用SendMessageUpwards( );

23.13List使用

List也叫列表,

23.14Dictionary使用

Dictionary也叫字典。

 

23.15Event Trigger组件

通过Event Trigger组件来控制鼠标的事件

 

23.16UI小窗口显示

再UI界面建一个Row Image,Hierarchy上新建一个摄像机,Project上新建一个Render Texture,将Render Texture分别挂在摄像机和Row Image上,就可以在Row Image上显示摄像机摄的东西。

 

23.17AssetBundle

1.打包

将要打包的资源在inspector中的预览窗口下设置要打包在AssetBundles下的路径和后缀名(可任意取)。新建一个C#脚本,脚本内容如下:

using System.IO;

using UnityEditor;

 

public class CreateAssetBundles 

{

    [MenuItem("Assets/Build AssetBundles")]//生成菜单目录

    static void BuildAllAssetBundles()

    {

        string assetBundleDirectory = "Assets/AssetBundles";//指定AssetBundles文件夹的目录

        if (!Directory.Exists(assetBundleDirectory))

        {

            Directory.CreateDirectory(assetBundleDirectory);//如果没有,则创建文件夹

        }

        BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.None,BuildTarget.StandaloneWindows);

    }

}

脚本无需挂载,在菜单Assets下点击新创建的Build AssetBundles,即可在指定文件夹创建AssetBundle.

2.读取

场景中物体上挂载一个脚本,脚本代码如下:

using UnityEngine;

 

public class LoadAssetBundle : MonoBehaviour

{

    void Start()

    {

        AssetBundle bundle = AssetBundle.LoadFromFile("Assets/AssetBundles/this/wall.ab");//找到AB包

        GameObject cubeWall = bundle.LoadAsset<GameObject>("CubeWall");//找到AB包中的物体

        Instantiate(cubeWall);//实例化物体

    }

}

Unity

 

 

1.基本介绍

1.1Unity的安装与汉化_引擎安装与基础操作

安装时先安装Unity Hub,再安装Unity.

汉化在Unity Hub的Installs中找到对应版本的Unity,左上角的设置按钮,在跳出的窗口选择中文包,下载安装好后进入Unity,在Edit>Preferences>Languages>Editor Languages中选择中文版本。

1.2Unity窗口界面介绍与布局

2.2.1Scene界面

1.鼠标右键旋转视角

2.按住鼠标滚轮移动视角

3.旋转鼠标滚轮调整远近视角

4.按住右键并按WASD可以在场景中进行漫游

5.Pivot和Center

Pivot表示轴心,在该状态下,点击父物体时坐标会落在父物体上,旋转时也是子物体围绕父物体旋转。

Center表示中心,在该状态下,点击父物体时坐标会落在父物体与其所有的子类物体(包括孙物体和后面的物体)的中心点,旋转时也会围绕该中心点旋转。

6.Global和Local

Global表示全局,在该状态下,旋转后物体的坐标方向会与原始的坐标方向一致。

Local表示局部,在该状态下,旋转后物体的坐标会保持旋转后的方向。

2.2.2Project界面

选择文件并右键点击Show in explorer可以打开所在文件夹

1.3Unity菜单

Fils,Edit,Assets,...等菜单的功能。

 

2.游戏流程控制与脚本基础

2.1脚本生命周期

2.1.1方法名

示例

using UnityEngine;

public class Test : MonoBehaviour

{

/*游戏开始时调用,在脚本组件未勾选的情况下也可运行。*/

    void Awake()

    {

        Debug.Log("Awake");

    }

/*当物体被启用时调用*/

    void OnEnable()

    {

        Debug.Log("Enable");

    }

/*没有Reset方法的情况下,会在执行OnEnable方法后执行*/

    void Start()

    {

        Debug.Log("Start");

    }

/*每帧调用一次,一般用于非物理运动,例如游戏的逻辑。*/

    int updateCount = 0;

    void Update()

    {

        Debug.Log("Update第" + UpdateCount++ + "次打印");

    }

/*以相同的时间间隔调用,用在力学更新效果中。*/

    int fixedUpdateCount = 0;

    void FixedUpdate()

    {

        Debug.Log("FixedUpdate第" + FixedUpdateCount++ + "次打印");

    }

/*在Update和FixedUpdate调用后调用。*/

    int lateUpdateCount = 0;

    void LateUpdate()

    {

        Debug.Log("LateUpdate第" + LateUpdateCount++ + "次打印");

    }

/*当物体被禁用时调用*/

    void OnDisable()

    {

        Debug.Log("OnDisable");

    }

/*当物体销毁后执行*/

    void OnDestroy()

    {

        Debug.Log("Ondestroy");

    }

}

该段代码的功能是,通过控制台打印观察方法的执行顺序

2.1.2检测调用间隔时间

使用的API:Time.deltaTime;

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    void Update()

    {

        Debug.Log("Update"+Time.deltaTime);

    }

}

该脚本实现的功能是每帧输出一次文字Update和每帧的间隔时间。

2.2变量的创建与使用

2.2.1变量的创建

变量在类下面直接创建,默认为私有,如为私有可省略Private.

2.2.1变量的操作

1.隐藏Publicb变量

在变量上方用 [HideInInspector]

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    [HideInInspector]   //序列化  隐藏

    public int num;

}

2.显示private变量

在变量上方用[SerializeField]

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    [SerializeField]    //序列化  显示

    private int num;

}

3.设置变量范围

在变量上方用[Range(a,b)]

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    [Range(1, 100)]

    public int num;

}

 

3.游戏素材与脚本

3.1游戏素材

游戏素材包括字体,图片,音频,视频,模型,场景,粒子特效等。

素材的添加可以通过在Project中点击右键选择Import New Assets或Import Package实现,也可以通过文件夹拖入的方式实现。

3.2游戏脚本

游戏脚本可以通过在Project中点击右键Create>C# Script创建。

游戏脚本需要挂载到物体上方能实现其功能。

游戏脚本命名不能加空格,否则无法挂载。

 

4.游戏物体

4.2物体的标签和层级

标签可以方便查找物体。

层级可以运用在一些操作上,比如Camera中Inspector中的Culling Mask上,可以通过勾选掉一些层级来屏蔽显示一些物体

4.3摄像机

组件Camera>Projection下的persepective表示透视,透视模式下可以通过Field in view调镜头的角度;另一个Orthography表示正交即在播放时场景没有透视效果。

组件Camera>Clipping Planes为视距设置选项,在视距范围之外(高于最远视距,低于最近视距)的物体无法被摄像机看到。

4.4预制件

4.4.1克隆预制件

使用的API:GameObject.Instantiate(变量名);

示例:

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        GameObject go = Resources.Load<GameObject>("Cubes/Cube");

        GameObject.Instantiate(go);

    }

}

在Project中新建Resources文件夹,在Resources文件夹下新建Cubes文件夹,将Hierachy中做好的物体Cube拖入Cubes文件夹中,制成预制件。该段代码实现的功能是:在运行时将Resources/Cubes文件夹中的Cube预制件克隆一份并显示。

4.4.2修改预制件

预制件的修改的两种方式;

第一种:在Project中双击预制件,或者在Hietachy中点击其中一个预制件的最后的“>”标志,进入预制件修改视图,在修改视图中进行预制件的修改。

第二种:在Hierachy中选择一个预制件,直接进行修改,修改后再单击Hierachy中的预制件,在Inspector中找到Override按钮,点击按钮并选择Apply All即可完成对预制体的修改。预制件的Inspector中的组件参数修改后会留下标记,在标记行点击鼠标右键会出现Apply to prefab”/*预制件名称*/”的提示框,点击即将修改应用至预制件。

4.5通过脚本操作物体

4.5.1查找物体

1.按照路径查找物体

使用的API:GameObject.Find(物体的Hietachy路径);

示例:

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        GameObject go = GameObject.Find("Cube/Sphere");

        go.SetActive(false);

    }

}

在Hierachy中新建一个物体Cube,在Cube下新建一个子物体Sphere,将含上面代码的脚本挂载到某一物体上,可以实现在运行时隐藏物体Sphere,若一个文件夹下有同名的多个物体,则查找到的物体为创建时间最短的物体。

2.按照标签查找

使用的API:GameObject.FindGameObjectWithTag("标签名");

示例:

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        GameObject go = GameObject.FindGameObjectWithTag("Player");

        go.SetActive(false);

    }

}

该段代码的功能是找到最后将标签设置成Player的物体,并在运行时隐藏该物体。

4.5.2修改物体名称

使用的API:物体名.name=”修改后物体名称”;

示例:

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        GameObject go = GameObject.Find("Cube/Sphere");

        go.name = "CuteSphere";

    }

}

该段代码功能是找到物体Sphere,并在运行时将该物体名称改为CuteSphere。

4.5.3修改物体位置

使用的API:变量名.transform.position=/*更改后的位置*/

示例:

using UnityEngine;

 

public class Temp : MonoBehaviour

{

    public GameObject cube;

    void Start()

    {

        cube.transform.position = new Vector3(2, 1, 3);

    }

}

该段代码功能是,将物体的位置移动到世界坐标(2,1,3)的位置。

如果是想让物体移动到相对坐标(2, 1, 3)的位置,可将代码cube.transform.position = new Vector3(2, 1, 3);写成cube.transform.localposition = new Vector3(2, 1, 3);

如果想让找到的物体在运行时旋转一定角度,可以将上面示例中的代码cube.transform.position = new Vector3(2, 1, 3);写成go.transform.Rotation= Quaternion.Euler(new Vector3(a, b, c))或cube.transform.eulerAngles = new Vector(a,b,c))/*a,b,c表示旋转角度*/;

如果想让找到的物体在运行时放大或缩小,可以将上面示例中的代码cube.transform.position = new Vector3(2, 1, 3);写成cube.transform.localScale = new Vector3(a,b,c))/*a,b,c表示放大倍数*/;

4.5.4删除物体

使用的API:Destroy( );

示例:

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        GameObject go = GameObject.Find("Cube/Sphere");

        Destroy(go);

    }

}

该段代码功能是找到物体Sphere,并在运行时删除该物体。

如果想实现在运行后5秒消除,可以将代码Destroy(go);修改为Destroy(go,5);。

如果想让物体在切换场景的时候不销毁,可以将Destroy(go);修改为DontDestroyOnLoad(go);。

4.5.5克隆物体

示例:

using UnityEngine;

public class Test : MonoBehaviour

{

    public GameObject Cube;

    void Start()

    {

        GameObject.Instantiate(Cube);

    }

}

将含上面代码的脚本挂载到某一物体上,并将需要克隆的物体Cube拖入脚本组件中,运行后便可在场景中得到一个克隆的预制体Cube。

5.物体组件

5.1组件的基本操作

代码类名后面跟的MonoBehaviour使脚本能够挂到物体的组件中。

组件在Inspector视图中,可以通过最下面的Add Component添加组件,通过组件点击组件名左边的勾选符号打开或关闭组件,通过组件名右边的三个点下面的Remove Component移除组件。

5.2通过脚本操作组件

5.2.1添加组件

使用的API:AddComponent</*组件名称*/>();

示例:

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        GameObject go = GameObject.Find("Cube/Sphere");

        go.AddComponent<Rigidbody>();

    }

}

该段代码先找出物体Sphere,运行时在该物体上添加Rigidbody组件。

5.2.2查找组件

1.查找单个组件

使用的API:GetComponent</*组件名称*/>()

示例:

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        GameObject go = GameObject.Find("Cube/Sphere");

        go.GetComponent<SphereCollider>().radius = 1;

    }

}

该段代码的功能是,先查找Sphere物体,然后查找Sphere物体的SphereCollider组件,并将该组件中radios值改为1。

如果想查找该物体及其子物体的某个组件,可以将示例代码中的go.GetComponent<SphereCollider>().radius = 1;改为go.GetComponentInChildren<SphereCollider>().radius = 1;,改完之后会查找该物体及其子物体的该组件类型,找到一个后便停止,不再继续查找。

如果想查找该物体及其父物体的某个组件,可以将示例代码中的go.GetComponent<SphereCollider>().radius = 1;改为go.GetComponentInParent<SphereCollider>().radius = 1;改完之后会查找该物体及其父物体的该组件类型,找到一个后便停止,不再继续查找。

2.查找多个同类型的组件

使用的API:GetComponents<AudioSource>();

示例:

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        GameObject go = GameObject.Find("Cube/Sphere");

        SphereCollider[] sphereColliders= go.GetComponents<SphereCollider>();

        Debug.Log("查找到多少个:"+sphereColliders.Length);

    }

}

这段代码的功能是,先找到Sphere物体,找出物体里所有SphereCollider组件,将找到的组件放入数组SphereCollider中,并通过控制台打印数组的长度。

如果想查找该物体及其子物体的某个组件,可以将示例代码中的SphereCollider[] sphereColliders= go.GetComponents<SphereCollider>();改为SphereCollider[] sphereColliders= go.GetComponentsInChildren<SphereCollider>();改完之后会查找该物体及其子物体的所有该组件类型。

如果想查找该物体及其父物体的某个组件,可以将示例代码中的SphereCollider[] sphereColliders= go.GetComponents<SphereCollider>();改为SphereCollider[] sphereColliders = go.GetComponentsInParent<SphereCollider>();改完之后会查找该物体及其父物体的所有该组件类型。

5.2.3删除组件

使用的API:Destroy(/*要删除的组件类型*/);

示例:

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        GameObject go = GameObject.Find("Cube/Sphere");

        SphereCollider sphereCollider = go.GetComponent<SphereCollider>();

        Destroy(sphereCollider);

    }

}

该段代码的功能是,找到物体Sphere,并在运行时删除该物体的SphereCollider组件。SphereCollider sphereCollider = go.GetComponent<SphereCollider>();改为Component sphereCollider = go.GetComponent<SphereCollider>();也可实现该效果。

5.2.4关闭和激活组件

使用的API:enabled=false;

示例:

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        GameObject go = GameObject.Find("Cube/Sphere");

        go.GetComponent<SphereCollider>().enabled=false;

    }

}

该代码的功能是,找到物体Sphere,并在运行时关闭该物体的SphereCollider组件。

如果想要激活组件,可以将上面示例中的go.GetComponent<SphereCollider>().enabled=false;改为go.GetComponent<SphereCollider>().enabled=true;

 

 

6.场景管理

6.1场景的基础操作

6.1.1场景的创建

场景创建的快捷键Ctrl+N可以快捷创建场景,此时创建的场景为临时场景,需要保存起来后续才能使用。

6.1.2场景的删除

直接在文件夹中进行删除即可,因为场景中可能会有一些依赖项,因此非必要不要删除场景。

6.2同步加载场景

6.2.1切换场景

使用的API:SceneManager.LoadScene( );

示例:

using UnityEngine;

using UnityEngine.SceneManagement;

public class Test : MonoBehaviour

{

    void Start()

    {

        SceneManager.LoadScene("Scenes/SampleScene1");

    }

}

先将两个场景导入File>Build Settings...中,将含上面代码的脚本挂到待切换场景的一个物体上,该脚本可以实现将场景切换至Scenes文件夹下的SampleScene1场景播放;

地址"Scenes/SampleScene1"也可换成该场景在Build Settings...中所对应的序号。

6.2.2同时加载场景

使用的API:SceneManager.LoadScene( ,LoadSceneMode.Additive);

示例:

using UnityEngine;

using UnityEngine.SceneManagement;

public class Test : MonoBehaviour

{

    void Start()

{     

SceneManager.LoadScene("Scenes/SampleScene1",LoadSceneMode.Additive);

    }

}

先将两个场景导入File>Build Settings...中,将含上面代码的脚本挂到原场景的一个物体上,该脚本可以实现将原将原场景与Scenes文件夹下的SampleScene1场景同时加载;

地址"Scenes/SampleScene1"也可换成该场景在Build Settings...中所对应的序号。

6.3异步加载场景

示例

using System.Collections;

using UnityEngine;

using UnityEngine.SceneManagement;

public class Test : MonoBehaviour

{

    void Start()

    {

        StartCoroutine(Load());

    }

    private IEnumerator Load()

    {

        AsyncOperation asyncOperation=SceneManager.LoadSceneAsync("Scene/Cut");

        asyncOperation.allowSceneActivation = false;

        while (asyncOperation.progress < 0.9f)

        {

            Debug.Log("Current progress is " + asyncOperation.progress);

            yield return null;

        }

        asyncOperation.allowSceneActivation = true;

        if (asyncOperation.isDone)

        {

            Debug.Log("Finished load and skip.");

        }

        else

        {

            Debug.Log("Not finished");

        }

    }

}

不理解该段代码

6.4加载场景时保留物体

使用的API:DontDestroyOnLoad( );

示例:

using UnityEngine;

using UnityEngine.SceneManagement;

public class Test : MonoBehaviour

{

    void Start()

    {

        GameObject capsule = GameObject.Find("Capsule");

        DontDestroyOnLoad(capsule);

        SceneManager.LoadScene("Scenes/SampleScene1");

    }

}

先将两个场景导入File>Build Settings...中,将含上面代码的脚本挂到原场景的一个物体上,该脚本实现的功能是将原场景切换至Scenes文件夹下的SampleScene1场景后保留原场景的Cube物体及该物体下面的子物体,该代码保留的物体只能是根物体,即没有父物体的物体。

地址"Scenes/SampleScene1"也可换成该场景在Build Settings...中所对应的序号。

 

7.UGUI图形系统

7.1画布与事件系统

7.1.1画布

画布用于承载所有的UI元素。

Canvas物体的Canvas组件Render Mode分为三种:

第一种:Screem Space Overlay模式,该模式下画布中的元素始终在前面。

第二种:Screem Space Camera模式,该模式下画布中的元素是否在前取决于它与物体的位置。

第三种:World Space模式,该模式下画布可以自由移动缩放。可用来做人物的血条等。

7.1.2事件系统

事件系统是使画布内元素产生效果系统,创建画布后会自动创建,如果不小心删除也可点击添加单独创建。

7.2图像、文本框、按钮、输入框的脚本交互

7.2.1登录按钮的脚本实现

示例

using UnityEngine;

using UnityEngine.UI;

public class Login : MonoBehaviour

{

    InputField accountInput;

    InputField passwordInput;

    Button loginButton;

    void Start()

    {

        accountInput = transform.Find("Account").GetComponent<InputField>();

        passwordInput = transform.Find("Password").GetComponent<InputField>();

        loginButton = transform.Find("Login").GetComponent<Button>();

        loginButton.onClick.AddListener(LoginButtonOnClick);

    }

    void LoginButtonOnClick()

    {

        string account = accountInput.text;

        string password = passwordInput.text;

        Debug.Log("Account is " + account);

        Debug.Log("Password is " + password);

    }

 

}

该段代码实现的功能是,在输入账号和密码并点击登录键后,将账号和密码在控制台输出。

7.2.2更换背景图的脚本实现

示例

using UnityEngine;

using UnityEngine.UI;

public class Change : MonoBehaviour

{

    public Sprite bg;

    void Start()

    {

        transform.Find("Background").GetComponent<Image>().sprite = bg;

    }

}

该段代码实现的功能是,在将新的图像添加到新建的脚本后,点击播放可以在运行时将背景图换成新的图像

7.2.3修改文本框

示例

using UnityEngine;

using UnityEngine.UI;

public class Test : MonoBehaviour

{

    string text = "抵制不良游戏,拒绝盗版游戏。注意自我保护,谨防受骗上当。\n适度游戏益脑,沉迷游戏伤身。合理安排时间,享受健康生活。";

    void Start()

    {

        transform.Find("Text").GetComponent<Text>().text = text;

    }

}

该段代码实现的功能是,在运行时将文本框文字改为:抵制不良游戏,拒绝盗版游戏。注意自我保护,谨防受骗上当。适度游戏益脑,沉迷游戏伤身。合理安排时间,享受健康生活。

7.2.4点击按钮导入链接

示例

using UnityEngine;

using UnityEngine.UI;

public class Test : MonoBehaviour

{

    void Start()

    {

transform.Find("Button").GetComponent<Button>().onClick.AddListener(ButtonOnClick);

    }

    void ButtonOnClick()

    {

        Application.OpenURL("https://v.qq.com/channel/choice?channel_2022=1");

    }

}

该段代码实现的功能是,在点击了Button按钮后,跳转到网站https://v.qq.com/channel/choice?channel_2022=1。

7.3切换开关与开关组

7.3.1切换开关

示例

using UnityEngine;

using UnityEngine.UI;

public class Test : MonoBehaviour

{

    InputField user;

    InputField password;

    Toggle toggle;

    Button logon;

    void Start()

    {

        user= transform.Find("User").GetComponent<InputField>();

        password = transform.Find("Passward").GetComponent<InputField>();

        toggle=transform.Find("Toggle").GetComponent<Toggle>();

        logon=transform.Find("Logon").GetComponent<Button>();

        logon.onClick.AddListener(logonOnClick);

    }

    void logonOnClick()

    {

        if (toggle.isOn == true)

        {

            string username= user.text;

            string passwordnum=password.text;

            Debug.Log("用户名是:"+username);

            Debug.Log("密码是:"+passwordnum);

        }

        else

        {

            Debug.Log("请先同意用户协议");

        }

    }

}

该段代码实现的功能是,在点击了按钮后,可以正常登录,未点击时控制台显示:请先同意用户隐私协议!

7.3.2开关组

若有多个Toogle,而只能选择一个,可在Hierachy中新建一个空对象,在空对象的Inspector中添加一个Toggle Group,将空对象移入每个Toogle的Inspector>Toogle>Group中,运行即可实现单选,Toggle Group的Allow Switch Off指允许取消勾选,即选择后可以实现一个都不选。

7.4滑动条Slider的使用

示例

using UnityEngine;

using UnityEngine.UI;

public class Test : MonoBehaviour

{

    Slider slider;

    void Start()

    {

        slider = transform.Find("Slider").GetComponent<Slider>();

        slider.onValueChanged.AddListener(OnValueChanged);

    }

    void OnValueChanged(float value)

    {

        Debug.Log("进度条的值为:"+slider.value);

    }

}

该段代码的功能是,在控制台显示slider滑动的值。

 

7.5滚动视图与遮罩的使用

7.5.1滚动视图Scroll View

滚动视图是容纳多个图标的容器,可以通过拖动滚动条来查看所有的图标,因为在Scroll View中的Viewport含有Mask组件,所以,图标只会在滚动视图内显示。

7.5.2Mask和Rect Mask 2D

Mask作为父物体的组件时,子物体超出父物体的部分不会显示,这里会识别父物体的透明度,透明度高的部分也不会被显示。

Rect Mask 2D作为父物体的组件时功能与Mask相同,但不会识别父物体的透明度,父物体以矩形方式呈现。

 

7.6水平、垂直、网格布局组件与布局元素

7.6.1水平、垂直和网格布局

水平布局组件:Horizontal Layout Group,在Scroll View>View Port>Content中加入该组件,可以将滚动视图中的图像设置成一行,并进行相关设置。

垂直布局组件:Vertical Layout Group,在Scroll View>View Port>Content中加入该组件,可以将滚动视图中的图像设置成一列,并进行相关设置。

网格布局组件:Grid Layout Group,在Scroll View>View Port>Content中加入该组件,可以将滚动视图中的图像设置成方固定方格排列,并进行相关设置。

7.6.2布局元素

布局元素组件:Layout Element,网格布局元素中的单个图像若添加该组件,并选择组件中的Ignore Layout,可以使该图像自由移动,不受网格限制。

 

7.7内容尺寸适配器Context Size Fitter

7.7.1内容尺寸适配器

该组件英文名Context Size Fitter,当在内容输入文本框或者在Scroll View>View Port>Content的网格状态下使用该组件,把Horizontal Fit项设置成Preferred Size时,可以根据内容自适应左右宽度的大小,Vertical Fit同理。

7.7.2克隆元素图标

示例

using UnityEngine;

public class Clone : MonoBehaviour

{

    public GameObject hero;

    public Transform content;

    void Update()

    {

        if (Input.GetKeyDown(KeyCode.A))

        {

            GameObject clonehero=GameObject.Instantiate(hero);

            clonehero.transform.parent = content;

        }

    }

}

将元素图标的预制件与HeroPanel>Scroll View>View Port>Content拖入该脚本并将该脚本挂到penel中后,可以在播放时通过按A键来克隆物体。

7.8UI特效与图片填充功能

7.8.1UI特效

Outline组件,该组件可以通过设置大小、颜色等给UI元素(如图片)描边。

Shadow组件,该组件可以通过设置大小、颜色等给UI元素(如图片)设置阴影。

7.8.2图片型进度条制作

示例

using System.Collections;

using UnityEngine;

using UnityEngine.UI;

public class FullFill : MonoBehaviour

{

    public Image image;

    void Start()

    {

        StartCoroutine(Fill());

    }

    IEnumerator Fill()  //协程就是要等时间

    {

        float value = 0;

        while(value<=1)

        {

            yield return new WaitForSeconds(0.5f);

            value+=0.1f;

            image.fillAmount = value;

        }

    }

}

新建两个层级不同的Image,父Image设置成背景色,子Image设置成填充色,并在子Image的Sourse Image中导入一张图片,将Image Type设置成Filled,将Fill Method设置成Horizontal,将Fill Origin设置成Left,将含上面代码的脚本挂到某一物体上,将子Image挂到脚本中,可以实现实现播放时的进度条加载效果。

 

8.用户输入管理

8.1虚拟轴

使用的API:.GetAxis("/*Edit>Project Settings>Input Manager>Axes中对应的名字*/");

8.1.1控制位置  

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    void Update()

    {

        float horizontal = Input.GetAxis("Horizontal");

        float vertical = Input.GetAxis("Vertical");

        if (horizontal != 0)

        {

            transform.position=new Vector3(transform.position.x+horizontal*0.1f, transform.position.y,transform.position.z);

        }

        if(vertical != 0)

        {

            transform.position=new Vector3(transform.position.x,transform.position.y+vertical*0.1f,transform.position.z);

        }

    }

}

该段代码实现的目标是在运行时可以通过WASD来控制前后左右,Horizontal和Vertical是Edit>Project Settings>Input Manager>Axes中Horizontal和Vertical的名字。

8.1.2控制旋转

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    void Update()

    {

        float horizontal = Input.GetAxis("Horizontal");

        if (horizontal != 0)

        {

            transform.eulerAngles=new Vector3(transform.eulerAngles.x, transform.eulerAngles.y+horizontal, transform.eulerAngles.z);

        }

    }

}

该段代码实现的功能是通过AD来控制左右旋转。

8.1.3控制其他

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    void Update()

    {

        Debug.Log(Input.GetAxis("Mouse X"));

    }

}

该段代码实现的功能是在控制台输出鼠标在X轴方向移动的值,Mouse X也可以换成Edit>Project Settings>Input Manager>Axes中的其他值来实现相应的控制。

8.2获取键盘事件

使用的API:GetKey("相应的键"/*也可以用KeyCode.A*/)

using UnityEngine;

public class Test : MonoBehaviour

{

    void Update()

    {

        if (Input.GetKey("a"/*也可以用KeyCode.A*/))

        {

            Debug.Log("A键被按下了");

        }

    }

}

该段代码实现的功能是,在按住A键时控制台不停输出:A键被按下了。

若上面代码将GetKey换成GetKeyDown,则控制台会在按键按下时打印一次输出。

若上面代码将GetKey换成GetKeyUp,则控制台会在按键抬起时打印一次输出。

8.3获取鼠标事件

8.3.1获取鼠标按键

使用的API:GetMouseButtonDown(数字)、GetMouseButtonUp(数字)、GetMouseButton(数字)/*数字0代表鼠标左键,数字1代表鼠标右键,数字2代表鼠标滚轮*/

示例1

using UnityEngine;

public class Test : MonoBehaviour

{

    void Update()

    {

        if (Input.GetMouseButtonDown(0))

        {

            GameObject cube = GameObject.Find("Cube");

            cube.transform.localScale=new Vector3(2,2,2);

        }

    }

}

画面中创建一个立方体,当上述代码执行时,按下鼠标左键,画面中的立方体会放大一倍。

若将上面代码中的GetMouseButtonDown换成GetMouseButtonUp则会在按键抬起时执行效果。

示例2

using UnityEngine;

public class Test : MonoBehaviour

{

    void Update()

    {

        if (Input.GetMouseButtonDown(0))

        {

            GameObject cube = GameObject.Find("Cube");

            cube.transform.localScale+=new Vector3(1,1,1);

        }

    }

}

上述代码的功能是,在播放时不停按下鼠标左键,立方体会被不断放大。

8.3.2获取鼠标位置

使用的API:Input.mousePosition;

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    bool isDown=false;

    void Update()

    {

        if (Input.GetMouseButtonDown(0))

        {

            isDown=true;

        }

        if (Input.GetMouseButtonUp(0))

        {

            isDown = false;

        }

        if (isDown)

        {

            GameObject go = GameObject.Find("Image");

            go.transform.position=Input.mousePosition;

        }

    }

}

创建一个图片,该段代码实现的功能是,点击鼠标左键后,图片会回到鼠标指针所在的位置,当鼠标持续点击并移动时,图片会跟随鼠标指针。

8.4移动设备输入

使用的API:Input.touchCount

          Input.touches[0].fingerId

Input.touches[0].position

Input.touches[0].deltaPosition;

示例

using UnityEngine;

using UnityEngine.UI;

public class MyText : MonoBehaviour

{

    Text juse;

    void Start()

    {

        juse = GameObject.Find("Text").GetComponent<Text>();

    }

    void Update()

    {

        if (Input.touchCount >= 1)

        {

            juse.text= "当前有:" + Input.touchCount + "根手指触碰。" + "当前手指的ID是:" + Input.touches[0].fingerId + "当前手指所在位置是:" + Input.touches[0].position + "从上一帧到现在移动了:" + Input.touches[0].deltaPosition;

        }

    }

}

在场景中新建一个Text,将上面的代码写好并打包成apk文件,运行apk文件,在点击屏幕的时候,屏幕上会显示当前有几根手指触碰,当前手指的ID,当前手指所在位置,和从上一帧到现在移动了多少。

 

9.自然环境设计

9.1天空盒的创建

9.1.1六张图片创建

在Project中新建材质,将Inspector>Shader中将材质设置成Skybox>6 Side,导入6张照片,将6张照片添加进Inspector中,再将新建材质拖入Scene中。

9.1.2全景图片创建

在Project中新建材质,将Inspector>Shador中将材质设置成Skybox>Cubemap,导入一张全景图片,将图片的Texture Shape设置成Cube,再将图片拖进新建材质的Inspector中,将新建材质拖入Scene中。

9.2山脉和地表贴图的创建

在Hierachy视图中新建Terrain物体,在Terrain的Inspector>Terrain中对地形进行修改,如果要Paint Texture需要先创建图层。

9.3树和草的创建

通过在Terrain的Inspector>Terrain中对地形添加树和草,树和草均需要先添加图层。

在Hierachy中添加Windzone来使树木在播放时有风吹效果。

9.4水和雾

通过将一个水的预制件(也可自己制作,即一个有动态纹理的平面)加入场景实现水的效果。

通过点击Lighting>Other Seeting>Fog来实现雾的效果,还可在下面设置雾的颜色,密度等。

 

10.光照系统

10.1灯光组件

10.1.1区域灯光的使用

先将Lighting>Mixed Lighting>Baked Global Illumin选项打开,并将Lighting>Lightmap Setting>Lightmapper设置为progressive GPU(preview),,创建一个区域光和一个其他类型(直线光、点光、和聚光都可)的光源,设置区域光的光照范围和颜色,在Lighting中点击Generate Lighting就可以看到静态的物体被渲染成了区域光的颜色,而其非静态物体则不受影响,烘焙后的物体的颜色将一直保存,不随区域光的删除而消失,除非在Lighting中点击Generate Lighting重新生成照明。

10.1.2灯光组件介绍

灯光组件的添加及灯光组建的功能。

10.2照明设置

照明设置打开方式:Windows>Rendering>Lighting Setting.

介绍了Lighting的一些按钮功能。

10.3自发光

自发光物体创建方式:在Project中新建材质,在新建材质的组件中将Emission勾选上,将挂上贴图和设置颜色,在将新建材质挂到物体的Mesh Render>Material中,即可以实现物体的自发光。

10.4光照探测器

自发光可以在Generate Lighting后让静态物体有烘焙效果,但对非静态物体无效。

通过在Hierachy里添加光照探测器,并编辑光照探测器的范围,让非静态物体在光照探测器的范围之内,点击Lighting>Generate Lighting,可以使非静态物体也能有烘焙效果。

10.5反射探测器

若一个房间里的地板上反射的灯光模糊,可以在Hierachy里添加反射探测器,将反射探测器调整至合适的大小,将房间的地板在组件中取消勾选Matellic,并将Smooth的值拉到最大,将反射探测器组件中的Type改为Realtime,此时地面就可以呈现镜子般反射灯光的效果。

 

12.3D物理系统

12.1刚体组件介绍

介绍了刚体组件Rigidbody的中一些选项的功能。

Rigidbody组件中的Is Kinematic勾选上后,该物体将不会受到碰撞等效果的影响。

12.2刚体常用的方法

12.2.1Constant Forse组件

可以在该组件中设置不同方向的恒定力,Relative表示按照相对坐标的的方向确定力。

12.2.2添加刚体速度

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    Rigidbody rb;

    void Start()

    {

        rb = GetComponent<Rigidbody>();

        rb.velocity = new Vector3(0, 0, 5);

    }

}

该段代码的功能是,使脚本所挂的物体在世界坐标的Z轴方向以5的速度运动。

12.2.3添加力

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    Rigidbody rb;

    void Start()

    {

        rb = GetComponent<Rigidbody>();

        rb.AddForce (new Vector3(0, 0, 10f));

    }

}

该段代码的功能是在代码所挂的物体上添加一个世界坐标Z轴方向的大小为50的力。

若想添加相对坐标的Z轴的方向的力,可以将上述代码中的rb.AddForce(new Vector3(0, 0, 10f));改为rb.AddRelativeForce (new Vector3(0, 0, 10f));

若想添加世界坐标Z轴方向的扭矩力,可以将上述代码中的rb.AddForce(new Vector3(0, 0, 10f));改为rb.AddTorque (new Vector3(0, 0, 10f));

若想添加相对坐标Z轴方向的扭矩力,可以将上述代码中的rb.AddForce(new Vector3(0, 0, 10f));改为rb.AddRelativeTorque (new Vector3(0, 0, 10f));

ForceMode 力的模式

在unity中,Rigidbody.AddForce()实现对刚体物体施加力的效果,实现物体例如碰撞,爆炸等等效果

调用函数如下:

public void AddForce(Vector3 force, ForceMode mode = ForceMode.Force);

public void AddForce(float x, float y, float z, ForceMode mode = ForceMode.Force);

AddForce()函数有一个参数 ForceMode , 为枚举类型

Force:添加一个可持续力到刚体,使用它的质量

Acceleration:添加一个可持续加速度到刚体,忽略它的质量。

Impulse:添加一个瞬间冲击力到刚体 ,使用它的质量。( 爆炸或碰撞力量 )

VelocityChange:添加一个瞬间速度变化给刚体,忽略它的质量。

具体介绍如下:

在以下举例中均设刚体质量为m=2.0f,力向量为f=(10.0f,0.0f,0.0f)。

1 . ForceMode.Force:默认方式,使用刚体的质量计算,时间间隔以系统帧频间隔计算(默认值为0.02s)。

则由动量定理 f • t = m • v

可得:10 * 0.02 = 2.0 * v1,从而可得 v1=0.1 m/s,即每秒刚体在X轴上值增加0.1米

2 . ForceMode.Acceleration:忽略刚体的实际质量而采用默认值m = 1.0f,时间间隔以系统帧频间隔计算(默认值为0.02s)

则 f • t = 1.0 • v

可得:10 * 0.02 = 1.0 * v2,从而可得 v2=0.2 m/s,即每秒刚体在X轴上值增加0.2米

3 . ForceMode.Impulse:采用瞬间力作用方式,即默认 t = 1.0f,不再采用系统的帧频间隔

则 f • 1.0 = m • v

可得:10 * 1.0 = 2.0 * v3,从而可得 v3=5.0 m/s,即每秒刚体在X轴上值增加5.0米

4 . ForceMode.VelocityChange:忽略刚体的实际质量,采用默认值m = 1.0f,同时也忽略系统的实际帧频间隔,采用默认间隔 t = 1.0f

则 f • 1.0 = 1.0 • v

可得:10 * 1.0 = 1.0 * v4,从而可得 v4=10.0 m/s,即每秒刚体在X轴上值增加10.0米

12.2.4爆炸力

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    Rigidbody rb;

    void Start()

    {

        rb = GetComponent<Rigidbody>();

    }

    void Update()

    {

        if (Input.GetKeyDown("a"))

        {

            rb.AddExplosionForce(500f, transform.position, 10f);/*三个参数分别是:爆炸力度、爆炸位置、爆炸范围*/

        }

    }

}

该段代码的功能是在运行时按下A键后,组件所挂的物体在原位置受到一个大小为500f的力。

12.2.5刚体的唤醒和休眠

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    Rigidbody rb;

    void Start()

    {

        rb = GetComponent<Rigidbody>();

    }

    void Update()

    {

        if (Input.GetKeyDown("a"))

        {

            rb.Sleep();

        }

        else if (Input.GetKeyDown("b"))

        {

            rb.WakeUp();

        }

    }

}

该段代码实现的功能是,在运行状态下按A键,刚体组件将失效,再按B键刚体组件将恢复效果。

12.3碰撞器和触发器

12.3.1碰撞器组件介绍

1.点了碰撞器组件中的Is Trigger按钮后,碰撞器变为触发器。

2.触发和碰撞检测的条件

碰撞器条件:1.碰撞与被碰撞物体都需要有碰撞器组件且都不能勾选为触发器。2.挂脚本的物体上有刚体组件。

触发器条件:1.碰撞与被碰撞物体,至少有一个勾选为触发器。2挂脚本的物体上有刚体组件。

12.3.2碰撞器

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    private void OnCollisionEnter(Collision collision)

    {

        Debug.Log("I had collision");

    }

}

该段代码的功能是,脚本所挂物体发生碰撞时控制台打印:我发生了碰撞。

若想在结束碰撞时调用控制台打印,可以将上述代码中的private void OnCollisionEnter(Collision collision)换成private void OnCollisionExit(Collision collision)。

若想在碰撞停留时调用控制台打印,可以将上述代码中的private void OnCollisionEnter(Collision collision)换成private void OnCollisionStay(Collision collision)。

12.3.3触发器

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    private void OnTriggerEnter(Collider collider)

    {

        Debug.Log("I had Trigger.");

    }

}

该段代码的功能是,脚本所挂物体发生碰撞时控制台打印:我发生了触发。

若想在结束触发时调用控制台打印,可以将上述代码中的private void OnTriggerEnter(Collider collider)改为private void OnTriggerExit(Collider collider)。

若想在触发停留时调用控制台打印,可以将上述代码中的private void OnTriggerEnter(Collider collider)改为private void OnTriggerStay(Collider collider)。

12.3.4所碰撞物体

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    public void OnCollisionEnter(Collision collision)

    {

        Debug.Log("Collision object is:" + collision.gameObject.name);

    }

}

该段代码可以在运行时打印脚本所挂物体所碰撞的物体名称。

12.4力的常用函数

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    Rigidbody rb;

    void Start()

    {

        rb = transform.GetComponent<Rigidbody>();

        Vector3 direction = transform.position + new Vector3(0, 1, 0) - transform.position;

        rb.AddForceAtPosition(direction * 10f, transform.position);

    }

}

该函数的功能是,使脚本所挂物体受到一个指定方向和作用点的力。

12.5物理材质

物理材质在Project>Creat>Physics Material中创建,创建后可以设置摩檫力、弹力等值,设置后拖入物体的Collider组件中,便可使组件具有该物理性质。

注意,当两个碰撞的物体设置了不同的结合方式时,采用的顺序如下: Average < Minimum < Multiply < Maximum,例如一个设置Minimum,一个设置Maximum,那么结合方式为Maximum。

12.6关节组件

12.6.1组件效果

固定关节组件(Fixed Joint):想两个物体用棍子连载一起。

弹簧关节组件(Spring Joint):像两个物体用弹簧连在一起。

铰链关节组件(Hinge Joint):像两个物体用铰链连在一起。

角色关节组件(Character Joint):可以模拟角色的骨骼关节。

可配置关节组件(Configurable Joint):可模拟任意关节效果。

12.6.2关节力度检测

检测断开的代码,脚本API:OnJointBreak

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    private void OnJointBreak(float force)

    {

        Debug.Log("Joint is break,force is:" + force);

    }

}

该段代码的功能是在设置了关节断开的力度后,运行时断开会在控制台打印关节断开了,并显示断开时的力度。

12.7射线

12.7.1射线的绘制

第一种方式:

脚本API:Debug.DrawLine(起点位置,终点位置,颜色,持续时长,是否被遮挡);

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        Debug.DrawLine(transform.position, new Vector3(5, 5, 5), Color.blue, 10,true);

    }

}

上述脚本的功能是,在脚本所挂物体处发射一条终点坐标为(5,5,5)的,蓝色的,延迟10秒的,可被遮挡的射线。

第二种方式:

脚本API:Debug.DrawRay(起点位置,方向和长度,颜色,持续时长,是否被遮挡);

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        Debug.DrawRay(transform.position,new Vector3(0,1,0),Color.blue,10,true);

    }

}

上述脚本的功能是,在脚本所挂物体处发射一条朝(0,1,0)方向的,两点之间长度的,蓝色的,延迟10秒的,可被遮挡的射线。

12.7.2射线检测

1.检测单个物体

第一种方式

using UnityEngine;

public class Test : MonoBehaviour

{

    Ray ray;

    RaycastHit hit;

    void Update()

    {

        ray = Camera.main.ScreenPointToRay(Input.mousePosition);

        if (Physics.Raycast(ray, out hit))

        {

            Debug.Log("Mouse point attached to " + hit.transform.name);

        }

    }

}

将含上面代码的脚本挂到摄像机上,在运行时可以显示鼠标指向的物体的名称。

第二种方式

使用的API:Physics.Raycast(射线,光线碰到的物体out hit(类型RaycastHit),射线长度float,遮罩过滤层LayerMask)

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    Camera camera;

    void Start()

    {

        camera = GameObject.Find("Main Camera").GetComponent<Camera>();

    }

    void Update()

    {

        if (Input.GetMouseButtonDown(0))

        {

            Ray ray = camera.ScreenPointToRay(Input.mousePosition);

            RaycastHit hit;

            if (Physics.Raycast(ray, out hit, 100f))

            {

                Debug.Log("Hitted,Position is:" + hit.point + ",Object name is:" + hit.collider.gameObject.name);

            }

            else

            {

                Debug.Log("No hitted");

            }

        }

    }

}

该段代码的功能是,在运行并用鼠标左键点击某处后如果发生了碰撞,控制台打印发生了碰撞,并打印碰撞的位置和碰撞的物体名称。

第三种方式

使用的API:Physics.Raycast(射线起点Vector3,射线方向Vector3,光线碰到的物体out hit(类型RaycastHit),射线长度float,遮罩过滤层LayerMask)

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    public LayerMask layerMask;

    void Start()

    {

        layerMask = LayerMask.GetMask("Boss");

    }

    void Update()

    {

 

        if (Input.GetMouseButtonDown(0))

        {

            RaycastHit hit;

            if (Physics.Raycast(transform.position, transform.forward, out hit, 100f, layerMask))

            {

                Destroy(hit.collider.gameObject);

            }

            else

            {

                Debug.Log("miss hitted target");

            }

        }

    }

}

创建两个物体,该两个物体的X,Y轴数值相同,将含上面代码的脚本挂到两个物体中Z轴数值小的物体上,在Inspector中将两个物体的Layer设置成“Boss”,在两个物体的中间加一个物体将两个物体隔开,将该物体的Layer设置成另一种,运行后点击鼠标左键,Z轴数值大的物体将被销毁。

2.检测多个物体

碰到的物体形成数组

用到的API:Physics.RaycastAll(射线,射线最大长度fioat,遮罩过滤层LayerMask)

也可以用:Physics.RaycastAll(射线起点Vector3,射线方向Vector3,射线长度float,遮罩过滤层LayerMask)

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    void Update()

    {

        if (Input.GetMouseButtonDown(0))

        {

            RaycastHit[] hit=Physics.RaycastAll(transform.position,transform.forward,100f);

            for(int i = 0; i < hit.Length; i++)

            {

                Debug.Log("Hitted "+hit.Length+" object");

                Debug.Log("No." + i + " name is " + hit[i].collider.gameObject.name);

            }

        }

    }

}

该段代码的功能是将探测的物体组成一个数组,并通过控制台访问数组的信息。

3.球形射线

使用的API:Physics.OverlapSphere(transform.position,3f);

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        Collider[] colliders = Physics.OverlapSphere(transform.position, 3f);

        for(int i = 0; i < colliders.Length; i++)

        {

            Debug.Log("Hitted " + colliders.Length + " objects");

            Debug.Log("No. " + i + " name is " + colliders[i].gameObject.name);

        }

    }

}

该段代码的功能是,检测一个球形内的碰撞体信息,并用控制台输出。

 

13.2D物理系统

13.1 2D的物理碰撞和触发器

13.1.1碰撞和触发的条件

碰撞的条件:两个物体都要带有碰撞器,其中一个需要有刚体。

触发的条件:碰撞的两个物体至少有一个勾选了Is Trigger选项。

13.1.2碰撞的生命周期

使用的脚本API:OnCollisionEnter2D

示例

using UnityEngine;

public class Player : MonoBehaviour

{

    private void OnCollisionEnter2D(Collision2D collision)

    {

        Debug.Log("I collided "+collision.gameObject.name);

    }

}

该段代码的功能是,在两个2D物体发生碰撞时,控制台打印进入碰撞和脚本所挂物体碰到的物体名称。

若想在碰撞结束时打印,可以将上述代码中的OnCollisionEnter2D改为OnCollisionExit2D。

若想在碰撞发生时打印,可以将上述代码中的OnCollisionEnter2D改为OnCollisionStay2D。

13.1.3触发的生命周期

使用的脚本API:OnTriggerEnter2D

示例

using UnityEngine;

public class Player : MonoBehaviour

{

    private void OnTriggerEnter2D(Collider2D collision)

    {

        Debug.Log("I trigged " + collision.gameObject.name);

    }

}

该段代码的功能是,在两个2D物体发生接触时,控制台打印进入接触和脚本所挂物体接触到的物体名称。

若想在接触结束时打印,可以将上述代码中的OnTriggerEnter2D改为OnTriggerExit2D。

若想在接触持续时打印,可以将上述代码中的OnTriggerEnter2D改为OnTriggerStay2D。

13.2 2D物理材质

讲了Project中新建的Physice Material 2D的使用。

13.3 2D效果器

讲了2D效果器组件,包括:

1.Area Effector 2D

2.Surface Effector 2D

3.Buoyancy Effector 2D

4.Point Effector 2D

13.4 2D物体中的其他碰撞器与恒力组件

讲了Capsule Collider 2D,Circle Collider 2D,Edge Collider 2D组件。

讲了Constant Force 2D组件。

13.5 脚本与2D刚体的交互

示例

using UnityEngine;

public class Player : MonoBehaviour

{

    Rigidbody2D r2;

    void Start()

    {

        r2 = transform.GetComponent<Rigidbody2D>();

    }

    void Update()

    {

        float x = Input.GetAxis("Horizontal");

        float y = Input.GetAxis("Vertical");

        if (x != 0 || y != 0)

        {

            r2.velocity = new Vector2(100 * x, 100 * y);

        }

    }

}

该段代码实现的功能是,通过WSAD来控制对象的上下左右移动。

 

14.动画系统

14.1动画的播放控制

14.1.1通过组件控制

导入模型后,在Project中新建一个Animator Controller,双击Animator Controller,将模型内部的动画文件拖入到Animator Controller的场景中,再将Animator Controller拖入到模型的Animator组件(如果没有该组件可以新创建一个)的Controller中,再点击运行模型即可动起来。

14.1.2通过脚本控制

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    Animator am;

    void Start()

    {

        am = transform.GetComponent<Animator>();

    }

    void Update()

    {

        if (Input.GetKeyDown(KeyCode.Alpha0))

        {

            am.SetInteger("id", 0);

        }

        else if (Input.GetKeyDown(KeyCode.Alpha1))

        {

            am.SetInteger("id", 1);

        }

        else if (Input.GetKeyDown(KeyCode.Alpha2))

        {

            am.SetInteger("id", 2);

        }

        else if (Input.GetKeyDown(KeyCode.Alpha3))

        {

            am.SetInteger("id", 3);

        }

        else if (Input.GetKeyDown(KeyCode.Alpha4))

        {

            am.SetInteger("id", 4);

        }

    }

}

在Prooject中创建一个Animator Controller,将动画拖进Animator Controller中,在Animator中设置通过Any State设置动画的播放,在Parameter中设置一个名叫id的变量,点击Animater中的箭头,在Inspector中设置动漫所对应的值,并将Inspector>Setting>Can Transition To Self取消勾选,通过该代码可以实现在运行时,通过按设置的值实现相应的动画效果。

14.2人形动画

人形动画的特点是可以使用其他的人形动画。

14.3动画遮罩

动画遮罩的功能是屏蔽游戏对象某一部位的运动。

14.4动画的分层和退出控制

动画的分层控制是在Animator中添加多个Layer,并对各个Layer进行编辑,来对物体的动作进行分类控制。

14.5动画事件

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    public void TestDebug()

    {

        Debug.Log("Test event");

    }

}

可以在Project的动画文件的Inspector>Animatian>Events中添加动画事件,通过将脚本中的函数名(本例为TestDebug)粘贴至中Inspector>Animatian>Events>Founction中,运行后在动画播放到设置的位置时会激活函数。

 

15.寻路系统

15.1实现简单导航寻路功能

示例

using UnityEngine;

using UnityEngine.AI;

public class Test : MonoBehaviour

{

    private NavMeshAgent agent;

    void Start()

    {

        agent = GetComponent<NavMeshAgent>();

    }

    void Update()

    {

        if (Input.GetMouseButtonDown(0))

        {

            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

            RaycastHit hit;

            bool iscollider = Physics.Raycast(ray, out hit);

            if (iscollider)

            {

                agent.SetDestination(hit.point);

            }

        }

    }

}

将地面物体的Inspector设置成Navigation Static.然后点击菜单Windows>AI>Navigation,将地面物体进行Bake.在待引导的物体上添加Nav Mesh Agent组件。将上述代码挂到待引导物体上,在运行时可以实现通过鼠标左键控制物体运动。

15.2导航面板参数介绍以及导航网格区域介绍

可以在Navigation>Areas中为不同区域添加不同的行走成本,再在Navigation>Object中设置道路成本类型,通过设置成本可以是物体智能的选择走哪条路。

15.3动态障碍物

将Nav Mesh Obstacle组件挂到一个阻碍物体上,并选中该组件中的Carve后,可以使待引导物体检测到阻碍物体而重新规划路线。

15.4分离导航连接线

在地面添加Off Mash Link组件,可以在该组件中设置两个点,设置好后待引导物体可以在这两个点之间移动。

15.5运动时动态烘培导航网格

需要用到Unity官方扩展的Navigation工具。

添加扩展工具后,可以添加NavMeshSurface组件,该组件生成导航网格不需要将地面物体设置成Navigation Static,并可以通过脚本动态生成物体并烘焙。

15.6其他组件功能介绍

Unity官方扩展的Navigation工具中的NavMashLink,该组件为OffMash Link的加强版,可以连接两个导航面。

 

16.音效系统

16.1音频源和音频监听器组件

音频播放可以选择在Hierachy中单独创建Audio Source物体,也可以选择在物体的Inspector中添加Audio Source组件来播放音频。

需要有Audio Listener组件方可听到播放的音频。

16.2音频源组件常用的函数

16.2.1常用功能

使用的API:

播放音频:AudioSours.Play();

暂停播放:AudioSours.Pause();

停止播放:AudioSours.Stop();

检测是否在播放:AudioSourse.isPlaying

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    AudioSource audio;

    void Start()

    {

        audio = transform.GetComponent<AudioSource>();

    }

    void Update()

    {

        if (Input.GetKeyDown("a"))

        {

            if (audio.isPlaying == false)

            {

                audio.Play();

            }

            else

            {

                Debug.Log("Audio is playing,no need to play again.");

            }

        }

        if (Input.GetKeyDown("b"))

        {

            audio.Pause();

        }

        if (Input.GetKeyDown("c"))

        {

            audio.Stop();

        }

    }

}

将该脚本挂入Audio Sourse物体后,可以实现按A键播放(如果已经在播放,则打印在播放),按B键暂停播放,按C键停止播放。

16.2.2指定音频剪辑

使用的API:AudioSource.clip

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    AudioSource audio;

    void Start()

    {

        audio = transform.GetComponent<AudioSource>();

        audio.clip = Resources.Load<AudioClip>("kuaidi1");

    }

    void Update()

    {

        if (Input.GetKeyDown("a"))

        {

            audio.Play();

        }

    }

}

该段代码的功能是,将Resources中的kuaidi1音频文件添加进组件,在游戏播放时按A键可以播放音频。

16.3音频过滤器和音频混响区

16.3.1音频过滤器

音频过滤器组件需要在有Audio Sources组件或Audio Listener组件的物体中才能添加。

16.3.2音频混响区

音频混响区组件Audio Reverb Zone,该组件可以设置在一定区域内的混响效果。

16.3.3音频管理器

打开方式:Edit>Project Setting>Audio.

 

11.3D模型管理

11.1蒙皮网格与普通网格对比

11.1.1对比

共同点:二者都可以通过关闭网格组件来隐藏物体

不同点:蒙皮网格适用于野怪等动画人物,普通网格适用于树等静态物,且普通网格有网格过滤器(Mesh filter),蒙皮网格没有。

11.1.2通过脚本控制网格组件的开关

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    public void Start()

    {

        transform.GetComponent<MeshRenderer>().enabled = false;

    }

}

在将脚本挂到对应的物体后,上述脚本实现的功能是在运行时将网格组件关闭使该物体不再显示,如果为动态物体,可以将上面的代码transform.GetComponent<MeshRenderer>().enabled= false;换成transform.GetComponent<SkinnedMeshRenderer>().enabled= false;

11.2材质的使用

新建或导入物体模型后,在Project中新建一个Material,将新建的Material导入到物体模型的Inspector>Mash Rander>Materials>Elements中,然后通过在新建的Marerial的Inspector中对材质进行Main Map>Albedo中导入图片,变换颜色等设置来改变物体材质。

11.2换肤功能的实现

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    public MeshRenderer cube;

    public Material material1;

    public Material material2;

    void Update()

    {

        if (Input.GetKeyDown("a"))

        {

            cube.material = material1;

        }

        if (Input.GetKeyDown("b"))

        {

            cube.material = material2;

        }

    }

}

将含上面代码的脚本挂到目标物体身上,并将目标物体拖入到脚本的MeshRenderer选项中,再将2套需要变换的材质分别拖入到脚本的material1和material2选项中,点击运行,按A键和按B键后可以实现皮肤的变换。

 

17.特效系统

17.1粒子系统

演示了一些粒子系统的效果。

创建粒子系统,Hierachy中点击右键Effect>Particle System.

17.2使用脚本和粒子系统交互

17.2.1基本交互

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    GameObject particleGO;

    ParticleSystem particle;

    void Start()

    {

        particleGO = GameObject.Instantiate(Resources.Load<GameObject>("22_RFX_Fire_Campfire1"));

        particleGO.transform.position = transform.position;

        particle = particleGO.GetComponent<ParticleSystem>();

        ParticleSystem.MainModule mainModule = particle.main;

        mainModule.loop = true;

    }

    void Update()

    {

        if (Input.GetKeyDown(KeyCode.A))

        {

            particle.Play();

        }

        if (Input.GetKeyDown(KeyCode.B))

        {

            particle.Stop();

        }

        if (Input.GetKeyDown(KeyCode.C))

        {

            particle.Pause();

        }

        if (Input.GetKeyDown(KeyCode.D))

        {

            Destroy(particleGO);

        }

    }

}

新建一个空物体,将含上面代码的脚本挂在空物体上,将名为22_RFX_Fire_Campfire的粒子特效预制体放入Projece/Resources文件夹中,可以实现在运行时将粒子特效预制体22_RFX_Fire_Campfire克隆并在点击A键时播放,B键时停止,C键时暂停,D键时销毁。

17.2.2碰撞回调

使用的API:OnParticleCollision(GameObject go)

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    private void OnParticleCollision(GameObject go)

    {

        Debug.Log("Particle had collision,collide to:" + go.name);

    }

}

将该段代码挂到粒子系统物体的主子物体上,并将该主物体Inspector>Particle System>Collision勾选上,把Collision>Type设置成World,Collision>Mode设置成3D,Collision>Send Collision Messages勾选上,在粒子上方放一物体,运行时控制台会打印粒子发生了碰撞和碰撞到的物体名称。

17.3粒子触发回调

示例

using System.Collections.Generic;

using UnityEngine;

public class Test : MonoBehaviour

{

    ParticleSystem particle;

    void Start()

    {

        particle = transform.GetComponent<ParticleSystem>();

    }

    private void OnParticleTrigger()

    {

        List<ParticleSystem.Particle> particles = new List<ParticleSystem.Particle>();

        int numEnter = particle.GetTriggerParticles(ParticleSystemTriggerEventType.Enter, particles);

        for (int i = 0; i < numEnter; i++)

        {

            ParticleSystem.Particle pt = particles[i];

            pt.startColor = Color.red;

            particles[i] = pt;

        }

        particle.SetTriggerParticles(ParticleSystemTriggerEventType.Enter, particles);

    }

}

在粒子系统上方放一个物体,将该物体拖入粒子系统的Inspector>Particle System>Triggers>Colliders中,将Inspector>Particle System>Triggers>Enter设置成Callback,将含上面代码的脚本挂载到粒子系统物体上,运行时可以使粒子进入物体后变成红色。

17.4特效系统之拖尾

使用的API:TrailRenderer

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    GameObject go;

    void Start()

    {

        go = GameObject.Instantiate(Resources.Load<GameObject>("Accelerate"));

        go.transform.SetParent(transform);

        go.transform.localPosition = new Vector3(0, 0.5f, 0);

    }

    void Update()

    {

        if (Input.GetKeyDown("a"))

        {

            go.GetComponent<TrailRenderer>().emitting = true;

        }

        if (Input.GetKeyDown("b"))

        {

            Destroy(go);

        }

    }

}

新建一个物体,将含上面代码的脚本挂载到该物体上,准备一个拖尾的预制体Accelerate放入Resources文件夹中,在运行时按下A键可以激活克隆的Accelerate,使拖动时表现出效果,按下B键时销毁克隆的Accelerate。

17.5特效系统之粒子力场

讲了Hierachy中点击右键Effect>Particle System Force Field的相关知识点。

 

18.视频播放管理

18.1视频播放方法

在场景中新建RawImage,在RawImage中添加Video Player组件,在Assets中新建Render Texture,将Render Texture和视频资源分别放入Raw Image和Video Player组件中,点击即可播放。

18.2视频组件常用的函数

18.2.1视频播放常用操作

示例

using UnityEngine;

using UnityEngine.Video;

public class Test : MonoBehaviour

{

    VideoPlayer video;

    void Start()

    {

        video = transform.GetComponent<VideoPlayer>();

    }

    void Update()

    {

        if (Input.GetKeyDown("a"))

        {

            if (video.isPlaying == false)

            {

                video.Play();

            }

            else

            {

                Debug.Log("Video is playing,no need to play again");

            }

        }

        if (Input.GetKeyDown("b"))

        {

            video.Pause();

        }

        if (Input.GetKeyDown("c"))

        {

            video.Stop();

        }

    }

}

将该段代码挂到有Video Player组件的物体中,在运行时可以通过按键实现播放,暂停,停止等

18.2.2视频播放组件设置

示例

using UnityEngine;

using UnityEngine.Video;

public class Test : MonoBehaviour

{

    VideoPlayer video;

    void Start()

    {

        video = transform.GetComponent<VideoPlayer>();

        video.source = VideoSource.VideoClip;

        video.clip = Resources.Load<VideoClip>("GameExplain");

    }

}

将视频剪辑文件GameExplain放入Resources文件夹,将组件Video Player>Source设置成URL,通过该段代码可以实现在运行时Video Player>Source切换至Video Clip模式,并播放素材名为GameExplain的视频。

 

19.DoTween补间动画插件

19.1空间物体位置旋转大小等动画

19.1.1位置

使用的API:DOMove(位置,时间)

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        transform.DOMove(new Vector3(10, 10, 10), 2f);

    }

}

当前代码的功能是将脚本所挂物体用2秒移动到世界坐标系(10,10,10)位置。

如果想以本地坐标系作为参考,可以将上面代码中的transform.DOMove(new Vector3(10,10,10), 2f);换成transform.DOLocalMove(new Vector3(10,10,10), 2f);

如果想将物体沿X轴移动,可以将上面代码中的transform.DOMove(new Vector3(10,10,10), 2f);换成transform.DOLocalMoveX(10, 2f);

如果想让物体匀速运动,需要将transform.DOMove(new Vector3(10, 10, 10), 2f);改为transform.DOMove(new Vector3(10, 10, 10), 2f).SetEase(Ease.Linear);

19.1.2旋转

使用的API:DORotate(角度,时间)

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        transform.DORotate(new Vector3(0, 20, 0), 2f);

    }

}

当前代码的功能是将脚本所挂物体用2秒沿世界坐标系的Y轴顺时针转20度。

如果想以本地坐标系为参考旋转,可以将上面代码中的transform.DORotate(new Vector3(0, 20, 0), 2f);改为transform.DOLocalRotate(new Vector3(0, 20, 0), 2f);

19.1.3缩放

使用的API:DOScale(缩放倍数,时间)

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        transform.DOScale(new Vector3(6, 6, 6), 2f);

    }

}

该段代码的功能是,将脚本所挂物体的X,Y,Z轴三个方向都缩放至6倍.

如果只想让X轴方向缩放至6,可以将上面代码中的transform.DOScale(new Vector3(6, 6, 6), 2f);换成transform.DOScaleX (6, 2f);

19.1.4跳跃

使用的API:DOJump(跳跃目的地位置,跳跃高度,步数,时间)

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        transform.DOJump(new Vector3(60, 0, 0), 1,5,6);

    }

}

该段代码的功能是,使脚本所挂物体在6秒内以Y轴方向1高度分5步跳到指定位置。

如果想以当地坐标系为参考,可以将上面代码中的transform.DOJump(new Vector3(60,0,0),1,5,6);换成transform.DOLocalJump(new Vector3(60,0,0),1,5,6);

19.1.5弹簧冲击

使用的API:DOPunchPosition(位置, 时间, 频率, 对侧弹性);

DOPunchRotation(new Vector3(角度,时间, 频率, 对侧弹性);

transform.DOPunchScale(缩放倍数, 时间, 频率, 对侧弹性);

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        transform.DOPunchPosition(new Vector3(10, 0, 0), 3,10,1);

    }

}

该段代码实现的功能是,使脚本所挂物体用3秒,每秒10次,以最大的弹性的来回弹跳。

如果想实现物体的角度弹簧冲击,可以将上面代码中的transform.DOPunchPosition(new Vector3(10, 0, 0), 3, 10, 1);换成transform.DOPunchRotation(new Vector3(10, 0, 0), 3, 10, 1);

如果想实现物体缩放的弹簧冲击,可以将上面代码中的transform.DOPunchPosition(new Vector3(10, 0, 0), 3, 10, 1);换成transform.DOPunchScale(new Vector3(10, 0, 0), 3, 10, 1);

19.1.6旋转

使用的API:.DOLookAt(旋转的方向,时间);

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        transform.DOLookAt(new Vector3(1,1,1), 2f);

    }

}

该段代码实现的功能是用2秒沿着指定方向自旋转。

19.1.7增量

使用的API:DOBlendableMoveBy(位置增量, 时间);

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        transform.DOBlendableMoveBy(new Vector3(20,0,0), 2f);

    }

}

该段代码的功能是,是脚本所挂物体用2秒在X轴方向的坐标增加20。

如果想实现旋转角度的增量,可以将上面代码transform.DOBlendableMoveBy(new Vector3(20, 0, 0), 2f);换成transform.DOBlendableRotateBy(new Vector3(20, 0, 0), 2f);

如果想实现缩放的增量,可以将上面代码transform.DOBlendableMoveBy(new Vector3(20, 0, 0), 2f);换成transform.DOBlendableScaleBy(new Vector3(20, 0, 0), 2f);

19.2颜色、透明度的控制

19.2.1颜色

使用的API:DOColor(颜色,时间);

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        Material material = GetComponent<MeshRenderer>().material;

        material.DOColor(Color.red, 2f);

    }

}

该段代码的功能是用两2秒将脚本所挂物体变成红色。

该方法也可用于文本和图片颜色的更改。

19.2.2透明度

使用的API:DOFade(透明度,,时间);

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        Material material = GetComponent<MeshRenderer>().material;

        material.DOFade(0, 2f);

    }

}

将脚本所挂物体的Inspector>Shader修改成Lagacy Shader>TransParent>Diffuse,通过上面的代码可以用2秒将脚本所挂物体隐形。

19.2.3颜色渐变

使用的API:

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    public Gradient gradient;

    void Start()

    {

        Material material = GetComponent<MeshRenderer>().material;

        material.DOGradientColor(gradient, 2f);

    }

}

定义了公开变量gradient后,在Unity中Inspector中找到gradient并设置该渐变色,设置完成后运行,该段代码功能是使脚本所挂物体的颜色用2秒渐变。

19.3震动效果表现

19.3.1物体震动

使用的API:DOShakePosition(时间, 振幅,频率,混乱程度);

transform.DOShakeRotation(时间, 角幅度,频率,混乱程度);

transform.DOShakeScale(时间, 大小幅度,频率,混乱程度);

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        transform.DOShakePosition(2f, 1, 10, 90);

    }

}

该段代码实现的功能是,使脚本所挂物体用2秒以1振幅,10振幅,90混乱度的状态震动。

如果想换成方向震动,可以将上述代码中的transform.DOShakePosition(2f, 1, 10, 90);换成transform.DOShakeRotation(2f, 90, 10, 90);

如果想换成大小震动,可以将上述代码中的transform.DOShakePosition(2f, 1, 10, 90);换成transform.DOShakeScale(2f,2, 10, 90);

19.3.2摄像机震动

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        transform.DOShakePosition(2f, 1, 10, 90);

    }

}

定义了摄像机后,将指定摄像机拖入该变量中,通过该段代码可以实现摄像机的震动。

参考上一小节,同理可实现摄像机的角震动。

19.4物体路径动画

使用的API:DOPath(路径,时间,路径类型,路径模式,分辨率,颜色);

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        Vector3[] path = new Vector3[] { new Vector3(1, 2, 1), new Vector3(2, 1, 3), new Vector3(10, 2, 5), new Vector3(4, 9, 6) };

        transform.DOPath(path, 5,PathType.Linear,PathMode.Full3D,10,Color.red);

    }

}

该段代码的功能是,使脚本所挂物体以设置的模式沿路径运动

除了用脚本控制物体运动外,还可以通过Dotween Path组件来控制物体的运动。

19.5动画序列Sequence

19.5.1动画序列

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        Sequence sequence = DOTween.Sequence();

        sequence.Append(transform.DOMoveX(10,1));

        sequence.Insert(0,transform.DOScale(2,1));

        sequence.AppendInterval(2);

        sequence.Append(transform.DOMoveX(0,1));

        sequence.Insert(3,transform.DOScale(1,1));

    }

}

该段代码实现的功能是,用1秒钟使被挂脚本的物体在X轴移动到10的位置,同时大小变为原来的2倍,停顿两秒后,物体X轴的位置变为0,同时大小变回原来的大小。

上面代码中Insert方法也可以用Join方法来实现同样的功能,只需将代码sequence.Insert(0, transform.DOScale(2, 1));换成sequence.Join(transform.DOScale(2, 1));并将sequence.Insert(3,transform.DOScale(1, 1));换成sequence.Join(transform.DOScale(1, 1));即可。

19.5.2方法回调

Append回调:

示例

using DG.Tweening;

using UnityEngine;

 

public class Test : MonoBehaviour

{

    void Start()

    {

        Sequence sequence = DOTween.Sequence();

        sequence.Append(transform.DOMoveX(10,1));

        sequence.Join(transform.DOScale(2,1));

        sequence.AppendCallback(() =>

        {

            Debug.Log("AppendCallback1");

        });

        sequence.Append(transform.DOMoveX(0,1));

        sequence.Join(transform.DOScale(1,1));

        sequence.AppendCallback(() =>

        {

            Debug.Log("AppendCallback2");

        });

    }

}

AppendCallback会在上面的代码执行完后调用。

Insert回调:

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        Sequence sequence = DOTween.Sequence();

        sequence.Append(transform.DOMoveX(10,1));

        sequence.Insert(0,transform.DOScale(2,1));

        sequence.AppendInterval(2);

        sequence.Append(transform.DOMoveX(0,1));

        sequence.Insert(3,transform.DOScale(1,1));

        sequence.InsertCallback(6,() =>

        {

            Debug.Log("InsertCallback2");

        });

    }

}

该段代码会在运行6秒后打印InsertCallback,即InsertCallback的执行时间点只与填写的时间点有关。

19.6动画常用设置以及动画控制

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    Tweener tweener;

    void Start()

    {

        tweener=transform.DOMoveX(10,1).SetEase(Ease.Linear).SetLoops(-1,LoopType.Restart).SetDelay(0).SetAutoKill(true);

    }

    private void onGUI()

    {

        if (GUILayout.Button("暂停"))

        {

            tweener.Pause();

        }

        if (GUILayout.Button("Kill"))

        {

            tweener.Kill();

        }

        if (GUILayout.Button("播放"))

        {

            tweener.Play();

        }

        if (GUILayout.Button("倒回播放"))

        {

            tweener.PlayBackwards();

        }

        if (GUILayout.Button("向前播放"))

        {

            tweener.PlayForward();

        }

        if (GUILayout.Button("重新播放"))

        {

            tweener.Restart();

        }

        if (GUILayout.Button("回到初始位置"))

        {

            tweener.Rewind();

        }

        if (GUILayout.Button("跳转到"))

        {

            tweener.Goto(2);

        }

        if (GUILayout.Button("点击暂停"))

        {

            tweener.TogglePause();

        }

    }

}

该段代码的功能是,设置一段动画,并通过不同的按键来控制动画。(运行问题:游戏页面无法形成控制按钮)

21.各平台打包操作

21.1Windows平台

讲解了Windows平台的打包操作

21.2安卓平台

安卓平台的打包需要先在Hub中安装Android SDK & NDK Tools和Open JDK两个组件。

21.3IOS平台

讲解了IOS平台的打包操作

 

19.7动画的回调

示例

using DG.Tweening;

using UnityEngine;

public class Test : MonoBehaviour

{

    Tweener tweener;

    void Start()

    {

        tweener=transform.DOMoveX(10,1).SetEase(Ease.Linear).SetLoops(-1,LoopType.Restart).SetDelay(0).SetAutoKill(true);

        tweener.OnComplete(() =>

        {

            Debug.Log("OnComplete");

        });

        tweener.OnKill(() =>

        {

            Debug.Log("OnKill");

        });

        tweener.OnPlay(() =>

        {

            Debug.Log("OnPlay");

        });

        tweener.OnStart(() =>

        {

            Debug.Log("OnStart");

        });

        tweener.OnRewind(() =>

        {

            Debug.Log("OnRewind");

        });

        tweener.OnUpdate(() =>

        {

            Debug.Log("OnUpdate");

        });

        tweener.OnPause(() =>

        {

            Debug.Log("OnPause");

        });

    }

}

该段代码的功能是根据动画运行时的不同状态打印相应的提示。

 

20.EasyTouch手势插件

20.1手势监测之初级使用

示例

using HedgehogTeam.EasyTouch;

using UnityEngine;

public class Test : MonoBehaviour

{

    void Update()

    {

        Gesture gesture = EasyTouch.current;

        if (gesture != null)

        {

            if (EasyTouch.EvtType.On_TouchStart == gesture.type)

            {

                OnTouchStart(gesture);

            }

            else if (EasyTouch.EvtType.On_Drag == gesture.type)

            {

                OnDragStart(gesture);

            }

        }

    }

    private void OnTouchStart(Gesture gesture)

    {

        Debug.Log(gesture.type);

    }

    private void OnDragStart(Gesture gesture)

    {

        Debug.Log(gesture.type);

    }

}

上述代码的功能是,当运行时鼠标点击或者拖拽被挂脚本物体,控制台打印相关信息。

20.2手势监测之使用QuickGesture以及Trigger

20.2.1QuickGesture类组件

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    public void Log(string str)

    {

        Debug.Log(str);

    }

}

新建一个空物体,讲脚本挂入空物体中,然后将空物体挂入待操作物体的Quick Drag,Quick Tap,Quick Touch,Quick Pinch等组件中,设置相关输出内容,在运行时进行对物体进行操作后,会输出相关内容。

20.2.2Trigger组件

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    public void Log(int str)

    {

        Debug.Log(str);

    }

}

将含该代码的脚本挂入待操作物体上,并在待操作物体上加入Trigger组件,选择Add new event>On_Touch Start,将Mothed name改成Log,将Parameter to send改为Touch_Count,在运行时将对物体的操作信息通过控制台打印。

20.3组件核心参数

讲解了Easy Touch组件

 

20.4JoyStick虚拟摇杆

讲解了ETCJoystick组件

 

22.各平台调试技术

22.1常见的异常

22.1.1空指针导致的异常

空指针异常可以分为未指定引用对象(包括未指定和未分配对象),和指定的路径错误(包括查找物体和查找资源)两类。

22.1.2数据结构错误

包括重复添加相同的Key和索引出现异常。

22.2编辑器模式下的日志功能

日志的三种类型:

普通日志:Debug.Log("普通日志");

警告日志:Debug.LogWarning("警告日志");

错误日志:Debug.LogError("错误日志");

22.3安卓平台下的日志跟踪

分为Unity本身的调试和AndroidStudio调试。

22.4IOS调试日志查看

讲解了IOS平台下的日志查看。

22.5断点调试和调用堆栈

22.5.1断点调试

在一些代码前面加入断点,点击附加到Unity,在Unity中点击播放,返回Visual Studio中查看相关代码的值。

22.5.2调用堆栈

在Visual Studio中操作

 

23.其他知识

23.1生成随机数

示例

using UnityEngine;

public class Test : MonoBehaviour

{

    void Start()

    {

        for(int i = 0; i < 10; i++)

        {

            Debug.Log(Random.Range(0,8));

        }

    }

}

该段代码的功能是在运行时控制台随机打印10个0~7之间的随机数。

 

23.2协程方法

示例1

using System.Collections;

using UnityEngine;

 

public class Test : MonoBehaviour

{

    private void Start()

    {

        StartCoroutine(MyCoroutine(2, "success"));

    }

    IEnumerator MyCoroutine(int i, string str)

    {

        Debug.Log(i);

        yield return new WaitForSeconds(5f);

        Debug.Log(str);      // 打印i的5s后执行

        yield return new WaitForSeconds(5f);

        Debug.Log("123");    // 打印str的5s后执行

    }

}

该段代码的功能是间隔一定时间打印内容。

示例2

using System.Collections;

using UnityEngine;

 

public class Test : MonoBehaviour

{

    private void Start()

    {

        StartCoroutine(MyCoroutine(2));

    }

    IEnumerator MyCoroutine(int i)

    {

        while (true)

        {

            yield return new WaitForSeconds(1);

            Debug.Log(i);

        }

    }

}

该段代码的作用是每过1秒打印一次数字2.

 

23.3调用方法

示例1

using UnityEngine;

 

public class Test : MonoBehaviour

{

    private void Start()

    {

        Invoke("Bigger",2);

    }

    void Bigger()

    {

        transform.localScale = new Vector3(2, 2, 2);

    }

}

该代码的作用是使脚本所挂物体在2秒后变为原来的2倍。

示例2

using UnityEngine;

 

public class Test : MonoBehaviour

{

    private void Start()

    {

        InvokeRepeating("Bigger",2,1);

    }

    void Bigger()

    {

        transform.localScale += new Vector3(1, 1, 1);

    }

}

该代码的作用是使脚本所挂物体2秒后增大1倍,然后每1秒增大1倍。

示例3

using UnityEngine;

 

public class Test : MonoBehaviour

{

    private void Start()

    {

        InvokeRepeating("Fuse", 0.01f,0.01f);

    }

    private void Fuse()

    {

        transform.Translate(new Vector3(0.02f, 0.02f, 0.02f));

    }

    private void Update()

    {

        if (Input.GetMouseButtonDown(0))

        {

            CancelInvoke();

        }

    }

}

该段代码的功能是,使物体持续朝一个方向运动,在按下鼠标左键后停止运动。

 

23.3触发器

示例

using UnityEngine;

public class zidan : MonoBehaviour

{

    void OntriggerEnter(Collider coll)

    {

        if (coll.name == "Cube")

        {

            //transform.position  生成一个特效到这个位置上

            Destroy(transform.gameObject);

        }

        else if (coll.name == "xiaonuhai")

        {

            //transform.position  生成一个别的特效到这个位置上

            Destroy(transform.gameObject);//打中小女孩后,销毁子弹

            Destroy(coll.gameObject);//打中小女孩后,销毁小女孩

        }

    }

}

23.5按键控制程序退出

示例

using UnityEngine;

using UnityEngine.UI;

 

public class Exit : MonoBehaviour

{

    void Start()

    {

        transform.GetComponent<Button>().onClick.AddListener(() => { DoExit(); });

    }

    void DoExit()

    {

        UnityEditor.EditorApplication.isPlaying= false;

        Application.Quit();

    }

}

上述代码的功能是,当按键被按下时,退出游戏。

23.6Text中显示时间

示例

using System;

using UnityEngine;

using UnityEngine.UI;

 

public class ShowTime : MonoBehaviour

{

    public Text time1;

    void Update()

    {

        DateTime nowTime=DateTime.Now.ToLocalTime();

        time1.text = nowTime.ToString("yyyy-MM-dd HH:mm:ss");

    }

}

上述代码可以实现在Text中显示实时时间。

23.7Text字体隐形显现转换

示例

using DG.Tweening;

using UnityEngine;

using UnityEngine.UI;

 

public class FlashWord : MonoBehaviour

{

    private void Start()

    {

        Pingpong(1, 0, 0.6f);

    }

    void Pingpong(float fromValue, float toValue, float duration)

    {

        Color temColor = gameObject.GetComponent<Text>().color;

        temColor.a = fromValue;

        Tweener tweener = DOTween.ToAlpha(() => temColor, x => temColor = x, toValue, duration);

        tweener.onUpdate = () => { gameObject.GetComponent<Text>().color = temColor; };

        tweener.onComplete = () =>

        {

            Pingpong(toValue, fromValue, duration);

        };

    }

}

上述代码可以实现将字体的显隐变换效果,将<Text>改为<Image>可以实现图片的显隐效果。

23.8关闭程序

示例

using UnityEngine;

using UnityEngine.UI;

 

public class Exit : MonoBehaviour

{

    void Start()

    {

        transform.GetComponent<Button>().onClick.AddListener(() => { DoExit(); });

    }

    void DoExit()

    {

       // UnityEditor.EditorApplication.isPlaying= false;

        Application.Quit();

    }

}

上述代码可以实现点击按键关闭程序。“//”后的代码加上后可以实现在编辑器模式下的关闭效果,但加上后无法打包成安卓应用。

23.9实现UI圆点跟随运动

示例

using System.Collections;

using DG.Tweening;

using UnityEngine;

 

public class AfterScanDotsMove : MonoBehaviour

{

    public Transform[] Dots;

    Vector3[] tempvec3;

    void Start()

    {

        tempvec3 = new Vector3[Dots.Length];

        StartCoroutine(DotsMove());

    }

    IEnumerator DotsMove()

    {

        while (true)

        {

            for (int i = 0; i < Dots.Length; i++)

            {

                tempvec3[i] = Dots[i].position;

            }

 

            for (int i = 0; i < Dots.Length; i++)

            {

                if (i < Dots.Length - 1)

                {

                    Dots[i].transform.DOMove(tempvec3[i + 1], 0.5f).SetEase(Ease.Linear);

                }

                else

                {

                    Dots[i].transform.DOMove(tempvec3[0], 0.5f).SetEase(Ease.Linear);

                }

            }

            yield return new WaitForSeconds(0.5f);

        }

    }

}

该代码可以实现小圆点的跟随运动。

23.10全局变量

//该脚本不用挂载,内数据不会随场景变化而变化

public class storeData

{

    public static int countData = 0;

}

//其他脚本可以使用这个数据

if (storeData.countData ==0)  

23.11单例(一个脚本调另一个脚本里的变量或方法)

示例

//待调用的代码

using UnityEngine;

 

public class Juse : MonoBehaviour

{

public static Juse m_Instance;

    void Start()

    {

        m_Instance = this;

}

public void OpenPage()

{

//待调用的方法

}

}

//调用的代码

using UnityEngine;

 

public class TimeShow : MonoBehaviour

{

    void Start()

    {

        Juse.m_Instance.OpenPage();

    }

}

23.12SendMessenger方法调用

示例

//待调用的脚本代码

using UnityEngine;

 

public class TakeMess : MonoBehaviour

{

    public void DebugWord(string str)

    {

        Debug.Log(str);

    }

}

//调用的脚本代码

using UnityEngine;

 

public class SendMess : MonoBehaviour

{

    void Start()

    {

        GameObject.Find("Cube").SendMessage("DebugWord", "juse");

    }

}

该代码可以调用Cube物体上的DebugWord方法,并传递相关参数。

若想调用自身及子物体上的方法,可以用BroadcastMessage( );

若想调用自身及父物体上的方法,可以用SendMessageUpwards( );

23.13List使用

List也叫列表,

23.14Dictionary使用

Dictionary也叫字典。

 

23.15Event Trigger组件

通过Event Trigger组件来控制鼠标的事件

 

23.16UI小窗口显示

再UI界面建一个Row Image,Hierarchy上新建一个摄像机,Project上新建一个Render Texture,将Render Texture分别挂在摄像机和Row Image上,就可以在Row Image上显示摄像机摄的东西。

 

23.17AssetBundle

1.打包

将要打包的资源在inspector中的预览窗口下设置要打包在AssetBundles下的路径和后缀名(可任意取)。新建一个C#脚本,脚本内容如下:

using System.IO;

using UnityEditor;

 

public class CreateAssetBundles 

{

    [MenuItem("Assets/Build AssetBundles")]//生成菜单目录

    static void BuildAllAssetBundles()

    {

        string assetBundleDirectory = "Assets/AssetBundles";//指定AssetBundles文件夹的目录

        if (!Directory.Exists(assetBundleDirectory))

        {

            Directory.CreateDirectory(assetBundleDirectory);//如果没有,则创建文件夹

        }

        BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.None,BuildTarget.StandaloneWindows);

    }

}

脚本无需挂载,在菜单Assets下点击新创建的Build AssetBundles,即可在指定文件夹创建AssetBundle.

2.读取

场景中物体上挂载一个脚本,脚本代码如下:

using UnityEngine;

 

public class LoadAssetBundle : MonoBehaviour

{

    void Start()

    {

        AssetBundle bundle = AssetBundle.LoadFromFile("Assets/AssetBundles/this/wall.ab");//找到AB包

        GameObject cubeWall = bundle.LoadAsset<GameObject>("CubeWall");//找到AB包中的物体

        Instantiate(cubeWall);//实例化物体

    }

}

运行后即可实例化物体。

 

标签:UnityEngine,入门,void,transform,笔记,物体,using,public
From: https://www.cnblogs.com/gatran/p/17205581.html

相关文章

  • 我的c语言笔记
    1.进制转换二进制、八进制和十六进制向十进制转换都非常容易,就是“按权相加”。如:1010.1101=1×23 +0×22 +1×21 +0×20 +1×2-1 +1×2-2 +0×2-3 +1......
  • Java应用【XIX】Redis入门
    如果您觉得本博客的内容对您有所帮助或启发,请关注我的博客,以便第一时间获取最新技术文章和教程。同时,也欢迎您在评论区留言,分享想法和建议。谢谢支持!一、简介1.1Redis是什......
  • 入门Android 四大开发组件学习
    一、Activity组件1、Activity相关概念介绍        一个Activity包含了用户能够看到的界面,从而于用户进行交互。一个应用程序中可以有零个或者多个Activity。零个......
  • Shader 入门:GLSL ES(数据类型)
    在上一篇文章中我们初步了解了GLSLES的基本语法,那么本篇文章就和大家一起学习GLSLES的数据类型。Let’sgo!!!上一篇:《Shader入门:GLSLES(简介和基本语法)》在本系......
  • 跟艾文学编程《零基础入门学Python》PyCharm 安装
    作者:艾文,计算机硕士学位,企业内训讲师和金牌面试官,公司资深算法专家,现就职BAT一线大厂。学习目标PyCharm下载PyCharm工具的使用利用PyCharm工具开发第一个应用程序PyChar......
  • 新概念2册L55笔记(定语从句_关系副词、of+n.=adj.)
    L55notagoldmineInspiteofthis,manypeopleareconfidentthat'TheRevealer’mayrevealsomethingofvaluefairlysoon.ofvalue=ofn.=adj.单词理解课......
  • 操作系统学习笔记2-进程和线程
    2.进程和线程2.0引入2.0.1顺序执行特征顺序性封闭性:独占整机资源可再现性:只要在相同的环境与初始条件下,执行结果相同顺序执行的场合:单道批处理系统2.0.2并......
  • MacOS 苹果笔记本使用ClashX下载安装配置教程
    一、ClashX简介ClashX是运行在macOS上的一款科学上网工具。支持的协议: Vmess,Shadowsocks,Snell,SOCKS5,ClashX现已支持SSR协议。ClashX可随时切换代理模式及节......
  • 算法学习笔记(18): 平衡树(一)
    平衡树建议在清楚二叉搜索树的所有操作之后食用本文。本文将略过部分基础知识目录平衡树Treap旋转插入删除其他操作FHQ-Treap分裂合并其他操作Splay旋转伸展其他操作WB......
  • 笔记14
    考试十五分钟:1、编写代码实现功能tail-faccess.logf.seek()应用程序(文件对象/文件句柄1)应用程序(文件对象/文件句柄2)操作系统(真正的文......