Unity学习part1
课程为b站【Unity教程】零基础带你从小白到超神
1、脚本执行顺序
unity的脚本执行顺序不像blender的修改器那样按顺序执行,而是系统默认给配置一个值,值越小,执行顺序越靠前(注意,这个顺序是全局生效的)
2、初始化内容
脚本要初始化的内容放在awake函数中,onenable是可以反复调用的。unity中执行顺序是先调用所有脚本的awake完后,在按脚本执行顺序调用其他脚本中的onenable等函数
3、标签与图层
图层用于碰撞检测,例如将一组物体图层设置为CHARACTER,这样可以让相机在剔除遮罩时,选择CHARACTER图层不进行拍摄,使物体在玩家眼中隐形。可以理解为:标签是开发者给物体分组便于理解的,例如将物体分为敌人,玩家等;而图层是显示分类,给相机使用的
4、预设体
prefab是预设体资产。如果物体变蓝,说明它是与某个预设体相关。物体可以拖到项目栏中生成预设体资产。预设体资产与游戏中物体相当于类与实例的关系,但游戏资产自行更改数值之后,预设体资产的改动就不会影响到游戏体。物体上修改了并且没有将修改应用到预制体上,预制体无法对对应的参数进行修改,即关于此参数,预制体与游戏物体脱钩。
如果需要游戏资产的更改能够影响到预设体,则需要通过打开按钮进行修改(保证游戏物体与预制体参数的关联)
或者通过应用到预制件来进行修改(保证游戏物体与预制体参数的关联)
游戏物体添加组件时,组件会显示一个+号,代表预制体资产里没有。可以通过感叹号右键或者覆盖按钮来应用到预制体组件
预制体变体与预制体资产之间才是继承关系,即预制体修改,预制体变体随之修改。而预制体变体修改,预制体不会变化。并且预制体变体和预制件之间不存在应用关系
5、vector3
向量vector3可以代表向量、坐标、缩放、旋转
6、四元数与欧拉角的转换
Vector3 rotate = new Vector3(0,30,0);
Quaternion quaternion = Quaternion.identity;
// 欧拉角转换为四元数
quaternion = Quaternion.Euler(rotate);
//四元数转换为欧拉角
rotate = quaternion.eulerAngles;
//看向一个物体
quaternion = Quaternion.LookRotation(rotate);
7、DEBUG方法
打印日志
Debug.LogWarning("");
Debug.Log("");
Debug.LogError("");
画一条线
// (起点,终点,颜色)
Debug.DrawLine(Vector3.zero,Vector3.one);
画一条射线,并区分线与射线的区别
8、物体的激活状态
public class test2 : MonoBehaviour
{
public GameObject cube2;
// Start is called before the first frame update
void Start()
{
//立方体的名称
Debug.Log(cube2.name);
//当前真正的激活状态
Debug.Log(cube2.activeInHierarchy);
//当前自身激活状态
Debug.Log(cube2.activeSelf);
}
// Update is called once per frame
void Update()
{
}
}
public class test2 : MonoBehaviour
{
public GameObject cube2;
//获取预设体
public GameObject preFab;
// Start is called before the first frame update
void Start()
{
//立方体的名称
Debug.Log(cube2.name);
//当前真正的激活状态
Debug.Log(cube2.activeInHierarchy);
//当前自身激活状态
Debug.Log(cube2.activeSelf);
//获取transform组件
Transform trans = this.transform;
Debug.Log(transform.position);
//获取其他组件
BoxCollider bc = GetComponent<BoxCollider>();
//获取当前物体子物体身上的某个组件
GetComponentInChildren<CapsuleCollider>();
//获取当前物体父物体身上的某个组件
GetComponentInParent<BoxCollider>();
//给当前物体添加一个组件
gameObject.AddComponent<AudioSource>();
//给特定物体添加组件
cube2.AddComponent<AudioSource>();
//通过游戏物体的名称获取游戏物体
GameObject test = GameObject.Find("Test");
Debug.Log(test.name);
Debug.Log("11111");
//通过游戏标签获取游戏物体
GameObject[] test2 = GameObject.FindGameObjectsWithTag("Enemy");
// 设置激活状态
test2[0].SetActive(false);
Debug.Log(test2[0].name);
//通过预设体资产来实例化一个物体
Instantiate(preFab);
//生成的游戏物体可以被当成当前物体的子物体
Instantiate(preFab, this.transform);
//实例化一个物体并放置在固定位置并作旋转
//GameObject go =Instantiate(preFab,Vector3.zero, Quaternion.identity);
//销毁
//Destroy(go);
}
// Update is called once per frame
void Update()
{
}
}
9、时间类
public class TimeTest : MonoBehaviour
{
float timer = 0;
// Start is called before the first frame update
void Start()
{
//游戏开始到现在所花的时间
Debug.Log(Time.time);
//时间缩放值 游戏的加速减速暂停等功能
Debug.Log(Time.timeScale);
//固定时间间隔 与FixUpdate()函数相关
Debug.Log(Time.fixedDeltaTime);
//上一帧到这一帧所用的游戏时间
Debug.Log(Time.deltaTime);
}
//60帧 1/60 120帧 1/120
// Update is called once per frame
void Update()
{
//相当于一个计时器,将每一帧帧运行时间相加.作用-->旅行者,请在3秒内开启宝箱
timer = timer + Time.deltaTime;
//上一帧到这一帧所用的游戏时间,可用来帧率测试
//Debug.Log(Time.deltaTime);
//如果大于十秒
if (timer > 3)
{
Debug.Log("> 3");
}
}
}
10、Application类的常用属性方法
public class ApplicationTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
//游戏数据文件夹路径(只读,加密压缩)
Debug.Log(Application.dataPath);
//持久化文件夹路径,对应不同系统(MAC,WINDOWS,LINUX)。游戏存档存放位置
Debug.Log(Application.persistentDataPath);
//StreamingAssets文件夹路径,需手动建立该文件夹。(只读,不加密,放游戏的配置文件或一些不需要加密的二进制文件,所有人可看)
Debug.Log(Application.streamingAssetsPath);
//临时文件夹
Debug.Log(Application.temporaryCachePath);
//控制是否在后台运行
Debug.Log(Application.runInBackground);
//打开url
Application.OpenURL("https://www.bilibili.com/");
//退出游戏
Application.Quit();
}
// Update is called once per frame
void Update()
{
}
}
垃圾window还是默认我工程项目放在appdata下,得想个法子改一下,不然c盘逐渐增加
11、加载场景(同步)
public class SceneTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
//两个类 场景类、场景管理类
// SceneManager.LoadScene(1);//通过索引
//SceneManager.LoadScene("MyScene"); //通过名称
//获取当前场景
Scene scene = SceneManager.GetActiveScene();
//场景名称
Debug.Log(scene.name);
//场景是否已经被加载
Debug.Log(scene.isLoaded);
//场景路径
Debug.Log(scene.path);
//场景索引
Debug.Log(scene.buildIndex);
//获取场景中所有的根游戏物体
GameObject[] objects = scene.GetRootGameObjects();
Debug.Log(objects.Length);
//场景管理类
//当前加载的活动场景数量
Debug.Log(SceneManager.sceneCount);
//创建新场景,场景同一个时间并不是只能存在一个 是可以同时存在的,可以用于时空关卡切换,关卡叠加
Scene scene1 = SceneManager.CreateScene("newScene");
Debug.Log("创建场景");
//已加载场景个数
Debug.Log(SceneManager.sceneCount);
//卸载场景
SceneManager.UnloadSceneAsync(scene1);
Debug.Log("卸载场景");
Debug.Log(SceneManager.sceneCount);
//加载场景
//SceneManager.LoadScene("MyScene",LoadSceneMode.Single); //替换形式加载
SceneManager.LoadScene("MyScene", LoadSceneMode.Additive);//加载出的场景与原本场景融合在一起。场景大的会可能会造成卡顿
}
// Update is called once per frame
void Update()
{
}
}
12、加载场景(异步)
异步 c#通过多线程实现的;而unity还提供了协程的方式来实现异步
public class AsyncTest : MonoBehaviour
{
AsyncOperation op1;
// Start is called before the first frame update
void Start()
{
//协程需要使用StartCoroutine方法
StartCoroutine(loadScene());
Debug.Log("加载完成");
}
//携程方法用来异步加载场景
IEnumerator loadScene()
{
op1 = SceneManager.LoadSceneAsync(1);
// 加载完场景不要自动跳转,让玩家手动确认再跳转
op1.allowSceneActivation = false;
yield return op1;
}
float timer = 0;
// Update is called once per frame
void Update()
{
//输出加载进度 数值范围为0-0.9
Debug.Log(op1.progress);
timer += Time.deltaTime;
if (timer > 5)
{
op1.allowSceneActivation = true;
}
}
}
可以看到,MyScene关卡还在加载中
可以看到,因为异步,所以加载完成日志先打印
13 、transform组件
游戏物体的父子关系是由transform组件所关联起来的
public class TransformTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
//获取位置
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); //只有相对于父物体的缩放,没有相对于世界的缩放
//向量,注意 物体旋转时,xyz轴指向也会发生变化。相当于获取红绿蓝三个轴的向量,z轴一般代表前方轴,红色轴代表右手轴,y轴代表上方
Debug.Log("forward is " + transform.forward);
Debug.Log("right is " + transform.right);
Debug.Log("up is " + transform.up);
//父子关系
//获取父物体
//Debug.Log(transform.parent.gameObject);
//获取子物体个数
//Debug.Log(transform.childCount);
//解除与子物体的父子关系
//transform.DetachChildren();
//获取子物体
Transform trans = transform.Find("Child");
trans = transform.GetChild(0);
//判断一个物体是不是另一个物体的子物体
bool res = trans.IsChildOf(transform);
Debug.Log("IsChildOf is " + res);
//设置为父物体.这个函数可以让原本不相干的两个物体变成父子关系
trans.SetParent(transform);
}
// Update is called once per frame
void Update()
{
//让一个物体时时刻刻看向另一个物体,举例看向000。即让物体的z轴时刻指向000。可以用于索敌
//transform.LookAt(Vector3.zero);
//旋转 按什么轴旋转,每一帧旋转多少度。可用于游戏开发的某种场景物体自旋转。
//transform.Rotate(Vector3.up, 1);
//绕某个物体旋转。也可以绑定父物体然后用脚本transform.Rotate让父物体自转
//绕000点的up轴,每一帧旋转五度(但如果按帧的话 不同设备间帧率有差 可能会导致不同设备上效果不同,可以选用秒单位
//transform.RotateAround(Vector3.zero, Vector3.up, 5);
//移动 每一帧向前移动0.1,可用于弹道轨迹
//transform.Translate(Vector3.forward * 0.0001f);
}
}
14、基本键鼠操作
public class KeyTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
//键盘鼠标操作需要每一帧都判断
//鼠标的点击, 0 左键 1 右键 2 滚轮.
if (Input.GetMouseButtonDown(0))
{
//持续按下也只会触发一个buttondown事件
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)) //也可以用小写字符"a",大写字符"A"会报错
{
Debug.Log("松开A");
}
}
}
15、虚拟轴
用键盘模拟摇杆.为了跨平台输入监听。不是全部设备都有键盘字母的
只有水平和垂直时虚拟轴,其他是虚拟按键
public class AxisTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
// 获取水平轴,通过输入轴的名称, 轴的名称在项目设置-》输入管理器中定义。按下什么健或鼠标可以在设置中定义
float horizontal = Input.GetAxis("Horizontal");
float vertical = Input.GetAxis("Vertical");
//Debug.Log(horizontal + " " + vertical);
//虚拟按键
if(Input.GetButtonDown("Jump"))
{
Debug.Log("空格");
}
if (Input.GetButton("Jump"))
{
Debug.Log("持续空格");
}
if (Input.GetButtonUp("Jump"))
{
Debug.Log("松开空格");
}
}
}
16、触摸屏操作
public class TouchTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
//开启多点触摸
Input.multiTouchEnabled = true;
}
// Update is called once per frame
void Update()
{
//判断单点触摸
if(Input.touchCount == 1)
{
//触摸对象
Touch touch = Input.touches[0];
//触摸位置
Debug.Log(touch.position);
//触摸阶段
switch(touch.phase)
{
case TouchPhase.Began:
break;
case TouchPhase.Moved:
break;
case TouchPhase.Stationary:
break;
case TouchPhase.Ended:
break;
case TouchPhase.Canceled:
break;
}
}
//判断多点触摸
if (Input.touchCount == 2)
{
Touch touch = Input.touches[0];
Touch touch1 = Input.touches[1];
}
}
}