Unity is a tool for creating and growing games, apps, and experiences across 20+ platforms and devices. Learn how to use Unity’s end-to-end solutions, services, and community resource
1.C#脚本
脚本的基本结构,其中Move是脚本名
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
脚本的生命周期
Awake 最早调用
- 当物体载入时立即调用1次;常用于在游戏开始前进行初始化,可以判断当前满足某种条件执行此脚本,this.enable = true;
OnEnable 激活后,只会调用一次
Start 调用一次,可以设置初始值
FixedUpdate 固定频率调用
Update 每帧调用一次
LateUpdate 在Update之后调用
- 适用于跟随逻辑
OnDisable 组件未激活调用
OnDestroy 销毁
OnApplicationQuit()当前程序结束时
[SerializeField] 在编辑器中无法修改,在脚本内可修改
序列化字段
[private int a = 100;
]
[HideInInspector]在编辑器中无法显示
[private int b;
]
[Range()]
[private int c;
]
2.脚本的执行顺序
先执行所有脚本的Awake方法,再执行所有脚本的OnEnable方法。。。
在Execution Order可以更改脚本的执行顺序
3.标识
Tag 唯一标识符
Layer 图层,用于碰撞检测
4.预制体和变体
1.预制体
rigidbody 添加重力
多个物体有相同的预设可以使用预设体
2.变体
原本的预设体会影响变体,变体的预设体只会影响变体
5.Vector3的使用
向量、坐标、旋转,缩放
Vector3 v = new Vector3();
Vector3 v3 = new Vector3(1, 0.5f,0.6f);
v3 = Vector3.zero;
v3 = Vector3.one;
修改向量的xyz值
v3.x = 1;
两个向量的计算
//角度
Debug.Log(Vector3.Angle(v31, v3));
//距离
Debug.Log(Vector3.Distance(v31, v3));
//点乘
Debug.Log(Vector3.Dot(v31, v3));
//叉乘
Debug.Log(Vector3.Cross(v31, v3));
//插值
//0.5为两个向量的中点
Debug.Log(Vector3.Lerp(Vector3.zero, Vector3.one, 0.5f));
//向量的模
Debug.Log(v3.magnitude);
//规范化向量(单位化向量)
Debug.Log(v3.normalized);
6.欧拉角与四元数
//欧拉角,四元数
Vector3 rotate = new Vector3(0,30,0);
Quaternion quat = Quaternion.identity;
//欧拉角转换为四元数
quat = Quaternion.Euler(rotate);
//四元数转换为欧拉角
rotate = quat.eulerAngles ;
//看向一个物体(旋转到一个方向)
quat = Quaternion.LookRotation(new Vector3(0,0,0));
7.Debug
可以定义共有变量,程序运行后再检测面板查看数据
Debug.Log("");
//警告
Debug.LogWarning("");
//错误
Debug.LogError("");
//绘制一条线(指定颜色为红色)
Debug.DrawLine(Vector3.one, Vector3.zero, Color.red);
//绘制一条射线 (起点,射线,颜色)
Debug.DrawRay(Vector3.one, Vector3.up, Color.yellow);
8.游戏物体的使用方法
拿到当前脚本所挂载的游戏物体
public class EmptyTest : MonoBehaviour
{
public GameObject cube;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
判断组件的激活状态
//所在层级是否激活
Debug.Log(gameObject.activeInHierarchy);
//自身是否激活
Debug.Log(gameObject.activeSelf);
获取transform组件
Transform trans = this.transform;
获取物体的组件
//获取自身的其他组件
BoxCollider bc = GetComponent<BoxCollider>();
//获取子物体的组件
GetComponentInChildren<BoxCollider>(bc);
//获取父物体的组件
GetComponentInParent<BoxCollider>(bc);
//添加一个组件
cube.AddComponent<AudioSource>();
获取游戏物体
//通过物体名
GameObject Capsule1 = GameObject.Find("Capsule");
Debug.Log(Capsule1.name);
//通过标签获取
GameObject Capsule2 = GameObject.FindWithTag("Player");
Debug.Log(Capsule2.name);
Capsule1.SetActive(false);
取消激活
预设体
//使用预制体创建一个实例
Instantiate(Prefab);
//创建一个物体,并且作为本游戏物体的子物体
Instantiate(Prefab,transform);
//创建一个物体
GameObject go = Instantiate(Prefab,Vector3.up,Quaternion.identity);
//销毁一个游戏物体
Destroy(go);
9.游戏时间
//游戏到现在所花的时间
Debug.Log(Time.time);
//时间缩放值
Debug.Log(Time.timeScale);
//固定时间间隔
Debug.Log(Time.fixedDeltaTime);
//上一帧到下一帧的时间间隔
Debug.Log(Time.deltaTime);
10.路径权限
//只读,压缩加密
Debug.Log(Application.dataPath + "/新建.txtx");
//持久化文件夹路径
Debug.Log(Application.persistentDataPath);
//StreamingAssert文件夹路径(只读,配置文件);
Debug.Log(Application.streamingAssetsPath);
//临时文件夹
Debug.Log(Application.temporaryCachePath);
//是否在后台运行
Debug.Log(Application.runInBackground);
//打开url
Application.OpenURL("https://www.baidu.com");
//退出游戏
Application.Quit();
11.场景类
场景类,场景管理类
//跳转场景
SceneManager.LoadScene(1); //1号场景
SceneManager.LoadScene("Test"); //场景名称
//获取当前场景
Scene scence = SceneManager.GetActiveScene();
Debug.Log(scence.name);
场景的API
//场景是否在加载
Debug.Log(scence.isLoaded);
//场景的路径
Debug.Log(scence.path);
//场景的索引
Debug.Log(scence.buildIndex);
//获取场景的游戏物体
GameObject[] games = scence.GetRootGameObjects();
Debug.Log(games.Length);
场景管理类
//场景管理类
//当前场景数
Debug.Log(SceneManager.sceneCount.ToString());
//创建新场景
SceneManager.CreateScene("newScene");
Debug.Log(SceneManager.sceneCount.ToString());
//卸载场景
Scene newScene = SceneManager.CreateScene("newScene");
SceneManager.UnloadSceneAsync(newScene);
加载场景
//加载场景
SceneManager.LoadScene("myscene", LoadSceneMode.Single);
12.异步加载场景并获取进度
public class AsyncTest : MonoBehaviour
{
AsyncOperation operation;
void Start()
{
StartCoroutine(loadScene());
}
IEnumerator loadScene()
{
operation = SceneManager.LoadSceneAsync(1);
yield return operation;
}
void Update()
{
}
}
输出加载进度
//输出加载进度0-0.9
Debug.Log(operation.progress.ToString());
模拟定时器
public class AsyncTest : MonoBehaviour
{
AsyncOperation operation;
void Start()
{
StartCoroutine(loadScene());
}
//用携程来异步加载场景
IEnumerator loadScene()
{
operation = SceneManager.LoadSceneAsync(1);
//加载完场景不要跳转
operation.allowSceneActivation = false;
yield return operation;
}
float Timer = 0;
void Update()
{
//输出加载进度0-0.9
Debug.Log(operation.progress.ToString());
Timer += Time.deltaTime;
//达到5秒后跳转
if (Timer > 5)
{
operation.allowSceneActivation = true;
}
}
}
13.Transform
tranform API
//获取位置
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);
//时时刻刻看向0,0,0
transform.LookAt(new Vector3(0, 0, 0));
//旋转
transform.Rotate(Vector3.up, 1);
//绕某个物体旋转
transform.RotateAround(Vector3.zero,Vector3.up, 5);
//移动
transform.Translate(Vector3.forward * 0.1f);
父子关系
//获取父物体
//transform.parent.gameObject
//获取子物体
//transform.childCount
//解除父子关系
transform.DetachChildren();
//获取子物体
Transform trans = transform.Find("Children");
transform.GetChild(0);
//判断一个物体是否是另一个物体的子物体
bool res = trans.IsChildOf(transform);
//设置父物体
trans.SetParent(transform);
14.游戏操作方式
在update里面写
//鼠标的点击 0左键 1右键 2滚轮
//点击
if (Input.GetMouseButtonDown(0))
{
Debug.Log("");
}
//点击后
if (Input.GetMouseButtonUp(0))
{
Debug.Log("");
}
//持续点击
if (Input.GetMouseButton(0))
{
Debug.Log("");
}
if (Input.GetMouseButton(0))
{
Debug.Log("");
}
if (Input.GetKey(KeyCode.Space))
{
Debug.Log("");
}
if (Input.GetKeyUp(KeyCode.Space))
{
Debug.Log("");
}
if (Input.GetKeyDown(KeyCode.Space))
{
Debug.Log("");
}
15.操作兼容与过渡
Edit –> ProjectSetting –> input Manager –> axes
水平 Horizontal
垂直 Vertical
//获取水平轴
float horizontal = Input.GetAxis("Horizontal");
//获取垂直轴
float vertical = Input.GetAxis("Vertical");
Debug.Log(horizontal + " " + vertical);
虚拟按键的使用
//虚拟按键
if (Input.GetButtonDown("Jump"))
{
Debug.Log("");
}
if (Input.GetButtonUp("Jump"))
{
Debug.Log("");
}
if (Input.GetButton("Jump"))
{
Debug.Log("");
}
16.手机平板触屏
//开启多点触屏
Input.multiTouchEnabled = true;
判断单点触摸
//判断单点触摸
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;
}
}
17.灯光与烘焙
定向灯光 –> 从无穷远的地方照射而来09
烘焙光 静态光
实时光 动态光会实时计算光的渲染
18.摄像机
摄像机深度越大,优先级越高
19.音频
添加Audio Source
//AudioClip
public AudioClip music;
public AudioClip se;
public AudioSource player;
void Start()
{
player = GetComponent<AudioSource>();
//设定播放的音乐音频
player.clip = music;
//循环
player.loop = true;
//音量
player.volume = 0.5f;
//播放
player.Play();
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
if (player.isPlaying)
{
//暂停播放
player.Pause();
//停止播放
/*player.Stop();*/
}
else
{
//继续播放
player.UnPause();
}
}
}
//播放一声,常用于播放音效
player.PlayOneShot(se);
20.视频播放
Video Player
using UnityEngine.Video;
private VideoPlayer mPlayer;
void Start()
{
mPlayer = GetComponent<VideoPlayer>();
}
21.角色控制
public class PlayerControll : MonoBehaviour
{
private CharacterController characterController;
void Start()
{
characterController = GetComponent<CharacterController>();
}
void Update()
{
//水平轴
float horizontal = Input.GetAxis("Horizontal");
//垂直轴
float vertical = Input.GetAxis("Vertical");
//创建一个方向向量
Vector3 dir = new Vector3(horizontal,0,vertical);
characterController.SimpleMove(dir);
}
}
22.物理系统
碰撞的产生与监听
public class PlayerControll : MonoBehaviour
{
private GameObject Prefab;
void Start()
{
}
void Update()
{
}
//监听发生碰撞
private void OnCollisionEnter(Collision collision)
{
//创建发生碰撞后产生的物体
Instantiate(Prefab,transform.position,Quaternion.identity);
//销毁自身
Destroy(gameObject);
}
//持续碰撞
private void OnCollisionStay(Collision collision)
{
}
//结束碰撞
private void OnCollisionExit(Collision collision)
{
}
}
触发
private void OnTriggerEnter(Collider other)
{
GameObject go = GameObject.Find("Cube");
if (go != null) {
go.SetActive(false);
}
}
private void OnTriggerStay(Collider other)
{
}
private void OnTriggerExit(Collider other)
{
}
弹簧 Spring Joint
铰链
23.冰面与地面
物理材质的使用
静态摩擦和动态摩擦的使用
24.射线检测
//方式1
Ray ray = new Ray(Vector3.zero,Vector3.up);
//方式1
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
//声明一个碰撞信息类
RaycastHit hit;
bool res = Physics.Raycast(ray, out hit);
if (res)
{
Debug.Log(hit.point);
//移动
transform.position = hit.point;
}
//多检测
RaycastHit[] hits = Physics.RaycastAll(ray, 100);
}
25.彩色尾条和拖尾
Line Render
//获取线段渲染器
LineRenderer lineRenderer = GetComponent<LineRenderer>();
//设置三个点
lineRenderer.positionCount = 3;
lineRenderer.SetPosition(0, Vector3.zero);
lineRenderer.SetPosition(0, Vector3.one);
lineRenderer.SetPosition(0, Vector3.forward);
Trail Render
26.动画组件
animation 旧组件
void Update()
{
if (Input.GetMouseButtonDown(0))
{
GetComponent<Animation>().Play("name");
}
}
animatior 新组件
新建动画器控制器
27.模型动作
if (Input.GetKeyDown(KeyCode.F))
{
//触发触发器triggername
GetComponent<Animator>().SetTrigger("triggername");
}
float horizontal = Input.GetAxis("Horizontal");
float vertical = Input.GetAxis("VErtical");
Vector3 dir = new Vector3 (horizontal,0, vertical);
if (dir != Vector3.zero)
{
transform.rotation = Quaternion.LookRotation(dir);
transform.Translate (dir * 1.5f);
}
28.帧事件的使用
void test1()
{
Debug.Log("test1");
}
void test2()
{
Debug.Log("test2");
}
在脚落地时打上帧事件,播放踩地的声音
29.混合动画
设置权重权重越高显示在前
Avatar Mask 相当于蒙版
30.反向动力学
反向运动学 (IK) 是一种设置动画的方法,它翻转链操纵的方向。
//IK方法
private void OnAnimatorIK(int layerIndex)
{
//人物头部IK
animator.SetLookAtWeight(1);
animator.SetLookAtPosition(target.position);
//设置右手IK
animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 1);
//旋转
animator.SetIKRotationWeight(AvatarIKGoal.LeftHand, 1);
}
31.导航网格
新版使用NavMeshSurface组件来进行
Nav Mesh Agent 导航代理组件(用于角色)
private NavMeshAgent agent;
void Start()
{
agent = GetComponent<NavMeshAgent>();
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
//获取位置
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
//射线信息类
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
Vector3 point = hit.point;
//该点为导航目标点
agent.SetDestination(point);
}
}
}
在两点之间传送
创建两个物体,其中一个绑定Off Mesh Link再绑定起始点
32.锚点和轴心点
当四个锚点均在同一点时,用轴点(Pivot)到锚点的水平距离和垂直距离来定位
33.按钮
使用图片前转为精灵图
在脚本内使用画布内的组件新版加入TMPro命名空间
绑定事件先将脚本绑定到画布,然后再按钮的鼠标单击事件中绑定脚本的鼠标单击事件方法(Button Click)
34.下拉选项Dropdown
void Start()
{
//获取下拉组件
Dropdown dropdown = GetComponent<Dropdown>();
//获取组件的选项
List<Dropdown.OptionData> options = dropdown.options;
//修改选项
options.Add(new Dropdown.OptionData("new selection"));
dropdown.options = options
}
35.常用的UI组件
Vertical Latout Gropu 可以用于多个元素之间控制相同的距离和宽度
Grid 网格布局