Getting started with Unity (1)

Unity

Unity is a set of cross-platform game development tools with a complete system and editor, which can also be called a game engine. A game engine refers to some well-written codes that can be reused and various functional editors used to develop games.

  • Based on C# programming, easy to use, high security
  • Unique component-oriented game development ideas make game development easier and easier to reuse
  • Very mature WYSIWYG development editor
  • good ecosystem
  • Powerful cross-platform, can make PC, host, mobile phone, AR, VR and other multi-platform games

Download and install

In the Chinese website https://unity.cn/releases

Just download Unity Hub.

insert image description here

After downloading, click to enter the software, and then select Unity Editorthe installation address to wait for the download and installation.

insert image description here

Chinese language is optional. The setting button in the above figure, after clicking

insert image description here

After completion, you still need to remember to apply for a license before you can use it, the personal version is fine.

Install an LTS version of the editor

insert image description here

Check the development tools of visual studio, if there is, you don’t need to install it again

insert image description here

After finishing, create a project, and then explore the function menu in it. .

model store

insert image description here

Just find the material you need for the subset on the page

insert image description here

Script Lifecycle

Create a C# script in unity

insert image description here

Enter vs editor

public class Test : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

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

Contains two methods, start() and Update(), while other life cycle methods

  • Awake(): The earliest call, generally implementing the singleton mode here
  • OnEnable(): It will be called after the component is activated, and it will be called once after Awake()
  • Start(): Called once before Update() and after OnEnable(), you can set some initial values ​​here
  • FixedUpdate(): The method is called at a fixed frequency, and the time interval between each call and the last call is the same
  • Update(): The frame rate call method, called once per frame, and the time interval between each call and the last call is different
  • LateUpdate(): Called immediately after each call to Update()
  • OnDisable(): Contrary to OnEnable(), it is called when the component is not activated
  • OnDestory(): Called once after being destroyed

OnEnable和OnDisable()的触发

insert image description here

Update()和LateUpdate()

When the program starts to execute, the Update() method will be called every frame, and after Update() is executed, LateUpdate() will be executed once.

insert image description here

FixedUpdate()

How many frames per second, how many times this method is called

OnDestory()

OnDestory() is called when the object's components are removed or when the program ends.

script execution order

insert image description here

When two scripts are added to an object, their execution order runs from bottom to top, and it will be executed 全部脚本firstAwake()、OnEnable()、Start()...

Then, we can implement the script method that is executed first and put it into the method with the highest priority in the life cycle.

Alternatively, we can set the order of execution for the scripts:

insert image description here

insert image description here

After setting, its execution sequence is: first execute Awake() of Test1, then execute Awake() of Test2, then execute Start() of Test1, execute Start() of Test2;

objects to mark

Tag objects for easy classification and easy search.

insert image description here

When you can't find the tag you want, you can create some custom tags for use.

There is also the Layer layer, which can be distinguished in a larger way, such as distinguishing between characters and scenes, etc., and the Layer layer can be used to distinguish.

Characters can be divided into players and enemies, and then subdivided into Tag tags.

insert image description here

In the camera object, you can set the layer to be captured.

insert image description here

The layer after ticking off will not be displayed in the actual camera shooting.

vector

scalar: a quantity with only magnitude

Vector: Both magnitude and direction.

Vector touch: the size of the vector

Unit vector: a vector of size 1

Unitization, normalization: the process of converting a vector into a unit vector.

点乘:得到两个向量之间的夹角:A向量*B向量=x1*x2+y1*y2=cosθ, and this θ is the value of point multiplication (degrees)

Prefabs and variants

insert image description here

When adding a component to the preset, the objects in the scene will also be added automatically, but when adding a component to the object in the scene, it is a unique component of the object in the scene and can be added to the preset.

insert image description here

In the property bar of the scene object, the newly added components are blue.

From the scene object, add to the prefab

insert image description here

When done, the blue fringe will disappear.

Note that files with the suffix prefab are prefabs, which can be exported for others to use, or imported into your own projects for use.

If the prefab needs to show a different prefab again, you can use the superposition on the basis of the original prefab, then when the original prefab changes, the new prefab changes accordingly

insert image description here

Use of Vector3

Create a C# script, in the start() method

public class VectorTest : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        // 向量
        Vector3 v = Vector3.right;
        Vector3 v2 = Vector3.forward;

        // 计算两点之间的角度
        Debug.Log(Vector3.Angle(v, v2));
        // 计算两点之间的距离
        Debug.Log(Vector3.Distance(v, v2));
        // 点乘
        Debug.Log(Vector3.Dot(v, v2));
        // 叉乘
        Debug.Log(Vector3.Cross(v, v2));

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

Orientation description, Euler angles and quaternions

common method

public class RotateTest : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        // 旋转:欧拉角,四元数
        Vector3 rotate = new Vector3(0, 30, 0);

        // 方法一:无旋转的四元数
        Quaternion quaternion = Quaternion.identity;
        // 方法二:通过欧拉角创建的四元数
        quaternion = Quaternion.Euler(rotate);

        // 看向一个物体
        quaternion = Quaternion.LookRotation(new Vector3(0,0,0))

        // 通过四元素转为欧拉角
        rotate = quaternion.eulerAngles;

    }

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

