第一课:了解unity脚本:
public class test : MonoBehaviour
{
// Start is called before the first frame update
// 1.最初始为awake激活组件(执行一次)
private void Awake()
{
Debug.Log("awake");
}
//2.在awake之后执行(可能执行多次) 激活时调用一次
private void OnEnable()
{
Debug.Log("enable");
}
//3.开始 在第一次enable之后执行(只执行一次)
void Start()
{
// Debug.Log("start");
}
// Update is called once per frame
//4.每一帧输出一次
void Update()
{
// Debug.Log("update");
}
// //5.紧跟在update之后 一帧一次
// private void LateUpdate(
// {
// }
// )
// //6.固定刷新(每格固定间隔会运行一次) 默认0.02s调用一次
// private void FixedUpdate
// {
// }
//6.非激活调用一次
// private void OnDisable()
// {
// }
//7.销毁时调用(只调用一次 销毁组件时调用)
// private void OnDestory(){
// }
}
第二课 基本方法
//下列vector可以表示向量 坐标 旋转 缩放
//新建Vector3表示xyz三维(一般含有三个参数)
Vector3 v=new Vector3()
v=Vector3.zero(表示Vector3(0,0,0))
Vector3.one(表示Vector3(1,1,1))
//计算两个向量的夹角
Vector3.Angle(v,v2)
//计算两个向量的距离
Vector3.Distance(v,v2)
//计算两个向量的点乘
Vector3.Dot(v,v2)
//插值(=a*(b-a)*t)
Vector3.Lerp(v,v2,0.8f)
第三课 欧拉角和四元数
//欧拉角和四元数和旋转相关
Vector3 rotate=new Vector3(x,y,z)
//定义四元数
Quaternion quaternion=Quaternion.identity
//欧拉角转化为四元数
quaternion=Quaternnion.Euler(rotate)
//四元数转化为欧拉角
rotate=Quaternion.eulerAngles;
第四课 debug相关
//三种console
Debug.Log() //输出
Debug.LogWarning() //警告
Debug.LogError() //错误
//绘制线条(起点,终点,颜色)
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.blue)
第五课 常用的代码改变物体属性(物体类)
//注意 脚本只有挂到物体上才能起作用
public GameObject Cube //需要在unity内进行绑定
//拿到当前脚本所挂在的物体
GameObject go=this.GameObject;
//获取当前物体name
go.name
//获取当前物件的标签或者涂层
go.tag(go.layer)
//获取当前物体真正的激活状态(会收到父亲的影响,有时即使自己上激活状态 但父不是则仍为未激活)
go.activeInHierarchy
//获取自己的激活状态
go.activeSelf
//获取位置组件
Transform tr=new Transform;
//获取组件的位置
tr.prosition
//获取其他组件
BoxColider bc=GetComponent<BoxColider(对应组件名称)>()
//获取当前物体的子物体身上的某个组件
GetComponentInChildern<如CapsuleColider>(bc)
//获取当前物体的父物体身上的某个组件
GetComponentInParent<如CapsuleColider>(bc)
//创建一个组件
Cube.AddComponent<组件名称>()
//通过游戏物体名称来获取物体
GameObject test=GameObject.find("字符串")
//通过游戏标签来获取物体和设置其激活状态
test=GAmeObject.FindWithTag("字符串")
test.SetActive(true/false)
//用预设体来实例化一个游戏物体
public GameObject Prefab;(然后去unitu中绑定预设体)
Instantiate(Prefab,位置(如vector3.zero),旋转角度(如Quaternion.identity))
第五课 游戏时间
float timer=0;
//游戏开始到现在所花的时间
Time.time
//时间缩放值,如加快或放慢
Time.timeScale
//固定时间间隔(可以去unity设置中修改)
Time.fixedDeltaTime
//上一帧到这一帧所用的时间
Time.deltaTime
第六课 路径权限 application
//游戏数据文件夹路径(只读,加密压缩)
Application.dataPath(输出asset文件夹)
第七课 scence跳转
//声明
using UnityEngine.SCeneManagement;
//分为 场景类和场景管理类
//1.场景类
//实现场景跳转,如跳转到场景myscene
SceneManager.LaodScene("myscene")
//获取当前场景
Scene scene = SceneManager.GetActiveScene();
//场景名称
scene.name
//场景是否已经加载
scene.isLoaded
//场景路径
scene.path
//获取场景索引
scene.buildIndex
//2.场景管理类
//创建一个新场景
Scene newScene=SceneManager.CreateScene("newScene");
//计算加载场景个数
SceneManager.sceneCount
//卸载场景
SceneManager.UnloadSceneAsync(newScene);
//加载场景
SceneManager.LoadScene("newscene",LoadSceneMode.Additive/single)
//Additive为和原有场景融合在一起 如果是single则用newscene代替原有场景
第八课 异步加载场景并获取进度
//用协程的方法来实现异步加载场景,步骤如下
//1.定义异步控制类
AsyncOperation operation
//2.定义方法来实现异步加载
IEnumerator LoadScene(){
operation=SceneManager.LoadSceneAsync(1);
yield return operation;
}
//3.挂载
void Start()
StartCoroutine(loadScene())
}
//获取加载进度0-0.9(用该数值可以结合ui来制作进度条)
operation.progress
第九课 位置旋转和缩放
Transform transform=new Transform
//1.获取位置
transform.position(世界位置)
transform.localPosition(相对于父的相对位置)
//2.获取旋转
transform.rotation(获取世界选择角度)
transform.localRotation(获取相对选择角度)
transform.eulerAngles(获取世界欧拉角)
transform.LocalEulerAngles
//3.获取缩放
transform.localScale(只能获取相对缩放)
//4.向量
transform.forward(z轴)
transform.right(x轴)
transform.up(y轴)
transform.LookAt(Vector3.zero)//物体始终面向000点
transform.Rotate(Vector3.up,1)//表示绕着up轴以1点速度旋转
transform.RotateAround(Vector3.zero,Vector3.up,5)//表示以000点为旋转点,绕up轴以5点速度旋转
//5.父子关系
//获取父物体
transform.parent.gameObject
//获取子物体个数
transform.childCount
//解除与子物体的父子关系
transform.DetachChildern()
//获取子物体
Trasnform trans=transform.Find("Child");
trans=transform.GetChile(0);//获取第一个子物体
//判断一个上午是否为另外一个物体的子物体
bool res =trans.IsChildOf(transform)
第十课 鼠标和键盘事件
//鼠标点击 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");
}
第十一课 虚拟轴(多用于多平台兼容性)
//获取水平轴
float horizontal=Input.GetAxis("Horizontal");
float vertical=Input.GetAxis("Vertical");
Debug.Log(horizontal+" "+vertical);
//获取虚拟按键(在project setting中的input manager中设定了)
if(Input.GetButton("Jump")){
Debug.Log("空格");
}
}
第十二颗 触摸获取 (如平板或者手机触屏)
//单点触摸
if(Input.touchCount==1){
//触摸对象
Touch touch=Input.touches[0];
//触摸位置
touch.position
//触摸阶段
switch(touch.phase)
{
case TouchPhase.Began;//开始时执行
break;
case TouchPhase.Moved;//移动时执行
break;
case TouchPhase.Staionary;//静止执行
break;
case TouchPhase.Ended;//结束时执行
break;
case TouchPhase.Canceled;//撤销时执行
break;
}
}
//若要实现多点触摸 则将Input.touchCount==n(n>1)
第十三课 添加音效
//AudioClip 需要配置的音乐和音效
public AudioClip music;(自定义名称)
public AudioClip se(自定义音效名称)
//播放器组件
private AudioSource player;
player=GetComponent<AduioSource>();
//设定播放的音乐
player.clip=muscic;
//设置循环播放
player.loop=true;
//利用空格切换声音的暂停和播放
if(Input.GetKeyDown(KeyCode.Space)){
//如果当时正在播放
if(player.isPlaying){
//暂停
player.Pause()
//停止
player.Stop();
//继续
player.UnPause();
//开始播放
player.Play();
}
//若要用鼠标左键实现点击音效可以用
if(Input.GetMouseButtonDown(0)){
player.PlayOneShot(se)
}
//视频的操作方法类似 只需要将aduioplayer换成videoplayer即可
// (可以在asset中添加渲染器纹理,给物体添加video player后绑定视频剪辑为所需视频,将目标纹理选为渲染器 纹理后直接拖拽给物体即可)
第十四课 角色移动
//1.给要移动的物体增加character controller组件
private CharacterController player;
void Start()
{
//获取组件对象
player=GetComponent<CharacterController>();
}
void Update()
{
//“水平轴 左右”
float horizontal=Input.GetAxis("Horizontal");
//“垂直轴 前后”
float vertical=Input.GetAxis("Vertical");
//定义向量
Vector3 dir=new Vector3(vertical,0,horizontal);
//绑定物体根据向量移动 simplemove有重力限制 move没有
player.SimpleMove(dir);
//或者
player.Translate(diir);
//如果要设置每次移动2s dir可以写成dir*2*Time.deltaTime
}
//如果想要角色跟随移动旋转 可以用
transform.rotation=Quaternion.LookRotation(dir)
第十五课 碰撞监听和事件
//前提:要添加colider和rigidbody才能实现碰撞
//创造碰撞效果预设体(如落地爆炸效果)
public GameObject Prefab;
//监听发生碰撞(最常用)
private void OnCollisonEnter(Collision collision){
//创建一个爆炸物体
Instantiate(Prefab,transform.position,Quaternion.identity)
//销毁自己(营造一个碰撞后爆炸的效果)
Destory(gameObject);
}
//持续碰撞中
private void OnCollisonStay(Collision collision){
}
//结束碰撞
private void OnCollisonExit(Collision collision){
}
//注意 谁发生了什么 应该由对应的脚本实现
//如要在1s后将爆炸效果消失,应用爆炸物绑定脚本
float time=0;
time+=Time.deltaTime;(deltaTime是帧)
if(time>1){
Destory(gameObject);
}
//触发器(触发器一般是可以闯过的 刚刚进入为下列第一个 在里面是第二个 出去为第三个)
private void OnTriggerEnter(Collision other){
//谁进去触发 谁就是other
//如触发门后物体消失
GameObject door=GameObject.Find("door")
if(door!=null){
door.SetActive(false);
}
}
//持续碰撞中
private void OnTriggerStay(Collision other){
}
//结束碰撞
private void OnTriggerExit(Collision other){
}
第十六课 射线检测(多用于用鼠标点击场景位置使得对应物体移动到该位置)
//方法如下(单碰撞)
if(Input.GetMouseButtonDown(0)){
//按下鼠标右键发射射线
Ray ray=Camera.main.ScerrnPointToRay(Input.mousePosition)
//声明一个射线碰撞类
RaycashHit hit;
//碰撞检测
bool res=Physics.Raycast(ray,out hit)
//如果碰撞到了,就赋予hit值
if(res=true){
transform.position=hit.position
}
}
//如果是多检测 就是一个射线射过多个物体
RaycastHit[] hits=Physics.RaycastAll(ray,100(这是距离),1<<10(表示第10个图层))
第十七课 animater控制动画
//如用f键位控制任务过渡到其他动画
if(Input.GetKeyDown(KeyCode.F)){
GetComponent<Animator>().SetTrigger("pickup");
}
//可以用dir!=verctor3.zero来判断移动
第十八课 混合动画状态
重点看视频51和视频52
动画太多可以使用多图层动画 设置权值来控制动画播放优先级 如果需要局部 可以在asses建立avatar遮照后应用到对 应图层即可,如果需要对于特定人体部分进行遮罩,可以选择对应部分(绿色为选中)
如果两个图层的权重为0.5,则会将两个图层对应的动画融合为一个动画
第19课 利用ik来实现身体特定部位(在范围内)指向目标
//步骤如下:
//1.打开对应图层的ik处理选项
//2.代码实现如下:
private void OnAnimatorIK(int layerIndex){
//设置头部ik
animatoor.SetLookAtWeight(1);
//让头部自动指向目标点
animator.SetLLookAtPosition(target.position);
//设置右手ik(除头部之外都得用以下方法,如右手右脚,左手左脚等)
animator.SetIKPositionWeight(AvatarIKGoal.RightHand,1);
//跟随旋转
animator.SetIKRotationWeight(AvatorIKGoal.RightHand,1);
//设置右手IK(函数参数为对应部分,目标位置)
animator.SetLLookAtPosition(AvatorIKGoal.RightHand,target.position);
}
第20课 利用混合树来生成混合动画
步骤1:选择从新混合树
步骤2:设置需要混合的
步骤3:设置混合值(如越靠近1则动画越靠近跑的效果,越靠近0则越靠近walk的效果)
第21课 导航功能(如自动寻路):生成导航路径
步骤1:设置测试物体(如下,生成城墙的导航路线:即可通过路线)
步骤2:给对应的测试物体集合添加navmeshsurface组件
步骤3:设置导航路径的限制条件:(图2代理类型可以设置不同角色的不同条件)
如:半径为物体能够通过的最大半径,高度为物体能通行的最大高度,步高表示人物每次跳的最大高度,设置完成之后点击组件的bake进行路径烘培即可生成路径(深蓝色表示可以通过)
第22课 导航功能(如自动寻路):绑定物体进行导航
步骤1:给测试人物添加nav mesh agent
参数1:代理类型:选择对应的代理类型
参数2:设置检测位置:通常为默认或者与地面平齐即可
参数3:自动刹车:到达边界是否停下
参数4:对于多物体,优先级高的先过
步骤2:实现物体根据点击位置移动且能实现导航功能
private NavMeshAgent agent;
void Start()
{
//获取导航组件
agent = GetComponent<NavMeshAgent>();
}
// Update is called once per frame
void Update()
{
// 获取射线
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
// 碰撞
RaycastHit hit;
// 如果有射线碰撞
if (Physics.Raycast(ray, out hit))
{
//获取点击位置
Vector3 point = hit.point;
//设置该位置为导航目标点
agent.SetDestination(point);
}
}
步骤3:添加物体作为导航obstacle(如:可新建导航路径)
给所需要的物体添加组件nav mesh obstacle:里面的切割属性为动态形成导航区域
补充课程:实现自动移动和跳跃
//利用rigidbody2d(自动移动)
public rigidbory2D rb;
rb.velocity=new Vector2(x,rb.velovity.y)//沿x轴移动 正数为右 负数为左
rb.velocity=new Vector2(0,y)//沿y轴移动(跳跃),正数向上
//输入移动(手动)
xinput=Input.GetAcxisRaw("Horizontal");
rb.velocity=new Vector2(xinput,rb.velovity.y)//沿x轴移动 正数为右 负数为左
//给物体添加弹力可以用material材质
//简单案例实现跳跃和移动
public rigidbory2D rb;
public float movespeed;
private float xinput;
public float jumpforce;
xinput=Input.GetAcxisRaw("Horizontal");
rb.velocity=new Vector2(xinput*movespeed,rb.velovity.y)//沿x轴移动 正数为右 负数为左
if(input.GetKeyDown(KeyCode.Space)){
//实现跳跃,jumpforce表示弹跳力
rb.velocity=new Vector2(rb.velocity.x,jumpforce);
}