Debug

During development, you may encounter situations that require debugging.

public class DebugTest : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Debug.Log("test");
        Debug.LogWarning("test2");
        Debug.LogError("test3");

    }

    // Update is called once per frame
    void Update()
    {
        // 画一条直线,起点和终点
        Debug.DrawLine(new Vector3(1,0,0), new Vector3(1,1,0), Color.blue);

        // 画一条射线  起点,射线
        Debug.DrawRay(new Vector3(1,0,0), new Vector3(1,1,0), Color.red);
        
    }
}

insert image description here

Dynamic modification of object properties, use of object classes

We need to get the game object mounted by the current script.

After binding the script to the object, the script will automatically get the object instance and put it into gameObjectthe object .

// 此脚本会自动获取到游戏物体
// GameObject go = this.gameObject;
// 游戏物体的名称
Debug.Log(gameObject.name);
// 游戏标签
Debug.Log(gameObject.tag);
// 图层 , 注意这里返回的是索引值 0是default层
Debug.Log(gameObject.layer);

When there are child objects in the object, you need to declare the variable of the child object in the script, and then set the game variable of the child object in the parent object.

public class EmptyTest : MonoBehaviour
{
    public GameObject cube;
    // Start is called before the first frame update
    void Start()
    {
        // 此脚本会自动获取到游戏物体
        // GameObject go = this.gameObject;
        // 游戏物体的名称
        Debug.Log(gameObject.name);
        // 游戏标签
        Debug.Log(gameObject.tag);
        // 图层 , 注意这里返回的是索引值 0是default层
        Debug.Log(gameObject.layer);

         // 立方体名称
        Debug.Log(cube.name);
    }

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

A cube GameObject object is created above. Then set the value.

insert image description here

Get the activation state of an object

// 当前真正的激活状态(跟父物体的状态有关系)
Debug.Log(cube.activeInHierarchy);
// 当前自身物体的激活状态
Debug.Log(cube.activeSelf);

Get the components of an object

Just like the object, when the script is bound to the object (object), it will automatically get the various components of the object, just call this. directly.

// 获取物体的transform组件
Debug.Log(transform.position);

// 获取其他的组件
BoxCollider bc = GetComponent<BoxCollider>();
// 获取当前物体的子物体身上的某个组件
// GetComponentInChildren<CapsuleCollider>(bc);
// 获取当前物体的父物体身上的某个组件
// GetComponentInParent<BoxCollider>();

// 手动代码添加组件
gameObject.AddComponent<AudioSource>();

Obtain objects by other means

// 通过游戏物体的名称获取游戏物体
GameObject test = GameObject.Find("Test");
Debug.Log(test.name);

// 通过标签获取物体
test = GameObject.FindWithTag("Enemy");
// 设置游戏物体不可用
test.setActive(false);

Presets dynamically generate entities

First set a variable of the preset body in the script, and then bind the preset body object in the object.

insert image description here

public class EmptyTest : MonoBehaviour
{
    public GameObject cube;
    public GameObject Prefab;
    // Start is called before the first frame update
    void Start()
    {
        // 使用预设体动态生成物体,会返回一个GameObject对象
        Instantiate(Prefab);

    }

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

use of game time

Create an object, bind the script, and use the game time count in the script

public class TimeTest : MonoBehaviour
{
    // Start is called before the first frame update
    float timer = 0;
    void Start()
    {
        // 游戏开始到现在所花的时间
        Debug.Log(Time.time);
        // 时间缩放值(时间倍速)
        Debug.Log(Time.timeScale);
        // 固定时间间隔(每一帧之间的间隔时间数)
        Debug.Log(Time.fixedDeltaTime);

    }

    // Update is called once per frame
    void Update()
    {
        // timer可以用来计数游戏总时间
        timer += Time.deltaTime;
        // 上一帧到这一帧所用的游戏时间
        Debug.Log(Time.deltaTime);
        // 如果总时间 > 3s,我可以做一些事情
        if (timer > 3)
        {
            
        }
    }
}

To clarify the path authority, Application is very important

If a new a.txt file is created in Project, how to read it in the code

insert image description here

public class ApplicationTest : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        // s游戏数据文件夹路径(只读的,打包后加密压缩,所以看不到)
        Debug.Log(Application.dataPath +"/a.txt");

        // 持久化文件夹路径(可写的)
        Debug.Log(Application.persistentDataPath);

        // StreamingAssets文件夹路径(只读,打包后不会加密压缩,这些文件可以放入此目录下,可以自己创建一个StreamingAssets的目录)
        Debug.Log(Application.streamingAssetsPath);

        // 临时文件夹,可以将临时数据写入
        Debug.Log(Application.temporaryCachePath);

        // 控制是否在后台运行
        Debug.Log(Application.runInBackground);

        // 用浏览器打开一个URL
        Application.OpenURL("www.baidu.com");

        // 退出游戏
        Application.Quit();
        
    }

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

insert image description here

switch scene

Create a new scene in the scenes of Assets

insert image description here

Then put these two scenes into the packaged scene, and it will have an index

insert image description here

Jump to MyScene in the SampleScene scene

using UnityEngine.SceneManagement;

public class SceneTest : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
        // 场景跳转,可以根据名称或索引进行跳转
        // SceneManager.LoadScene(1);
        // Additive:多场景叠加
        // Single:单场景
        SceneManager.LoadScene("MyScene", LoadSceneMode.Additive);

        // 获取当前场景
        Scene scene = SceneManager.GetActiveScene();
        // 场景名
        Debug.Log(scene.name);
        // 场景路径
        Debug.Log(scene.path);
        // 场景是否已经被加载
        Debug.Log(scene.isLoaded);
        // 场景索引
        Debug.Log(scene.buildIndex);
        // 获取场景中的所有游戏对象(根级别的)
        GameObject[] gos = scene.GetRootGameObjects();
        Debug.Log(gos.Length);

        // 场景管理类
        // 创建新场景
        Scene newScene = SceneManager.CreateScene("newScene");
        // 已加载场景的数量
        Debug.Log(SceneManager.sceneCount);
        // 卸载场景
        SceneManager.UnloadSceneAsync(newScene);
        
    }

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

Asynchronously load the scene to get the progress

using UnityEngine.SceneManagement;

public class SceneTest : MonoBehaviour
{

    AsyncOperation operation;
    // Start is called before the first frame update
    void Start()
    {
        StartCoroutine(loadScene());

    }

    // 协程方法用来异步加载场景
    IEnumerator loadScene() {
        operation = SceneManager.LoadSceneAsync(1);
        // 让用户手动跳转场景
        operation.allowSceneActivation = false;
        yield return operation;
    }
    float timer = 0;

    // Update is called once per frame
    void Update()
    {
        // 每一帧都记录 加载的进度 值范围 0-0.9
        Debug.Log(operation.progress);
        timer += Time.deltaTime;
        // 5s后跳转
        if (timer > 5)
        {
            operation.allowSceneActivation = true;
        }
    }
}

understand transform

The parent-child relationship of game objects is controlled by transform.

Create several objects with a three-layer relationship, and then bind the script code on the middle layer

insert image description here

Common attributes:

// 获取世界位置
Debug.Log(transform.position);
// 获取相对位置(相对于父物体)
Debug.Log(transform.localPosition);

// 获取世界旋转、
Debug.Log(transform.rotation);
// 获取相对旋转
Debug.Log(transform.localRotation);

// 获取世界欧拉角
Debug.Log(transform.eulerAngles);
// 获取相对欧拉角
Debug.Log(transform.localEulerAngles);

// 获取相对缩放
Debug.Log(transform.localScale);

// 获取向量
Debug.Log(transform.forward);
Debug.Log(transform.right);
Debug.Log(transform.up);

Common methods:

movement, angle

// 时刻看向 000点
transform.LookAt(Vector3.zero);

// 旋转 相对于local旋转
transform.Rotate(Vector3.up, 1);

// 绕物体旋转  绕着(0,0,0)的up轴,每一帧转5度
transform.RotateAround(Vector3.zero, Vector3.up, 5);

// 移动 每一帧移动0.1
transform.Translate(Vector3.forward * 0.1f);

Parent-child relationship:

// 获取父物体
transform.parent.gameObject;

// 获取子物体的数量
transform.childCount;

// 解除与子物体的父子关系
transform.DetachChildren();

// 获取子物体
// 方式一 通过子物体的名称获取子物体的transform
Transform trans = transform.Find("Child")
// 方式二 通过子物体的索引获取子物体的transform
trans = transform.GetChild(0);

// 判断物体是不是另一个物体的子物体
bool res = trans.IsChildOf(transform);
Debug.Log(res);

// 设置为父物体
trans.SetParent(transform);

Basic keyboard and mouse operation

Keyboard and mouse operations must be monitored in Update(), and each frame must be detected.

void Update()
{
    // 鼠标操作

    // 按下鼠标 0:左键 1:右键 2:滚轮
    if (Input.GetMouseButtonDown(0))
    {
        Debug.Log("按下了鼠标左键");
    }

    // 持续按下鼠标左键
    if (Input.GetMouseButton(0))
    {
        Debug.Log("持续按下鼠标左键");
    }

    // 抬起鼠标左键
    if (Input.GetMouseButtonUp(0))
    {
        Debug.Log("抬起鼠标左键");
    }
    

    // 按下键盘按键
    if (Input.GetKeyDown(KeyCode.A)) 
    {
        Debug.Log("按下了A");
    }
    // 持续按下键盘按键
    if (Input.GetKey(KeyCode.A)) 
    {
        Debug.Log("持续按下了A");
    }
    // 抬起键盘按键
    if (Input.GetKeyUp(KeyCode.A)) 
    {
        Debug.Log("抬起按键A");
    }

}

Guess you like

Origin blog.csdn.net/weixin_45248492/article/details/130373222